【发布时间】:2013-12-10 02:46:38
【问题描述】:
我有一个正在测试的 VCL 应用程序,但没有源代码。 我需要验证在屏幕上的标签上绘制了哪些文本,但标签不是窗口,因此我创建了一个 drawtext 函数的挂钩,我可以获取绘制到屏幕上的文本。
但我无法验证当函数获取 hdc 时在屏幕上的哪个位置绘制文本,以及在上下文中绘制文本的位置。 我需要确定 hdc 在屏幕上的位置,并确保标签正确。
有办法吗? 托管非托管剂量对我来说无关紧要。
【问题讨论】:
我有一个正在测试的 VCL 应用程序,但没有源代码。 我需要验证在屏幕上的标签上绘制了哪些文本,但标签不是窗口,因此我创建了一个 drawtext 函数的挂钩,我可以获取绘制到屏幕上的文本。
但我无法验证当函数获取 hdc 时在屏幕上的哪个位置绘制文本,以及在上下文中绘制文本的位置。 我需要确定 hdc 在屏幕上的位置,并确保标签正确。
有办法吗? 托管非托管剂量对我来说无关紧要。
【问题讨论】:
您可以在 Delphi 中构建一个 DLL 并将该 DLL 注入目标进程。由于您很高兴挂钩 Win32 API,我想您不会有问题。
在该 DLL 中,您可以找到(使用 Win32 API)HWND,它是标签的“父级”。
使用该 HWND,您可以找到关联的 TWinControl。为此,您必须深入研究 VCL 源代码。
对于 Delphi 4(是的,我知道,它很旧),您必须构建一个 Atom 字符串,使用 GlobalFindAtom,然后使用 GetProp。结果是指向 TWinControl 的指针。
对于 Delphi7(也是旧的),您必须使用 RegisterWindowMessage 和一个由“ControlOfs”组成的字符串,后跟模块句柄和线程 ID。然后SendMessage 的LRESULT 是指向TWinControl 的指针。
抱歉,我不知道其他 Delphi 版本,但应该都可以在 VCL 源中找到。
一旦有了TWinControl 指针,您就可以将孩子枚举为TComponent,并获取他们的Name(因为它们出现在您没有的源代码中......),他们的@ 987654331@'s,等等,你明白了。
【讨论】:
我认为你需要这样做:
WindowFromDC 查找承载标签的窗口。如您所知,Delphi 标签是非窗口化的,控件实际上是在其父窗口上绘制的。如果父级是双缓冲的,这可能会失败。在这种情况下,您没有希望从设备上下文中获取窗口句柄,因为您所拥有的只是位图的设备上下文。SetWindowOrgEx 来安排设备上下文在标签左上角的逻辑坐标为 0,0。因此,您可以调用GetWindowOrgEx 来查找标签相对于父标签的位置。ClientToScreen 确定文本在屏幕上的绘制位置。由于设备上下文仅在拥有它们的进程中才有意义,因此您需要注入目标进程来调用它。
【讨论】: