【发布时间】:2012-05-12 11:52:14
【问题描述】:
我正在尝试 subclass 和 WinApi edit control 并覆盖绘制方法。到目前为止,我正在使用 SetWindowLong 函数和 GWL_WNDPROC 标志来覆盖原始窗口过程,然后我收到 WM_PAINT 消息并使用我自己的 Paint 逻辑,这很好用,但我我想知道是否可以创建一个 shadow TEdit 组件并将 Winapi EDIT 控件的原始句柄传递给 Delphi TEdit 组件,这样我就可以使用影子 TEdit 来获取和设置编辑控制。这可能吗?
更新
按照 Remy 关于使用 WindowHandle 属性的建议,我以这段代码结束,但不起作用(设置编辑控件的颜色无效)。
type
TWinControlCracker= class(TWinControl);
Var
ShadowEdit : TEdit;
newWndProc : Pointer;
EditHandle : NativeInt;
begin
EditHandle:=$00320530;//this is the handle to the EDIT control
ShadowEdit:=TEdit.Create(nil);
TWinControlCracker(ShadowEdit).WindowHandle:=EditHandle;
newWndProc := MakeObjectInstance(ShadowEdit.WindowProc);
SetWindowLong(EditHandle, GWL_WNDPROC, NativeInt(newWndProc));
ShadowEdit.Color:=clLime;
ShadowEdit.Refresh;
end;
【问题讨论】:
-
什么是影子组件?这是德尔福的概念吗?
-
“影子”是指创建一个“假”TEdit VCL 控件。
-
好的。好吧,在那种情况下,我不知道 WinAPI 中有任何功能允许编辑可执行文件的资源文件(如果存在的话)。
-
使用“影子”
TEdit设置编辑HWND的Color将不起作用,因为它需要编辑控件的父窗口的合作。当需要绘制 Edit 控件时,它会向其父窗口发送WM_CTLCOLOREDIT消息以获取绘制期间使用的HBRUSH句柄。您的TEdit影子将永远不会收到该消息,除非您将父窗口子类化并手动转发相应的消息。对于原生 VCL 窗口,VCL 会为您处理所有重定向,因此TEdit(或一般的任何TControl后代)可以处理自己的消息。 -
GWL_WNDPROC 不能跨进程工作。