为什么TForm.Handle是一个吸气剂而不是一个领域?

Kro*_*ica 1 delphi vcl handle tform

我最近调试了一个复杂的bug.这是由访问不存在的Form.Handle(带状指针)引起的.这个bug以相当意想不到的方式向我揭示 - 访问Forms会Handle导致调整大小和重新绘制.

我希望Form.Handle通过垃圾指针访问只会返回一些垃圾THandle.期望Handle在表单创建时创建一次并保持相同直到Form被销毁.

这个问题

为什么会这样,这TForm.Handle不是一个在表单创建时初始化并通过访问的字段

property Handle: Integer read FHandle;
Run Code Online (Sandbox Code Playgroud)

,但是是一个吸气剂

property Handle: Integer read GetHandle;
Run Code Online (Sandbox Code Playgroud)

CreateWnd在第一次访问时创建Handle甚至Window()?

Rob*_*edy 9

即使底层操作系统窗口没有,表单对象也可以存在.在这些时间,字段将为0,这对需要有效窗口句柄的代码没有帮助.为了确保每次需要时都能获得有效的句柄,您需要在引用该字段之前进行调用.作为拥有吸气剂的酒店,酒店可以自动为您服务,方便客人使用酒店.HandleHandleNeededHandleHandleNeededHandle

  • 我说它比@LURD更强烈.规则是你永远不会在主线程之外使用VCL窗口句柄,因为它们需要重新创建.所以你使用的窗口句柄不是,例如来自`AllocateHWnd`的窗口句柄. (4认同)
  • @Kromster,如果你想从一个线程访问表单句柄以发送/发布消息,那么在主线程中分配一个带有'AllocateHwnd()`的句柄可能是个更好的主意,让线程发布消息这把柄.从那里消息可以转发到VCL. (3认同)
  • 是的.在这些情况下,首先调用`HandleAllocated`来猜测`Handle`的后续访问是否有效.你不能*知道*,因为主线程可能会在检查时间和使用时间之间破坏窗口.最终,关于在其他线程中做UI的事情.如果另一个线程*需要*知道一个窗口句柄,让主线程提供另一个线程的句柄(而不是另一个线程获取句柄本身),并使主线程负责确保提供的句柄只要另一个线程需要它,它就会保持有效. (2认同)