获取 Delphi 窗口句柄

7

我正在尝试从外部应用程序获取Delphi应用程序的窗口句柄。我可以看到创建了几个窗口(TApplication,TFrmMain和其他一些窗口),我知道TApplication是“控制器”,但从未可见。然而,我能否读取真实窗口的值?我知道它是TFrmMain(对于这个特定的应用程序),但是否可能通过某种方式实际上找出这一点呢?信息存储在窗口属性中还是其他地方?谢谢!

3个回答

14

没有记录的方法可以从应用程序外部发现哪个窗口代表Application.MainForm。在较新版本的Delphi中,主窗体的窗口句柄不一定是Application.MainForm.Handle;应用程序可以处理OnGetMainFormHandle事件以返回任何它们想要的内容——这用于选择模态对话框的父窗口。

您可以通过查找类名中带有“main”字样的窗口来猜测,但即使您找到了一个,也不能保证只有一个实例。应用程序可以具有多个顶级窗口,在这种情况下,将任何一个窗口指定为“主”窗口并没有太多意义。


谢谢,我很害怕。:( - Jon Tackabury

4

任何 Delphi 表单的类名也是底层 "Windows 窗口" 的注册窗口类名。因此,您应该能够使用 FindWindow() Windows API 调用来获取 TFrmMain 窗口句柄,类似于:

 hWnd := FindWindow('TFrmMain', NIL);

如果一个给定的表单类名有(可能)多个实例,那么您可以使用第二个参数(窗口名称,即“标题”或标题)来区分它们。如果这仍然不足够,那么您可能需要更加复杂一些,并查看使用EnumWindows()函数并检查窗口的属性以找到感兴趣的窗口。
要测试任意窗口句柄的类名(例如,在您使用EnumWindows()回调函数中),请使用GetClassName(),例如:
function GetWindowClassName(const aHWND: HWND): String;
var
  buf: array[0..255] of Char;  // Tip: Use a more appropriately sized array
begin
  GetClassName(SomeHWND, @buf, Length(buf));
  result := buf;
end;

...

if SameText(GetWindowClassName(hwnd), 'TFrmMain') then
  ...

etc

如果没有您特定实现挑战的具体细节,很难确定哪种方法最适合您,但希望这些提示足以让您朝着正确的方向前进。


1

我通常使用WinDowse来帮助我入门,但是接下来你必须按照Deltics所描述的API函数进行操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接