如何模拟Mouse点击另一个程序窗口上的一个按钮?(200分)

  • 主题发起人 主题发起人 Thinboy
  • 开始时间 开始时间
T

Thinboy

Unregistered / Unconfirmed
GUEST, unregistred user!
只知道另一个程序窗口的标题及按钮的标题!
如何做呢?
谢谢!
 
To Thinboy:
你也是新来的吧?
这是前辈们的经()〈——打不出来,你最好在问问(提)时先问题搜索!
不过你如何知道“另一个程序窗口的标题及按钮的标题”?要是你知道的话,看这里吧!
--------------〉
我摘录的以前的问题,没时间整理了[ ^_* ],自己慢慢查吧!很有用的哦——
——————————————————————————————————
自已写一个不太麻烦,以下程序可以定时移动光标并循环打开几个网页:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls,ShellApi, TimerLst;

type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
Timer2: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

const
URLList: Array[0..3] of String =('http://www.obsof.com',
'http://bbs.nease.net',
'http://www.gm-software.de/',
'http://delphidao.finalfiler.com/');

var
hIE: THandle;
i: Integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
hIE :=FindWindow('IEFrame',nil);
if hIE > 0 Then
begin
SetForeGroundWindow(hIE);
Timer1.Enabled := True;
Timer2.Enabled := True;
end
else
showMessage('请先启动IE');
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
curPos: TPoint;
begin
GetCursorpos(curPos);
if curPos.x > (Screen.DesktopWidth - 100) then
SetCursorpos(Screen.DesktopLeft +10,curPos.y);
Mouse_Event(MOUSEEVENTF_MOVE,10,0,0,0);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
i := (i + 1) mod 4;
if hIE > 0 then
ShellExecute(hIE,nil,PChar(URLList),nil,nil,0);
end;

end.

你要在form上做图的话,就在form的那些mouse事件中处理,
你看事件参数,可以知道当前mouse position,which button is pressed...




--------------------------------------------------------------------------------
来自:liangliang 时间:00-2-24 22:57:03 ID:191225
我指的屏幕是桌面上。
是这样的,我想实现的功能是鼠标在屏幕上移动,若移动到某应用程序则能在应用程序上画出一个框。这类似于'HyperSnap-Dx'中的用windows截图
时所见的情形。
不知如何实现,或者谁能告诉我HyperSnap-Dx是怎么作的。





--------------------------------------------------------------------------------
来自:Another_eYes 时间:00-2-24 23:44:19 ID:191254
一个很简单的办法:
建立一form, setwindowrgn(form.handle, createrectrgn(-1,-1,0,0), true);
setcapture(form.handle), 然后就可以用form.onmousemove, onmousedown, onmouseup等事件了, 而且窗口在屏幕上不可见(却是actived).



--------------------------------------------------------------------------------
来自:urus 时间:00-2-25 00:01:09 ID:191259
用mouse hook



--------------------------------------------------------------------------------
来自:liangliang 时间:00-2-25 23:56:20 ID:191518
To Another_eYes:
你的方法虽然简单但并能解决我的问题啊。
setcapture 只有在当前程序活动时有效,而且我在哪画框呢?

我发现HyperSnap-Dx截图时画面是静止的,所以我猜想它也许是先将整个屏幕截
下,然后在该图上处理画框,但若鼠标在该图上移动又如何取得其它程序句柄以取得某
window的rect,去画画框呢?难道可以在form上移动而把鼠标移动映射到桌面以取
得句柄?
不知哪位高手能指点一二?



--------------------------------------------------------------------------------
来自:阿蒙 时间:00-2-26 16:08:42 ID:191686
anothereyes 的方法应该可以.就是你启动的程序在后台运行.如同在屏幕上画一样
我只知道如何可以建立程序接受系统消息.
private
procedure wndproc(var message;tmessage);
.
.
procedure tform1.wndproc(var message;tmessage);
var
pos:tpoint;
dc:hdc;
begin
if message.lparam=wm_mousemoue then
getdc(0);屏幕句柄
getcursor(pos);鼠标位置;
.
.如何画图调用 winapi 自己查吧!





--------------------------------------------------------------------------------
来自:o*o 时间:00-2-28 13:09:11 ID:192295
在一个Timer里试试下面代码,不想用Timer就用Mouse Hook。

var p:TPoint; r:TRect;
begin
GetCursorPos(p);
GetWindowRect(WindowFromPoint(p),r);
DrawFocusRect(GetDC(0),r); //画Rect的方法参照这句自己发挥吧。
end;



--------------------------------------------------------------------------------
来自:liangliang 时间:00-2-28 20:11:16 ID:192495
to o*o:
In fact, your method is just my orinal manner, But
two problem:
How to back?
Getdc may occupy memory more and more with timer used.

To 阿蒙:
I have tried, but Wndproc cannt effect when the app is not actived.

问题的标题是:怎样把程序的图标做到系统托盘处(100分)
问题的分类是:编程手记 , 分坛主: DNChen, 分坛主: cAkk 来自:xlf 时间:00-2-5 23:22:31 ID:183579
请问怎样把程序的图标做到系统托盘处,并支持鼠标左右键,就像金山词霸2000那样,显示主界面时,在任务栏显示,最小化时任务栏上就没有。请详
细解答谢谢!!!





--------------------------------------------------------------------------------
来自:dedman 时间:00-2-5 23:40:12 ID:183585
我看过电脑报有一个用vc做的,不知有否 delphi的?
g



--------------------------------------------------------------------------------
来自:Dick 时间:00-2-5 23:51:28 ID:183590
这个问题怎么又提出来了?好像论坛中讨论过很多次了。
另外深度历险上有这个例子,看看就明白了,也就是10多行
代码的事,不是什么高难技术。



--------------------------------------------------------------------------------
来自:wrench 时间:00-2-6 00:11:06 ID:183595
windows 95 和 windows nt 4.0包含一个令人兴奋的特性:任务栏。这个通常位于区域任务条右面的区域能包含小的图标,这些图标能引出大的应用程序或者菜单。本篇文章主要讨论如何使用delphi建立这样的应用程序。
在开始之前,请看下面的需要的接口方面的内容:

从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应windows的消息来完成相应的功能。

procedure runtrayapplication;
var msg : tmsg;
begin
createwindow;
addtrayicon;
while getmessage(msg,0,0,0) do begin
translatemessage(msg);
dispatchmessage(msg);
end;
deletetrayicon;
end;
你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,最后关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。

让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(windows 95 & nt)句柄创建消息(例如鼠标单击等)和将消息发到我们的窗口。

procedure createwindow;
var
wc : twndclass;
w : hwnd;
begin
with wc do begin
style := 0;
lpfnwndproc := @wndproc;
cbclsextra := 0;
cbwndextra := 0;
hicon := 0;
hcursor := 0;
hbrbackground :=di2001.jpg;
lpszmenuname := nil;
lpszclassname := 'mytrayiconclass';
hinstance := system.hinstance;
end;
registerclass(wc);
w := windows.createwindow('mytrayiconclass', 'myveryowntrayiconwindow',
ws_overlappedwindow, 0, 0, 0, 0, 0, 0, hinstance, nil);
showwindow(w,sw_hide);
updatewindow(w);
mainwindow := w;
end;
 

这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_overlappedwindow”,但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。

下一步是加(注册)我们的图标。这将需要使用shell_notifyicon这个api函数,这个函数实际上可以完成三个功能,这里只需要它的增加的特性。

procedure addtrayicon;
var icondata : tnotifyicondata;
begin
with icondata do begin
cbsize := sizeof(icondata);
wnd := mainwindow;
uid := 0;
uflags := nif_icon or nif_message or nif_tip;
ucallbackmessage := wm_mycallback;
hicon := loadicon(hinstance,'myicon');
strcopy(sztip,pchar(trayicontip));
end;
shell_notifyicon(nim_add,@icondata);
end;
 

这个最重要的事情是tnotifyicondata的数据结构,它是一个设置window句柄的数据结构,是一个记录参数,对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),回调消息号,图标,工具提示等。一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。为了完成这个工作,使用nim_add程序。

现行我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。

const
wm_mycallback = wm_user+1000;
cm_exit = 100; { we worry about... }
cm_about = 101; { ...these later }
 

这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_nccreate)必须处理。然而,对我们来说,更重要的事情是处理wm_mycallback和wm_command消息:

function wndproc (window : hwnd; msg, wparam, lparam : integer): integer; stdcall;
begin
result := 0;
case msg of
wm_nccreate : result := 1;
wm_destroy : postquitmessage(0);
wm_command : begin { a command was chosen from the popup menu }
if (wparam = cm_exit) then
postmessage(window,wm_destroy,0,0)
else if (wparam = cm_about) then
messagebox(0,'shell test copyright ?'+
'jani j鋜vinen 1996.',
'about shell test',mb_ok)
else opendesktopicon(wparam-cm_about);
end;
wm_mycallback : begin { our icon was clicked }
if (lparam = wm_lbuttondown) then
showiconpopupmenu
else if (lparam = wm_rbuttondown) then
showaboutpopupmenu;
end;
else result := defwindowproc(window,msg,wparam,lparam);
end;
end;
 

就象你看到的一样,当用户单击图标时,windows提示我们。注意我们不使用通常使用的wm_lbuttondown 消息,而使用wm_mycallback message,详细的消息信息存储在lparam参数中。

当用户单击鼠标右键,我们创建一个菜单在桌面上。

type
ticondata = array[1..100] of string;
var
icondata : ticondata;
procedure showiconpopupmenu;
var
shellfolder : ishellfolder;
enumidlist : ienumidlist;
result : hresult;
dummy : ulong;
itemidlist : titemidlist;
pntr : pitemidlist;
strret : tstrret;
popupmenu : hmenu;
itemid : integer;
pos : tpoint;
procedure addtomenu(item : string);
var s : string;
begin
icondata[itemid-cm_about] := item;
s := extractfilename(item);
if (system.pos('.',s) <> 0) then setlength(s,system.pos('.',s)-1);
appendmenu(popupmenu,mf_enabled or mf_string,itemid,pchar(s));
inc(itemid);
end;
begin
popupmenu := createpopupmenu;
itemid := cm_about+1;
shgetdesktopfolder(shellfolder);
shellfolder.enumobjects(mainwindow,shcontf_nonfolders,enumidlist);
pntr := @itemidlist;
result := enumidlist.next(1,pntr,dummy);
while (result = noerror) do begin
shellfolder.getdisplaynameof(pntr,shgdn_forparsing,@strret);
with strret do addtomenu(string(cstr));
result := enumidlist.next(1,pntr,dummy);
end;
enumidlist.release;
shellfolder.release;
getcursorpos(pos);
appendmenu(popupmenu,mf_separator,0,'');
appendmenu(popupmenu,mf_enabled or mf_string,cm_exit,'e&xit');
setforegroundwindow(mainwindow);
trackpopupmenu(popupmenu,tpm_leftalign or tpm_leftbutton,
pos.x,pos.y,0,mainwindow,nil);
destroymenu(popupmenu);
end;
 

上面的程序看起来有点复杂,你可以将它分成两个部分来看:创建和显示菜单。

列举创建菜单是用windows的外壳接口完成的。首先,我们使用shgetdesktopforlder函数得到使用桌面的ishellfolder接口。使用这个接口,我们能得到另一个接口的实例:ienumidlist。这个接口通常实现实际的列举工作。我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。当我们得到一个菜单,我们使用addtomenu函数加它。

当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的list变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。

opendesktopicon(wparam-cm_about)

当然,wparam中储存了用户单击鼠标的菜单的菜单号(id)。

下面我们将处理运行用户选择的菜单。

procedure opendesktopicon(number : integer);
var
s : string;
i : integer;
begin
s := icondata[number];
i := shellexecute(0,nil,pchar(s),nil,nil,sw_shownormal);
if (i < 32) then begin
s := 'could not open selected item "'+s+'". '+
'result was: '+inttostr(i)+'.';
messagebox(0,pchar(s),'shell test',mb_ok);
end;
end;
 

上面,win 32 api函数shellexecute做了所有的工作。

现在你应该能用delphi创建简单的任务栏的程序了。





--------------------------------------------------------------------------------
来自:wlq 时间:00-2-6 00:19:11 ID:183596
用shellapi
function Shell_NotifyIcon(dwMessage,lpData):bool
可以完全满足您的要求。
我在论坛中问过这个问题:)
去深度历险,csdn,有很多源程序。





--------------------------------------------------------------------------------
来自:hzwdq 时间:00-2-6 00:25:39 ID:183597
!送个控件给你,愿意的话还可以隐藏任务栏上图标,需要完整例程,请发Email,
从2000年2月5日起一周内可给以回应。

//杭州电子工业学院 计算机应用技术研究所
//hzwdq@netease.com
uses Windows, SysUtils, Messages, ShellAPI, Classes, Graphics, Forms, Menus,
StdCtrls, ExtCtrls;

type
ENotifyIconError = class(Exception);

TTrayNotifyIcon = class(TComponent)
private
FDefaultIcon: THandle;
FIcon: TIcon;
FHideTask: Boolean;
FHint: string;
FIconVisible: Boolean;
FPopupMenu: TPopupMenu;
FOnClick: TNotifyEvent;
FOnDblClick: TNotifyEvent;
FNoShowClick: Boolean;
FTimer: TTimer;
Tnd: TNotifyIconData;
procedure SetIcon(Value: TIcon);
procedure SetHideTask(Value: Boolean);
procedure SetHint(Value: string);
procedure SetIconVisible(Value: Boolean);
procedure SetPopupMenu(Value: TPopupMenu);
procedure SendTrayMessage(Msg: DWORD; Flags: UINT);
function ActiveIconHandle: THandle;
procedure OnButtonTimer(Sender: TObject);
protected
procedure Loaded; override;
procedure LoadDefaultIcon; virtual;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Icon: TIcon read FIcon write SetIcon;
property HideTask: Boolean read FHideTask write SetHideTask default False;
property Hint: String read FHint write SetHint;
property IconVisible: Boolean read FIconVisible write SetIconVisible default False;
property PopupMenu: TPopupMenu read FPopupMenu write SetPopupMenu;
property OnClick: TNotifyEvent read FOnClick write FOnClick;
property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
end;

procedure Register;

implementation

{ TIconManager }
{ This class creates a hidden window which handles and routes }
{ tray icon messages }
type
TIconManager = class
private
FHWindow: HWnd;
procedure TrayWndProc(var Message: TMessage);
public
constructor Create;
destructor Destroy; override;
property HWindow: HWnd read FHWindow write FHWindow;
end;

var
IconMgr: TIconManager;
DDGM_TRAYICON: Cardinal;

constructor TIconManager.Create;
begin
FHWindow := AllocateHWnd(TrayWndProc);
end;

destructor TIconManager.Destroy;
begin
if FHWindow <> 0 then DeallocateHWnd(FHWindow);
inherited Destroy;
end;

procedure TIconManager.TrayWndProc(var Message: TMessage);
{ This allows us to handle all tray callback messages }
{ from within the context of the component. }
var
Pt: TPoint;
TheIcon: TTrayNotifyIcon;
begin
with Message do
begin
{ if it's the tray callback message }
if (Msg = DDGM_TRAYICON) then
begin
TheIcon := TTrayNotifyIcon(WParam);
case lParam of
{ enable timer on first mouse down. }
{ OnClick will be fired by OnTimer method, provided }
{ double click has not occurred. }
WM_LBUTTONDOWN: TheIcon.FTimer.Enabled := True;
{ Set no click flag on double click. This will supress }
{ the single click. }
WM_LBUTTONDBLCLK:
begin
TheIcon.FNoShowClick := True;
if Assigned(TheIcon.FOnDblClick) then TheIcon.FOnDblClick(Self);
end;
WM_RBUTTONDOWN:
begin
if Assigned(TheIcon.FPopupMenu) then
begin
{ Call to SetForegroundWindow is required by API }
SetForegroundWindow(IconMgr.HWindow);
{ Popup local menu at the cursor position. }
GetCursorPos(Pt);
TheIcon.FPopupMenu.Popup(Pt.X, Pt.Y);
{ Message post required by API to force task switch }
PostMessage(IconMgr.HWindow, WM_USER, 0, 0);
end;
end;
end;
end
else
{ If it isn't a tray callback message, then call DefWindowProc }
Result := DefWindowProc(FHWindow, Msg, wParam, lParam);
end;
end;

{ TTrayNotifyIcon }

constructor TTrayNotifyIcon.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FIcon := TIcon.Create;
FTimer := TTimer.Create(Self);
with FTimer do
begin
Enabled := False;
Interval := GetDoubleClickTime;
OnTimer := OnButtonTimer;
end;
{ Keep default windows icon handy... }
LoadDefaultIcon;
end;

destructor TTrayNotifyIcon.Destroy;
begin
if FIconVisible then SetIconVisible(False); // destroy icon
FIcon.Free; // free stuff
FTimer.Free;
inherited Destroy;
end;

function TTrayNotifyIcon.ActiveIconHandle: THandle;
{ Returns handle of active icon }
begin
{ If no icon is loaded, then return default icon }
if (FIcon.Handle <> 0) then
Result := FIcon.Handle
else
Result := FDefaultIcon;
end;

procedure TTrayNotifyIcon.LoadDefaultIcon;
{ Loads default window icon to keep it handy. }
{ This will allow the component to use the windows logo }
{ icon as the default when no icon is selected in the }
{ Icon property. }
begin
FDefaultIcon := LoadIcon(0, IDI_WINLOGO);
end;

procedure TTrayNotifyIcon.Loaded;
{ Called after component is loaded from stream }
begin
inherited Loaded;
{ if icon is supposed to be visible, create it. }
if FIconVisible then
SendTrayMessage(NIM_ADD, NIF_MESSAGE or NIF_ICON or NIF_TIP);
end;

procedure TTrayNotifyIcon.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = PopupMenu) then
PopupMenu := nil;
end;

procedure TTrayNotifyIcon.OnButtonTimer(Sender: TObject);
{ Timer used to keep track of time between two clicks of a }
{ double click. This delays the first click long enough to }
{ ensure that a double click hasn't occurred. The whole }
{ point of these gymnastics is to allow the component to }
{ receive OnClicks and OnDblClicks independently. }
begin
{ Disable timer because we only want it to fire once. }
FTimer.Enabled := False;
{ if double click has not occurred, then fire single click. }
if (not FNoShowClick) and Assigned(FOnClick) then
FOnClick(Self);
FNoShowClick := False; // reset flag
end;

procedure TTrayNotifyIcon.SendTrayMessage(Msg: DWORD; Flags: UINT);
{ This method wraps up the call to the API's Shell_NotifyIcon }
begin
{ Fill up record with appropriate values }
with Tnd do
begin
cbSize := SizeOf(Tnd);
StrPLCopy(szTip, PChar(FHint), SizeOf(szTip));
uFlags := Flags;
uID := UINT(Self);
Wnd := IconMgr.HWindow;
uCallbackMessage := DDGM_TRAYICON;
hIcon := ActiveIconHandle;
end;
Shell_NotifyIcon(Msg, @Tnd);
end;

procedure TTrayNotifyIcon.SetHideTask(Value: Boolean);
{ Write method for HideTask property }
const
{ Flags to show application normally or hide it }
ShowArray: array[Boolean] of integer = (sw_ShowNormal, sw_Hide);
begin
if FHideTask <> Value then
begin
FHideTask := Value;
{ Don't do anything in design mode }
if not (csDesigning in ComponentState) then
ShowWindow(Application.Handle, ShowArray[FHideTask]);
end;
end;

procedure TTrayNotifyIcon.SetHint(Value: string);
{ Set method for Hint property }
begin
if FHint <> Value then
begin
FHint := Value;
if FIconVisible then
{ Change hint on icon on tray notification area }
SendTrayMessage(NIM_MODIFY, NIF_TIP);
end;
end;

procedure TTrayNotifyIcon.SetIcon(Value: TIcon);
{ Write method for Icon property. }
begin
FIcon.Assign(Value); // set new icon
{ Change icon on notification tray }
if FIconVisible then SendTrayMessage(NIM_MODIFY, NIF_ICON);
end;

procedure TTrayNotifyIcon.SetIconVisible(Value: Boolean);
{ Write method for IconVisible property }
const
{ Flags to add or delete a tray notification icon }
MsgArray: array[Boolean] of DWORD = (NIM_DELETE, NIM_ADD);
begin
if FIconVisible <> Value then
begin
FIconVisible := Value;
{ Set icon as appropriate }
SendTrayMessage(MsgArray[Value], NIF_MESSAGE or NIF_ICON or NIF_TIP);
end;
end;

procedure TTrayNotifyIcon.SetPopupMenu(Value: TPopupMenu);
{ Write method for PopupMenu property }
begin
FPopupMenu := Value;
if Value <> nil then Value.FreeNotification(Self);
end;

const
{ String to identify registered window message }
TrayMsgStr = 'DDG.TrayNotifyIconMsg';

procedure Register;
begin
RegisterComponents('New Component', [TTrayNotifyIcon]);
end;

initialization
{ Get a unique windows message ID for tray callback }
DDGM_TRAYICON := RegisterWindowMessage(TrayMsgStr);
IconMgr := TIconManager.Create;
finalization
IconMgr.Free;
end.




--------------------------------------------------------------------------------
来自:beta 时间:00-2-11 02:24:52 ID:184969
这样的控件很多嘛,何必自己劳神?



--------------------------------------------------------------------------------
来自:freeforever 时间:00-2-11 02:34:37 ID:184974
http://jinhe.163.net/有关于此内容的文章



--------------------------------------------------------------------------------
来自:hsw 时间:00-2-11 02:40:57 ID:184977
有给wrench抢先,
为什么每次又简单的问题,wrench总能……




--------------------------------------------------------------------------------
来自:sunyonghua 时间:00-2-13 16:30:50 ID:186126
我在《Delphi Developer's Handbook》中的配套光盘发现此控件(附带源码)。
可发E_mail到你的邮箱。欢迎其他人索取此控件。
我的E_mail:sunyonghua@163.net



--------------------------------------------------------------------------------
来自:haoxg 时间:00-2-14 19:22:55 ID:186758
这样的东东实在是太多了,到处都有。
我也写了一个这样的组件
下载地址:
http://person.zj.cninfo.net/~haohome/newsoft/systray.zip
或直接访问在下的主页: http://haoxg.yeah.net






--------------------------------------------------------------------------------
来自:yang_pk 时间:00-2-14 19:39:22 ID:186764
最简单就是用控件了,
如很有名的RxLib中就有.



--------------------------------------------------------------------------------
来自:xlf 时间:00-2-18 21:54:10 ID:188781
我还想听更多的意见!
请问怎样做成窗体是透明的?
不是用 Form1.Brush.Style := bsClear
因为用 bsClear 后,透明的窗体就成了当前背景的图形,
并不是透明的背景.



--------------------------------------------------------------------------------
来自:xxniao 时间:00-2-22 21:48:10 ID:190448
直接用shellAPI最简单,最方便。查一下help就可以用了,而且
别的语言也使用。如果想要例子的话,发信到xiaoxiaoniao@263.net

前边讨论过了,用mouse_event.
模拟点击:
mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );

移动:
Mouse_Event(MOUSEEVENTF_MOVE,1,1,0,0);

问题的标题是:如何用鼠标指向截获其它程序的句柄?(100分)
问题的分类是:系统相关 , 分坛主: cAkk, 分坛主: lhz 来自:liangliang 时间:00-2-22 02:40:33 ID:190061
如题。





--------------------------------------------------------------------------------
来自:hubdog 时间:00-2-22 07:49:46 ID:190063
在一个TTimer控件的ontime事件中加入
var
WinPos:TPoint;
WinHandle:Thandle;
begin
GetCursorPos(WinPos);
WinHandle:=WindowFromPoint(WinPos);
end;


来自:lhxu 时间:99-11-13 21:19:38 ID:154788
不好意思,赶快把CJ小弟弟扶起来(CJ大富翁之最--年轻)
我的意思是用键盘的 方向建模拟鼠标的动作




--------------------------------------------------------------------------------
来自:hansong 时间:99-11-14 11:24:34 ID:154936
放置一个button,设置form.keypreview=true;

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,math;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure Button1Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormDblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Step:integer=4;
down:boolean=false;

implementation

{$R *.DFM}

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var mousepos:tpoint;
begin
case key of
'*': SetCursorPos(trunc(screen.Width/2),trunc(screen.height/2));
'a','A':
{left}
begin
GetCursorPos(mousepos);
SetCursorPos(max(mousepos.x-step,0),mousepos.y);
end;
'd','D':
{Right}
begin
GetCursorPos(mousepos);
SetCursorPos(min(screen.Width,mousepos.x+step),mousepos.y);
end;
's','S':
{Down}
begin
GetCursorPos(mousepos);
SetCursorPos(mousepos.x,min(screen.width,mousepos.y+step));
end;
'w','W':
{Up}
begin
GetCursorPos(mousepos);
SetCursorPos(mousepos.x,max(0,mousepos.y-step));
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (key=ord('o'))or(key=ord('O')) then
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (key=ord('o'))or(key=ord('O')) then
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
end;

procedure TForm1.FormDblClick(Sender: TObject);
begin
ShowMessage('this is doubleclick');
end;

end.




--------------------------------------------------------------------------------
来自:hansong 时间:99-11-14 11:27:33 ID:154937
方向键?没看清,那全要放在keydown里了.



--------------------------------------------------------------------------------
来自:menxin 时间:99-11-15 11:29:47 ID:155273
怎么没了响应?我给你改一个

unit keydown;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,math;

type
TForm1 = class(TForm)
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormDblClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Step:integer=4;

implementation

{$R *.DFM}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var mousepos:tpoint;
begin
case key of
ord('*'):{reset mouse pos} SetCursorPos(trunc(screen.Width/2),trunc(screen.height/2));
VK_LEFT:
{left}
begin
GetCursorPos(mousepos);
SetCursorPos(max(mousepos.x-step,0),mousepos.y);
end;
VK_RIGHT:
{Right}
begin
GetCursorPos(mousepos);
SetCursorPos(min(screen.Width,mousepos.x+step),mousepos.y);
end;
VK_DOWN:
{Down}
begin
GetCursorPos(mousepos);
SetCursorPos(mousepos.x,min(screen.width,mousepos.y+step));
end;
VK_UP:
{Up}
begin
GetCursorPos(mousepos);
SetCursorPos(mousepos.x,max(0,mousepos.y-step));
end;
end;
if (key=ord('o'))or(key=ord('O')) then
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (key=ord('o'))or(key=ord('O')) then
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
end;

procedure TForm1.FormDblClick(Sender: TObject);
begin
ShowMessage('this is doubleclick');
end;

procedure TForm1.FormShow(Sender: TObject);
begin
Form1.SetFocus;
end;


<font size=6 color="RED">是不是太多了?嘻嘻,你解决了能不能把源程序发给我?分数原数奉还!</font>
 
简单点罗:

findwindow可以获得窗口句柄, findwindowex找到button句柄, 然后
sendmessage(hwnd, bm_click,0,0)

findwindow时你需要知道class,所以你可以先用enumwindow获得当前系统所有
窗口及窗口类
 
首先,谢谢Atomic及yifeng
不过,Atomic贴了那么多,还没有说到主题去,还不能'点击另一个程序窗口上的一
个按钮'。
yifeng, 我用enumwindows就获得了窗口的句柄了,但如何查到此按钮,并单击它?
 
findwindowex(yourwindowhwnd,0,Tbutton, yourbuttoncaption)
 
现在,我可以做到我原先提到的要求了,但是发觉,要点击的那另一窗口上的那个
按钮,我不能用sendmessage(hwnd, bm_click,0,0)来模拟点击,只是将那按钮
变成了当前焦点,但没有引发其它事儿,一定要真正的点击才行,怎样模拟真正的
点击呢?这两者有什么不同呢?
谢谢!
 
PostMessage(Handle,WM_CLOSE,0,0);
 
不行呀,我用PostMessage也不行呀,
后来,我就用SetForegroundWindow先把那个窗口激活,再用
PostMessage(ahwnd, WM_LBUTTONDOWN,MK_LBUTTON,0);
Sleep(800);
PostMessage(ahwnd, WM_LBUTTONUP,MK_LBUTTON,0);
点击那个按钮也不行!
按钮是点击了,但是没有作用,本来,用Mouse点击那个按钮后,
窗口会关闭的,但是我使用了以上几个语句模拟点击后,也不能关闭窗口。
但按钮确实是按了下去了!
是啥回事呢?
谢谢大家
 
哦,还有,如何知道那个按钮的坐标呢?在Screen上的坐标,
知道后,我想试把Mouse移动那个按钮位置,再模拟点击!
行不?
知道了那个按钮的Handle,如何知道坐标?
谢谢!
 
我怎么就可以.我是这样试的.

先用Delphi建立一程序,只有一个form,form上就一个button,button的事件就是
关闭程序.

在另一个程序,用findwindow得到主form的handle,再用findwindowex得到button1
的handle,用SendMessage(H2,bm_click,0,0);就可以关闭上面那个程序.

var
H1,H2:THandle;
begin
H1:=FindWindow('TForm1','shenqw');
H2:=Findwindowex(H1,0,'TButton','Button1');
SendMessage(H2,bm_click,0,0);
end;
 
对,沈前卫, 我也象你一样,尝试过自己写另一个窗口来测试,测试是通过了!
但是,在那个程序中,还是不行,关闭不了!
我发觉,在点击那个按钮的时候,光标并没有移动按钮上。
有没有办法知道那按钮的坐标,再把光标移动它的上面,再模拟Mouse点击呢?
谢谢!
 
应该可以,带我写个测试程序试试.
 
应该可以,带我写个测试程序试试.

var
H1,H2:THandle;
Rect:TRect;
P1,P2:TPoint;
begin
H1:=FindWindow('TForm1','shenqw');
H2:=Findwindowex(H1,0,'TButton','Button1');
GetWindowRect(H2,Rect);
P1:=Rect.TopLeft;
P2:=Rect.BottomRight;
Windows.ClientToScreen(H2,P1);
Windows.ClientToScreen(H2,P2);
ShowMessage(IntToStr(P1.x));
end;
 
问题已经解决,在此,谢谢各位的帮助
我现在将代码贴出,以作参考
function EnumWindowsProc(AHWnd: HWnd; LPARAM: lParam): boolean; stdcall;
var
WndCaption: array[0..254] of char;
WndClassName: array[0..254] of char;
rtscreen: trect;
WinXY:TRect;
xy:TPoint;
begin
GetWindowText(AHWnd, @WndCaption, 254);
GetClassName(AHWnd, @WndClassName, 254);
if (pos('CashSurfers.com',wndcaption)<>0) then //用你已知的窗口标题替换这里, 找到此窗口
begin
ahwnd:=findwindowEX(ahwnd,0,pchar('TButton'),pchar('Cool!')); // 找到窗口上的按钮
GetWindowRect(AHWnd,WinXY); // 得到按钮的坐标范围
xy:=WinXY.TopLeft; // 取得按钮左上角的坐标
xy.x:=xy.x+10;
xy.y:=xy.y+10;
SetCursorPos(xy.x,xy.y); // 将Mouse定位到按钮上
Mouse_Event(MOUSEEVENTF_LEFTDown,xy.x,xy.y,0,0); // 按下左键
Mouse_Event(MOUSEEVENTF_LEFTUP, xy.x,xy.y,0,0); // 按下右键
end;
Result := True
end;
 
多人接受答案了。
 
后退
顶部