在另一个窗口上绘制(无闪烁)?

3
我需要在一个窗口上画一些东西(这不是我的窗口 - 它是用户定义的,如果有影响的话)。
我已经通过使用GetDC获取设备上下文并正常绘制来成功地在窗口上绘制了图形,问题是我不知道何时在窗口上绘制 - 窗口不断重绘自己(例如游戏)。 我有一些想法,但到目前为止它们都不好或者没有实现。
- 使用计时器。这是最糟糕的想法,但现在我会尝试任何事情。显然,由于窗口不断重绘,它会闪烁。我考虑在我的绘图之前强制窗口重新绘制,但仍然不好。无法想出一个好的计时器实现... - 钩取WM_PAINT消息。使用SetWindowsHookEx WM_GETMESSAGE钩子,我可以使用一个事件,在其他窗口接收到它时接收WM_PAINT消息,但是WM_PAINT是在完成绘制之前发送的。我在MSDN上发现,除了WH_GETMESSAGE Windows Hook之外,您还可以使用WndProcRetHook,它在处理Windows消息之后被调用并接收包含消息信息的结构,但到目前为止没有运气 - 我无法让它工作... - 钩取绘图函数。我尝试过钩取绘画函数(或函数),例如ReleaseDC和/或EndPaint,这会使窗口无效,以便我可以进行最后一分钟的绘图。这次,我做得很好 - 但它仍然会有点闪烁,并且在某些窗口上钩取ReleaseDC会阻止窗口渲染 - 它甚至不会擦除背景。有时甚至整个进程都会崩溃。
所以我正在寻找一种在窗口显示在屏幕上之前最后绘制的好方法。我更喜欢避免使用SetWindowsHookEx(例如:外部DLL)完成的挂钩,但这也可以。谢谢。
2个回答

3

另一种方法是避免直接在窗口上绘制,而是创建一个透明的分层窗口,并将其保持位于主窗口之上。这样,您在窗口上的绘图不会干扰主窗口上的绘图,反之亦然。

您可能需要采取某些步骤,以便鼠标单击能够穿过您的窗口到达主窗口;例如,使用HTTRANSPARENT处理WM_NCHITTEST并使用WS_EX_TRANSPARENT样式。


这是我心中所想的一件事。问题在于图纸也是透明的...颜色会根据透明度混合,因此我添加了用户定义选项来控制窗口的背景颜色和透明度以获得最佳效果。我希望这样能够很好地工作。谢谢。 - Symbol
我不知道为什么直到现在我才想到,但迄今为止,当我可以简单地将TransparencyKey设置为BackgroundColor属性时,我一直使用Opacity属性,然后我的绘图将显示为无透明度,我的窗口将完全透明。 ;) - Symbol
是的,在这里使用颜色键方法可能是最好的选择。 - BrendanMcK
我同意@BrendanMcK的看法,他/她提出的解决方案更少侵入性。这里有一个VB.net项目的链接,它封装了透明度和点击穿透行为。希望能对你有所帮助。 - user1222021

2

在Windows系统下,窗口需要按需绘制,因此唯一的方法是使用SetWindowsHookEx()函数挂钩该窗口的WM_PAINT消息。

这是一个比较复杂的过程,需要将你的绘图代码放在一个DLL文件中(以便可以将该DLL加载到目标应用程序的地址空间)。

总的来说,除非你有非常充分的理由,否则通常不建议这样做。


谢谢你的回答。我有其他实现我想要的功能的方法,但这个是最好的...只要我能够以良好的方式实现它。;) - Symbol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接