我想使经由SDL_CreateWindowFrom函数包装了一个SDL渲染表面的自定义VCL控制。 SDL_CreateWindowFrom采用现有的HWND手柄并提出一种高性能呈现上下文(它有几个可用的后端,包括DirectX和OpenGL)到其上。

在帮助文件中说:“不要指组件的创建或流期间Handle属性。”但它没有说为什么。它说,你第一次尝试访问Handle属性,它会调用HandleNeeded以确保有效的句柄存在。

所以,我有两个问题。 1:什么是为什么你不应该组件创建过程中引用的Handle属性的原因吗? 2.如果控制整个点是包装,需要进行初始化的HWND渲染表面,当是安全的执行(理想情况下)应该是创建/流期间发生初始化?

有帮助吗?

解决方案

在它的核心,它是一个高性能的事情。还有其他潜在的“坏”一点,可以在流过程中发生的,以及因为副作用。事情是在“中期建设”和所有正常预期是有可能不是。

当你提到“处理”属性,这将启动手柄创建过程。这是因为读书手柄实际调用GetHandle。在流过程中过早地做到这一点,你可能最终与充其量,慢流性能,在糟糕的是,部分配置的“手柄”。

如果您需要从属性setter中正确引用的手柄,你应该检查一下手柄已经通过检查HandleAllocated创建的,然后才是你引用它。如果你需要做一些标志变化为手柄就像调用SetWindowLong函数()或东西,那么你应该“缓存”的组件实例状态,然后覆盖CreateWnd方法,在这一点上应用这些设置。另一种选择是推迟所有手柄访问流传输的同时(如果csLoading中的ComponentState然后),直到加载虚拟方法被调用。

最后,你需要知道在您的手柄可能需要得到重建的病例。如果周围的形式或父组件的手柄经过一个重新创建过程可能发生这种情况。直到最近的Windows版本中,改变一些窗口标志的唯一办法是消灭手柄,在通过CreateWindowEx()调用新的标志重新创建。有许多组件是怎么做的。你知道,如果你在一个重新创建的情况是通过检查(在了ControlState- csRecreating)。

那么直接回答你的问题,最好的地方是覆盖CreateWnd方法和做你的工作在那里。手柄被创建时CreateWnd方法才会被调用。正确设计的组件应得到只有一个呼叫到CreateWnd方法是将要示出右之前。

其他提示

要回答你的第二个问题:假设你的控制是一个的 TCustomControl 的你应该覆盖的 CreateWindowHandle()的。这样做,所有的初始化是正确重复每一个新的窗口句柄的控件创建时间的益处。这允许更改不能设置一些窗口样式标志或不重新创建的窗口重置。它也允许通过释放手柄被不需要的时候,后来重新创建它以节约资源。

参见这个问题什么最差CreateWnd方法间 - 和-createwindowhandle 和更详细的答案做什么,当...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top