200大讨论:能者拿分--句柄 ( 积分: 200 )

  • 主题发起人 主题发起人 shell~
  • 开始时间 开始时间
S

shell~

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在写了一个程序A.exe控制另一个程序B.exe<br>B.exe窗体中有五个Edit,只知道它们是TEDIT类,不知道什么名称。<br>A.exe窗体中也有五个Edit,与B.exe中的一一对应。我现在要实现的就是把A.exe中五个EDIT的内容发送B.exe中的相对应的EDIT。<br>我如果得到B.exe窗体的中每个Edit的位置,从而ChildWindowFromPoint得到它的句柄。不要跟我说用猜的喔,有没有相关的API可得到其位置(不是相对屏幕的位置)
 
我现在写了一个程序A.exe控制另一个程序B.exe<br>B.exe窗体中有五个Edit,只知道它们是TEDIT类,不知道什么名称。<br>A.exe窗体中也有五个Edit,与B.exe中的一一对应。我现在要实现的就是把A.exe中五个EDIT的内容发送B.exe中的相对应的EDIT。<br>我如果得到B.exe窗体的中每个Edit的位置,从而ChildWindowFromPoint得到它的句柄。不要跟我说用猜的喔,有没有相关的API可得到其位置(不是相对屏幕的位置)
 
有API,但我不记得了,我是在《Delphi开发人员指南》一书上看到的,<br>那上面刚好有这个列题。
 
哪一单,我也有这本书。
 
可以用api取得位置,但是好像要指定控件句柄,而你要取的恰恰是句柄,所以这种方法可能不行。<br>可以考虑用鼠标hook挂到你的程序B上,当在控件上动作鼠标时就可以取道位置,然后用ChildWindowFromPoint取得句柄
 
给你一个程序,你自己看看,也许对你有帮助:<br><br>Delphi学习:查句柄知多少 出处:CSDN <br> <br>[ 2004-11-02 14:10:38 ] &nbsp;作者:pggpjj &nbsp;责任编辑:linjixiong <br><br>  基本上句柄是标志窗口,我可以根据句柄又可引申其中更多如类名,windowtitle等属性所以基于这点,一般开发工具会提供查句柄,查类名等工具,vs提供的spy++就是一个很好例子。现在教你们一查句柄知多少。其实也简单,下面贴出源代码。<br><br><br><br><br>   procedure Tform1.TimerTimer(Sender: TObject);<br>  var<br>  Pos: TPoint;<br>  Handle: HWND;<br>  ScreenDC: HDC;<br>  Buf: array[0..1024] of Char;<br>  ScreenColor: COLORREF;<br>  begin<br>  GetCursorPos(Pos); // 得到当前光标位置<br>  Handle := WindowFromPoint(Pos); // 返回当前位置的句柄<br>  HandleText.Caption := IntToStr(Handle);<br>  GetClassName(Handle, Buf, 1024); // 得到类名<br>  ClassNameText.Caption := Buf;<br>  SendMessage(Handle, WM_GETTEXT, 33, Integer(@Buf)); // 得到标题<br>  TitleText.Caption := Buf;<br>  { 得到光标处点的颜色 }<br>  ScreenDC := GetDC(0);<br>  ScreenColor := GetPixel(ScreenDC, Pos.X, Pos.Y);<br>  Shape.Brush.Color := TColor(ScreenColor);<br>  RGBColorText.Caption := '红: ' + IntToStr(GetRValue(ScreenColor)) +<br>  ' &nbsp;绿: ' + IntToStr(GetGValue(ScreenColor)) + ' &nbsp;蓝: ' +<br>  IntToStr(GetBValue(ScreenColor));<br>  ReleaseDC(0, ScreenDC);<br>  DelphiColorText.Caption := Format('Delphi中颜色值:$00%2.2x%2.2x%2.2x', [GetBValue(ScreenColor),<br>  GetGValue(ScreenColor), GetRValue(ScreenColor)]);<br>  HTMLColorText.Caption := Format('HTML颜色值:#%2.2x%2.2x%2.2x', [GetRValue(ScreenColor),<br>  GetGValue(ScreenColor), GetBValue(ScreenColor)]);<br>  end;  <br>
 
没太看明白什么意思,不过可以用FindWindowEx来得到自控件的句柄.[:)]
 
脑筯要转一转了,其实用相对位置也一样能得到呀,方法其实很多的。<br>说一个吧:按类和标题找到窗口,在遍历每个控件,如果相对位置和需要的控件相同。知道怎么办了吧。
 
TO weiliu: 你的方法我已经实现了,我不想用光标去取句柄,五个EDIT我要点五次。我是想通过计算每个EDIT的位置得出他们的句柄,我只要点一个按钮,五个文本全部发送出去。<br>TO 迷糊:B程序是别人的可执行程序,我该怎么办:<br>TO delphi2006:我比较笨,请详细说明。
 
不是很明白楼主的意思,给你函数吧<br><br>1. &nbsp; &nbsp;//取句柄<br> &nbsp; &nbsp;AHandle := FindWindow(nil, '计算器'); &nbsp;//就是窗口的Caption<br>//或 &nbsp;AHandle := GetActiveWindow; //或GetForeGroundWindow;获得当前激活窗体的句柄<br>2. 枚举组件,例: <br> &nbsp; if AHandle &amp;lt;&amp;gt; 0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;//在这里循环取到想要的句柄为止<br> &nbsp; &nbsp; &nbsp; &nbsp;EnumChildWindows(AHandle, @GetComponentHandle, Integer(@BHandle));<br> &nbsp; &nbsp; &nbsp; &nbsp;//此时,BHandle就是你要的句柄<br> &nbsp; &nbsp; &nbsp; &nbsp;PostMessage(BHandle, BM_Click, 0, 0); //向这个按钮发一个点击消息<br> &nbsp; &nbsp;end;<br>3. 判断 <br>function GetComponentHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>var<br> &nbsp;buffer: array[0..255] of Char;<br> &nbsp;ARect: TRect;<br> &nbsp;APoint: TPoint;<br>begin<br> &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp;//得到目标窗口的控件<br>{<br> &nbsp; &nbsp;GetClassName(hwnd, buffer, 256);<br> &nbsp; &nbsp;//找到目标窗口的TButton类目标控件<br> &nbsp; &nbsp;if StrPas(Buffer)='TButton' then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;PInteger(lparam)^ := hwnd; //得到目标控件的Hwnd(句柄)<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=False; &nbsp;//终止循环<br> &nbsp; &nbsp;end;<br>}<br>//其他函数<br>// &nbsp; &nbsp;GetWindowRect(hWnd, ARect); &nbsp;//组件的位置<br>// &nbsp; &nbsp;GetCursorPos(APoint); &nbsp; &nbsp; &nbsp; &nbsp;//光标的位置<br>// &nbsp; &nbsp;if PtInRect(ARect, APoint) then &nbsp; //光标是否在组件中<br> &nbsp; &nbsp;//找到目标窗口的目标控件(按标题)<br> &nbsp; &nbsp;GetWindowText(hwnd, buffer, 100);<br> &nbsp; &nbsp;if StrPas(Buffer)='Button1' then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;PInteger(lparam)^ := hwnd; //得到目标控件的Hwnd(句柄)<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=False; &nbsp;//终止循环<br> &nbsp; &nbsp;end;<br>end;<br><br>
 
当需要获取另外一个应用程序中的所有控件句柄时:<br>因为回调函数只能返回一个句柄,所以需要全局变量在回调函数获取。例:<br>var MyHandle :TStringList;<br> &nbsp; &nbsp;MyHandle :=TStringList.Create;<br><br>function GetComponentHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br>var<br> &nbsp;buffer: array[0..255] of Char;<br>begin<br> &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp;//得到目标窗口的控件<br> &nbsp; &nbsp;MyHandle.add(IntToStr(hwnd));//找到目标窗口的句柄<br>// &nbsp; &nbsp;GetClassName(hwnd, buffer, 256);<br>// &nbsp; &nbsp;MyHandle.add(StrPas(Buffer));//找到目标窗口的T类名<br>// &nbsp;等<br>end;<br>
 
TO yostgxf:问题是5个EDIT的TEXT都为空。
 
我现在的问题是:如果取得B.exe中的五个Edit各自的x,y坐标(窗体相对位置,不是屏幕相对位置)
 
上面我已经给你很多的函数了<br> &nbsp; &nbsp;GetClassName(hwnd, buffer, 256);<br> &nbsp; &nbsp;//找到目标窗口的TEdit类目标控件<br> &nbsp; &nbsp;if StrPas(Buffer)='TEdit' then<br>根据类名,TEdit 你可以找到所有的TEdit<br><br>其他的你类推吧
 
yostgxf:我如何区别这五个EDIT
 
这个你自己想想办法<br>比如用句柄,位置,还有看看它们的 &nbsp; &nbsp;//找到目标窗口的目标控件(按标题)<br> &nbsp; &nbsp;GetWindowText(hwnd, buffer, 100);<br>是不是相同的。<br><br>枚举函数会把所有的都列出来,你自己试一试嘛
 
[:(]晕了晕了。
 
&nbsp; &nbsp;我的意思是在你的程序(A)中用鼠标hook挂到别人的程序B中,然后当你在程序B的点edit的时候求可以取到handle了,但是好像你不愿意用鼠标点击取得句柄。:(<br> &nbsp; &nbsp;有个比较愚蠢的办法,先遍历B所有的edit,用setwindowtext给他附上不同的序号(1,2,3,4,5),然后用findwindwex一个一个对去吧,呵呵
 
我在遍历B的时候,回调函数总是出错。定义了一个MyHandle的StringList变量<br>var<br> &nbsp; &nbsp;fHd: HWND;<br>function EnumChildWindowsProc(hwnd: Integer; lparam: Longint):Boolean; stdcall;<br> &nbsp;var<br> &nbsp; &nbsp;buffer: array[0..255] of Char;<br> &nbsp;begin<br> &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp;//得到目标窗口的控件<br> &nbsp; &nbsp;GetClassName(hwnd,buffer,256);<br> &nbsp; &nbsp;//找到发消息的目标窗口的目标控件<br> &nbsp; &nbsp;if StrPas(Buffer)='TEdit' then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;//ShowMessage(IntToStr(hwnd));<br> &nbsp; &nbsp; &nbsp;//MyHandle.Add(IntToStr(hwnd)); //得到目标控件的Hwnd(句柄)<br> &nbsp; &nbsp; &nbsp;Memo1.Lines.Add(IntToStr(hwnd));<br> &nbsp; &nbsp; &nbsp;//Result:=False; &nbsp;//终止循环<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br>begin<br> &nbsp;fHd:=0;<br> &nbsp; &nbsp;fHd:=FindWindow(nil,Pchar('基本信息...信息框'));//按标题找父窗口的句柄<br> &nbsp; &nbsp;if fHd=0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage('找不到标题为基本信息...编辑框的窗口!');<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;enumchildwindows(fhd,@EnumChildWindowsProc,0);<br>end;
 
后退
顶部