使用FindWindowEx()查找编辑框的正确句柄

时间:2018-04-10 13:12:43

标签: freepascal findwindowex

我试图将一些文本发布到Windows树上第3级的编辑框中。 以下代码适用于记事本( vrr02 ),但不适用于其他程序( Var03 )。

procedure TEcr01.Button1Click(Sender: TObject);
var Var01, Var02, Var03, vrr01, vrr02: HWND;
    MyTxt : string;
begin
  Var01 := FindWindow('#32770', nil);
  Var02 := FindWindowEx(Var01, 0, '#32770', nil);
  Var03 := FindWindowEx(Var01, Var02, 'Edit', nil);
  vrr01 := FindWindow('notepad', nil);
  vrr02 := FindWindowEx(vrr01, 0, 'edit', nil);
  MyTxt := 'This is some text.';
  SendMessage(Var03, WM_SETTEXT, 0, integer(MyTxt));
  SendMessage(vrr02, WM_SETTEXT, 0, integer(MyTxt));
end;

以下图片为蓝色,我要发布的编辑但没有显示任何内容。我在这做错了什么?

Spy++ print-screen

感谢。

1 个答案:

答案 0 :(得分:1)

使用当前代码,您无法确定在任何阶段是否拥有所需的窗口句柄。

“#32770”是标准对话框类,在用户会话中的任何给定时间都可以有许多此类窗口。您在FindWindow电话中传递了lpWindowName参数的nil,文档说明:

  

lpWindowName [in,optional]   
类型: LPCTSTR

     


窗口名称(窗口标题)。如果此参数为 NULL ,则所有窗口名称都匹配。

因此,在Var01上有一个完全不同的窗口句柄,它具有相同的类但窗口标题不同。

或者根本没有。这就是为什么你必须在每次API调用后检查函数是否失败。有关如何使用,请参阅功能文档。


Var01 := FindWindow('#32770', 'Object Properties');
Win32Check(Var01 <> 0);

上面的调用指定了类名和窗口标题,这保证了函数将返回所需的窗口句柄。

Var02 := FindWindowEx(Var01, 0, '#32770', nil);
Win32Check(Var02 <> 0);

对Var02的调用看起来没问题。但Var03的父母是Var02,所以你第三次再次打错了。

Var03 := FindWindowEx(Var02, 0, 'Edit', nil);
Win32Check(Var03 <> 0);

这将检索第一个编辑,隐藏的编辑。您必须再次调用FindWindowEx以检索所需的子项,将前一个窗口指定为ChildAfter参数。

Var03 := FindWindowEx(Var02, Var03, 'Edit', nil);
Win32Check(Var03 <> 0);

另请注意,SendMessage的第四个参数不是整数,请始终参考文档。

总而言之:

Var01 := FindWindow('#32770', 'Object Properties');
Win32Check(Var01 <> 0);
Var02 := FindWindowEx(Var01, 0, '#32770', nil);
Win32Check(Var02 <> 0);
Var03 := FindWindowEx(Var02, 0, 'Edit', nil);
Win32Check(Var03 <> 0);
Var03 := FindWindowEx(Var02, Var03, 'Edit', nil);
Win32Check(Var03 <> 0);
MyTxt := 'This is some text.';
SendMessage(Var03, WM_SETTEXT, 0, LPARAM(MyTxt));
SendMessage(vrr02, WM_SETTEXT, 0, LPARAM(MyTxt));