【问题标题】:How subclass a WinApi Edit control using a delphi VCL component?如何使用 delphi VCL 组件子类化 WinApi Edit 控件?
【发布时间】:2012-05-12 11:52:14
【问题描述】:

我正在尝试 subclassWinApi 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 设置编辑HWNDColor 将不起作用,因为它需要编辑控件的父窗口的合作。当需要绘制 Edit 控件时,它会向其父窗口发送 WM_CTLCOLOREDIT 消息以获取绘制期间使用的 HBRUSH 句柄。您的TEdit 影子将永远不会收到该消息,除非您将父窗口子类化并手动转发相应的消息。对于原生 VCL 窗口,VCL 会为您处理所有重定向,因此 TEdit(或一般的任何 TControl 后代)可以处理自己的消息。
  • GWL_WNDPROC 不能跨进程工作。

标签: delphi winapi


【解决方案1】:

TWinControlTEdit 派生自)有一个公共 WindowHandle 属性,您可以将非 VCL HWND 分配给该属性。只需确保在销毁 TEdit 或执行任何可能导致其在内部调用其 RecreateWnd() 方法之前将属性设置回 0,否则 WinAPI 控件将被销毁。并且不要使用任何需要 TEdit.Parent 属性才有意义的东西。

【讨论】:

  • 当他说“一个外部应用程序”时,我们怎么能确定他的意思。
  • 我尝试使用您的建议,但不起作用,您能给我看一个基本的代码示例或查看我更新的问题吗?
  • 您尝试对Color 属性执行的操作将不起作用。请参阅我对您编辑的问题的其他评论。除非您将 Edit 控件的父窗口也子类化,否则任何涉及父窗口接收消息的功能都将不起作用。
猜你喜欢
  • 2012-04-26
  • 1970-01-01
  • 2013-03-13
  • 2023-03-14
  • 2012-06-14
  • 1970-01-01
  • 2013-01-24
  • 2011-05-23
  • 2018-12-25
相关资源
最近更新 更多