在挂钩到Drawtext函数后获取控件的位置

时间:2013-12-09 17:15:22

标签: delphi winapi

我有一个VCL应用程序,我正在测试,但没有源代码。 我需要验证屏幕上标签的文本是什么,但标签不是窗口,所以我创建了一个绘制文本功能的钩子,我可以得到绘制到屏幕上的文本。

但我无法验证屏幕上绘制文本的位置,因为函数获取hdc以及在上下文中绘制文本的位置。 我需要确定屏幕上hdc所在的位置,并确保标签正确。

有办法吗? 管理不受管理的剂量对我来说无关紧要。

2 个答案:

答案 0 :(得分:1)

我认为你需要做这样的事情:

  1. 调用WindowFromDC找出托管标签的窗口。如您所知,Delphi标签是非窗口的,控件实际上在其父窗口上绘制。如果父缓冲区是双缓冲的,则可能会失败。在这种情况下,你没有希望从设备上下文中获取窗口句柄,因为你所拥有的只是位图的设备上下文。
  2. 现在您有了标签所在的窗口,您需要找到窗口上标签的位置。 VCL调用SetWindowOrgEx来安排设备上下文在标签的左上角有逻辑坐标0,0。因此,您可以调用GetWindowOrgEx来查找标签相对于父母的位置。
  3. 现在您知道标签相对于父级的位置以及父级的窗口句柄,您可以使用ClientToScreen计算出在屏幕上绘制文本的位置。
  4. 由于设备上下文仅在拥有它们的进程中具有意义,因此您需要注入目标进程以调用它。

答案 1 :(得分:1)

您可以在Delphi中构建DLL并在目标进程中注入该DLL。由于你正在愉快地挂钩Win32 APis,我想你不会有这个问题。

在该DLL中,您可以找到(使用Win32 API)HWND,它是Label的“父”。

使用该HWND,您可以找到关联的TWinControl。为此,您必须深入了解VCL源代码。

对于Delphi 4(是的,我知道,它已经老了)你必须构建一个Atom字符串,使用GlobalFindAtom,然后使用GetProp。结果是指向TWinControl的指针。

对于Delphi7(也是旧的),你必须使用RegisterWindowMessage和一个由“ControlOfs”组成的字符串,然后是模块句柄和线程ID。 LRESULT的{​​{1}}是指向SendMessage的指针。

很抱歉,我不知道其他Delphi版本,但所有版本都应该在VCL源代码中找到。

获得TWinControl指针后,您可以将子项枚举为TWinControl,并获取TComponent个(因为它们出现在您没有的源代码中)。 ..),他们的Name等等,你明白了。