MFC GUI自定义控件:如何绘制光标更新以响应鼠标移动?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC GUI自定义控件:如何绘制光标更新以响应鼠标移动?相关的知识,希望对你有一定的参考价值。
我有一个来自CButton
的自定义Windows控件(不知道为什么选择了这个 - 这是17岁的代码;没有按钮功能的外观)。
它的DrawItem( LPDRAWITEMSTRUCT pdis )
方法被CButton::OnChildNotify
称为响应WM_DRAWITEM
。它用DC CDC::FromHandle( pdis->hDC )
呈现它的场景。
鼠标事件方法OnMouseMove()
计算新的光标位置并调用RedrawWindow( NULL, NULL, RDW_INVALIDATE )
。鼠标后面的光标正好出现在新的鼠标位置。它工作正常,但速度很慢。实际上,只需要重绘前一个和新的光标单元(如果是这样),但是图形更新开始滞后,因为整个场景被渲染很多次。
我认为在我的OnMouseMove()
方法中,而不是重新绘制整个场景,只能绘制有问题的细胞。它已经具有单元格的精确X和Y坐标以及指向其数据的指针。我认为CPaintDC(this)
会提供允许这个的DC
,但它不会画画。 (也不会崩溃,这是一种难得的快乐。)
我的朦胧回忆是,这样做的“最佳”方法是使两个单元格的区域无效,并且DrawItem()
方法最终将被告知这些区域无效,而不是完全重新绘制它可能只是从坐标它们是哪个单元格(不是简单的操作btw)并重新绘制它们,这样不仅可以简化这个光标问题,而且还可以确保只有少数单元格被绘制,部分遮挡的控件部分显示出来。但时间压力不允许,用例似乎没有要求优化。
所以问题是:是否有一些很好的方法让OnMouseMove()
立即重新渲染一个控件,如果有的话,DC
是什么? (例如,我可以通过DC
缓存我在DrawItem()
收到的FromHandle()?
现在我唯一的想法就是让一个对象成员指向要重绘的单个单元格,使用此RDW_UPDATENOW标志调用RedrawWindow(),并使用DrawItem(),如果设置了该标志,则只执行该项目。这将导致DrawItem()得到一个DC,可能会以它一直以来的方式工作。看起来像真正的黑客,有更好的方法吗?
在Windows应用程序中,习惯上执行所有呈现以响应WM_PAINT
(或WM_NCPAINT
)消息。需要触发重绘的代码通过调用InvalidateRect
(和朋友)将窗口的客户区域的一部分或全部标记为脏。系统针对此方法进行了优化,将多个请求合并到一个更新区域,然后在没有更重要的工作要做(如处理输入)时发出WM_PAINT
消息。
这可靠地工作,并且通常比在几个地方传播渲染更容易实现。但是,偏离此并完全合法,并在代码中的任何位置执行渲染。虽然WM_PAINT
消息仍然可以随时到达,但是需要让带外渲染产生与WM_PAINT
处理程序相同的视觉效果,以防止视觉伪像。
所有渲染都经历了一个名为device context(DC)的抽象。当在MFC应用程序中处理WM_PAINT
消息时,可以通过构造CPaintDC
实例来获得合适的DC。在任何其他地方渲染时,你不能使用CPaintDC
,但需要使用CClientDC
(或CWindowDC
,以渲染非客户区域)。通常,渲染代码不需要知道它渲染到哪种类型的DC,并且通常可以在不改变的情况下重复使用。
以上是关于MFC GUI自定义控件:如何绘制光标更新以响应鼠标移动?的主要内容,如果未能解决你的问题,请参考以下文章