2

我正在尝试将一些文本发布到 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++ 打印屏幕

谢谢。

4

1 回答 1

1

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

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

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));
于 2018-04-10T22:53:17.443 回答