在另一个窗口上绘图(没有闪烁?)

时间:2011-04-26 20:44:59

标签: c# c winapi graphics gdi+

我需要在窗口上绘制一些东西(这不是我的 - 如果重要的话,它是用户定义的。)

我已经设法通过使用GetDC获取设备上下文并正常绘制来绘制窗口,问题是我不知道何时绘制到窗口 - 窗口不断重绘(例如,一个游戏)。 我有一些想法,但到目前为止他们没有好或坏/没有实施。

  • 使用计时器。这是最糟糕的想法,但我现在会尝试任何事情。显然,由于窗口不断重绘,它会闪烁。我想在我的绘画之前强迫窗口重绘,但仍然没有好处。用计时器真的不能想到一个好的实现......
  • Hook WM_PAINT消息。使用SetWindowsHookEx WM_GETMESSAGE挂钩我可以使用一个事件,只要其他窗口收到它就接收WM_PAINT消息,但WM_PAINT在绘图完成之前发送。我在MSDN上发现,而不是WH_GETMESSAGE Windows Hook,您可以使用WndProcRetHook,在处理Windows消息之后称为,并收到包含消息信息的结构,但到目前为止还没有运气 - 我无法得到它工作...
  • 挂钩绘图功能。我已经尝试挂钩了ReleaseDC和/或EndPaint这样使窗口无效的绘画功能(或功能),所以我可以做最后一刻的绘图。这一次,我让它工作得很好 - 但它仍然闪烁一点,并在一些窗口挂钩ReleaseDC以某种方式阻止从窗口渲染 - 它甚至不会删除它的背景。有时甚至整个过程都会崩溃。

所以我正在寻找一个好的方法,最好在窗口上显示之前绘制窗口。我更喜欢避免使用SetWindowsHookEx(例如:外部DLL)完成钩子,但这样也可以。

感谢。

2 个答案:

答案 0 :(得分:3)

另一种方法可能是避免直接在窗口上绘画,而是创建一个透明的分层窗口,您可以将其放在主窗口的顶部。这样,窗口上的绘图不会干扰主窗口上的绘图,反之亦然。

您可能需要采取某些步骤,鼠标点击将通过您的窗口进入主窗口;例如。使用HTTRANSPARENT处理WM_NCHITTEST并使用WS_EX_TRANSPARENT样式。

答案 1 :(得分:2)

因为在Windows下,窗口需要按需绘制,所以唯一的方法是使用SetWindowsHookEx()挂钩该窗口的WM_PAINT窗口。

这是一个非常重要的过程,需要您的绘图代码驻留在DLL中(因此DLL可以加载到目标应用程序的地址空间中)。

一般来说,除非你有充分的理由这样做,否则这不是一个好主意。