Delphi组件有CreateWnd和CreateWindowHandle(DestroyWnd和DestroyWindowHandle).它们都打算被后代覆盖,对吧?除了底层的VCL实现之外,不打算调用它?
它们之间有什么区别; 什么时候应该被覆盖?
背景:我正在使用OmniThreadLibrary在后台加载批处理模式ADO存储过程.我打开SP之后通过交换连接做了一些略显狡猾的事情,但这看起来非常可靠.我正在使用PostMessage将消息发送回调用表单,这在我的测试应用程序中有效.Primoz的comms频道为我工作,我正在使用它们进行线程间通信,但对于我们的主应用程序,我试图通过使用标准的PostMessage调用来避免这种依赖,就像我们在app中的其他地方一样.
问题:不幸的是,当我把它放到我们的主应用程序中时,PostMessage调用线程开始失败1400:无效的窗口句柄.
我已经自由地添加了额外的PostMessage调用和日志代码来尝试找到问题,但我现在已经没有想法了.代码是样板:
const WM_PW_ADLQUEUEEMPTY = WM_USER + 11;
...
if PostMessage (OwnerHandle, WM_PW_ADLPROGRESS, QueueID, 10) then
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') OK for Queue ' + IntToStr (QueueID))
else
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') failed for Queue ' + IntToStr (QueueID));
Run Code Online (Sandbox Code Playgroud)
但是一系列电话的日志对我来说并不是很有启发性.请注意,时间之后的四个十六进制数字是来自GetCurrentThreadID的线程ID.
15:41:53.221 1614 TpwAsyncDataLoader.RunQueue WM_PW_ADLPROGRESS send to 00A5110C (IsWindow True) OK for Queue -6
15:41:53.265 13B4 TADLQueue.Run WM_PW_ADLPROGRESS …Run Code Online (Sandbox Code Playgroud) 在运行时应用新样式后,我的应用程序的MainForm创建一个新的窗口句柄 - 有没有办法停止此操作或重新分配句柄,因为我得到了一吨以下错误:
'系统错误.代码:1400.窗口句柄无效'
有没有办法操纵强制分配新句柄的过程?
我解决了这个问题:
我的主要表单创建了一个从未显示的看不见的"帮助"表单,但它确实有可视组件 - 它在尝试重绘这些可视组件时抛出了句柄错误,所以我用对象替换了相关组件(注意我最初没有写这段代码).
如您所知,窗口控件(包括表单)的窗口句柄被视为易失性.也就是说,设置一些属性可能会导致控制以破坏其窗口句柄,然后重新创建(有一堆这种技术的实例,搜索StdCtrls对RecreateWnd).
因此,当我需要在创建后注册我的HWND OS并在销毁之前取消注册它之后我应该覆盖相应的方法对.简要介绍Controls并Forms给了我3对,所有这些都是虚拟的:
还有对吗?我应该覆盖哪一对表格?哪一对用于一般窗口控制?