除了Handle,怎样唯一识别一个进程中的窗口(HWND)?(100分)

  • 主题发起人 主题发起人 lxggc
  • 开始时间 开始时间
L

lxggc

Unregistered / Unconfirmed
GUEST, unregistred user!
因为窗口的Handle会在每次重新启动后发生改变,比如一个EDIT控件,每次程序运行时它的Handle都会发生改变,有没有办法对一个Window中的ChildWindow(如一个Form中的Edit)进行唯一识别?也就是每次程序启动时我都能找到这个ChildWindow.<br>控件的 Z 顺序只是一种不太完美的解决,因为Z顺序也可能会发生改变。<br>
 
不明白意思,到底要实现什么?<br>程序启动的时候当然能找到 这个Edit,<br>你用name属性不能找到该控件?
 
to yf168:<br>&nbsp; 谢谢你的关注,可能是我表述不清,举个例子: 我要用程序往 IE 的地址栏输入超连接文本,必须先找到能唯一识别这个地址栏的标志,并且在 IE 重新启动后能重新找到这个地址栏, 可是地址栏的 Handle 在每次 IE 重启之后都会发生改变。<br>&nbsp; 我现在的问题就是,假设在一个Window中同时存在多个Edit, 有没有办法能区分他们?
 
对于你碰到的问题,如果你没试过用TIEcontroller,建议你试一试。<br>&nbsp; uses &nbsp;IEController;<br>&nbsp; IEControl:TIEController; &nbsp;<br>&nbsp; IEControl := TIEController.Create(Self);<br>&nbsp; IEControl.open;
 
&gt;&gt;我现在的问题就是,假设在一个Window中同时存在多个Edit, 有没有办法能区分他们? <br>记数器
 
看来还有些朋友不明白我的意思:假设有一个他人编写的程序,其中一个窗口中有5个Edit,<br>包括一个输入用户名的 Edit,现在我要做一个程序,能在它的程序每次启动时都能自动输入用户名,但我首先要找到这个 Edit。(这些Edit的位置,顺序都有可能发生变化)
 
用WindowFromPoint
 
EnumChildWindows(hFind,@EnumChildWindowsProc,Integer(@hFind));<br>// &nbsp;hFind &nbsp;窗口handle<br>function EnumChildWindowsProc(hwnd: Integer): Boolean; stdcall;<br>&nbsp; var<br>&nbsp; &nbsp; buffer: array[0..255] of Char;<br>&nbsp; &nbsp; buffer1: array[0..255] of Char;<br><br>&nbsp; begin<br>&nbsp; &nbsp; Result := True;<br>&nbsp; &nbsp; GetClassName(hwnd,buffer,256); &nbsp;//得到类名<br>&nbsp; &nbsp; GetWindowText(hwnd,Buffer1,256);<br>&nbsp; &nbsp; if StrPas(Buffer) = 'TEdit' then<br>&nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; //这里你可以计数,比如,第一个是什么。。一般是不会变的。<br>&nbsp; &nbsp; &nbsp; &nbsp; if iNum = 1 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hBack &nbsp;:= hwnd ;<br>&nbsp; &nbsp; end;<br>end;
 
to ranksun:<br>你的方法我也想到过,基本可行,但如果在程序运行中动态创建或删除Edit就没有办法了。<br>我估计解决这个问题很难 :-(
 
如果这样你就Hook api<br>只要以创建窗口就先调用你的替换API,然后你就能知道了
 
请详细解释一下好不好?Hook API
 
我还真没有想到好的办法:<br>&nbsp; 假设在一个Window中同时存在多个Edit, 有没有办法能区分他们?<br>顶<br>(回去查一下资料)
 
期待高手的加入,顶。。。。。。。。
 
下面是论坛上一为朋友发的帖子,我想你应该是这个意思.<br>先发给你,免得你去找了.<br><br>unit OicqSendForm;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, Buttons, ExtCtrls;<br><br>type<br>&nbsp; TfrmMain = class(TForm)<br>&nbsp; &nbsp; memText: TMemo;<br>&nbsp; &nbsp; edtTime: TEdit;<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Bevel1: TBevel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; bbtnStart: TBitBtn;<br>&nbsp; &nbsp; bbtnEnd: TBitBtn;<br>&nbsp; &nbsp; bbtnHelp: TBitBtn;<br>&nbsp; &nbsp; Timer: TTimer;<br>&nbsp; &nbsp; procedure bbtnStartClick(Sender: TObject);<br>&nbsp; &nbsp; procedure bbtnEndClick(Sender: TObject);<br>&nbsp; &nbsp; procedure TimerTimer(Sender: TObject);<br>&nbsp; &nbsp; procedure bbtnHelpClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; FTextHandle: HWND; &nbsp; //qq消息输入框句柄<br>&nbsp; &nbsp; FButtonHandle: HWND; //发送按钮输入框<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; frmMain: TfrmMain;<br><br>implementation<br><br><br>//这个函数取当前qq发送窗口上“送讯息”的按钮的句柄<br>//function EnumChildWindowsProc(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>function GetButtonHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>var<br>&nbsp; buffer: array[0..255] of Char;<br>&nbsp; buffer1: array[0..255] of Char;<br>begin<br>&nbsp; Result := True;<br>&nbsp; //得到目标窗口的控件<br>&nbsp; GetClassName(hwnd,buffer,256);<br>&nbsp; //找到发消息的目标窗口的目标控件<br>&nbsp; if StrPas(Buffer)='Button' then<br>&nbsp; begin<br>&nbsp; &nbsp; GetWindowText(hwnd,buffer1,100);<br>&nbsp; &nbsp; if buffer1 = '送讯息(&amp;S)' then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; PInteger(lparam)^ := hwnd; //得到目标控件的Hwnd(句柄)<br>&nbsp; &nbsp; &nbsp; Result:=False; &nbsp;//终止循环<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;//end of function<br><br>//这个函数取当前qq发送窗口上消息框句柄<br>//function EnumChildWindowsProc(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>function GetEditHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>var<br>&nbsp; buffer: array[0..255] of Char;<br>&nbsp; buffer1: array[0..255] of Char;<br>begin<br>&nbsp; Result := True;<br>&nbsp; //得到目标窗口的控件<br>&nbsp; GetClassName(hwnd,buffer,256);<br>&nbsp; //找到发消息的目标窗口的目标控件<br>&nbsp; if StrPas(Buffer)='Edit' then<br>&nbsp; begin<br>&nbsp; &nbsp; GetWindowText(hwnd,buffer1,100);<br>&nbsp; &nbsp; PInteger(lparam)^ := hwnd; //得到目标控件的Hwnd(句柄)<br>&nbsp; &nbsp; Result:=False; &nbsp;//终止循环<br>&nbsp; end;<br>end;//end of function<br><br>{$R *.DFM}<br><br>procedure TfrmMain.bbtnStartClick(Sender: TObject);<br>var<br>&nbsp; Handle: Integer;<br>&nbsp; tmpHandle: Integer;<br>begin<br>&nbsp; {取句柄}<br>&nbsp; Handle := FindWindow(nil,'对话模式'); &nbsp;//就是窗口的Caption<br>&nbsp; if Handle&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; tmpHandle := Handle;<br>&nbsp; &nbsp; //在这里循环取到想要的句柄为止<br>&nbsp; &nbsp; //取发送按钮的,FButtonHandle<br>&nbsp; &nbsp; EnumChildWindows(Handle,@GetButtonHandle,Integer(@Handle));<br>&nbsp; &nbsp; FButtonHandle := Handle;<br><br>&nbsp; &nbsp; //取消息输入框的,FTextHandle<br>&nbsp; &nbsp; EnumChildWindows(tmpHandle,@GetEditHandle,Integer(@tmpHandle));<br>&nbsp; &nbsp; FTextHandle := tmpHandle;<br><br>&nbsp; &nbsp; Timer.Interval := StrToInt(edtTime.Text);<br>&nbsp; &nbsp; Timer.Enabled := true;<br>&nbsp; end;//end of if<br><br>end;<br><br>procedure TfrmMain.bbtnEndClick(Sender: TObject);<br>begin<br>&nbsp; Timer.Enabled := false;//关闭定时器<br>end;<br><br>procedure TfrmMain.TimerTimer(Sender: TObject);<br>begin<br>&nbsp; {定时发送}<br>&nbsp; //设发送文本<br>&nbsp; SendMessage(FTextHandle,WM_SETTEXT,0,Integer(pchar(memText.Text)));<br><br>&nbsp; //发送按钮<br>&nbsp; //SendMessage(FButtonHandle,BN_CLICKED,0,0);<br>&nbsp; SendMessage(FButtonHandle,WM_LBUTTONDOWN,0,0);<br>&nbsp; SendMessage(FButtonHandle,WM_LBUTTONUP,0,0);<br>end;<br><br>procedure TfrmMain.bbtnHelpClick(Sender: TObject);<br>var<br>&nbsp; sHelp: String;<br>begin<br>&nbsp; //帮助<br>&nbsp; sHelp := '打开要发送的对象窗口'+#13+<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'选择对话模式后点[开始]!';<br>&nbsp; ShowMessage(sHelp); &nbsp; &nbsp; &nbsp; &nbsp; <br><br>end;<br><br>end.
 
to:newsha,<br>&nbsp; 谢谢你的回答,可是你的方法仍然不能解决问题,在 GetEditHandle 中只是简单的判断一个Hwnd的ClassName是否为 Edit,如果在窗口中出现多个 Edit的情况下你的程序就行不通了,我要求的是从多个Edit中找到我需要的一个。
 
如果是VC的程序,可以找到dialog资源,有唯一的资源ID<br>如果是delphi程序,frm文件上name是唯一标识。<br>
 
靠位置来区分,别告诉我位置也是变的。
 
to kawen:<br>&nbsp; 即使在 VC 中, Edit也不见得是放在 dialog 中<br><br>to satanmonkey:<br>办法蠢了点,但还真的可行,^_^,人太多,只好见者有份了,谢谢各位了!
 

Similar threads

S
回复
0
查看
832
SUNSTONE的Delphi笔记
S
S
回复
0
查看
792
SUNSTONE的Delphi笔记
S
后退
顶部