MFC的控件简直丑陋无比,因此往往会使用贴图的方式进行。于是自己也尝试开发一套UI控件。那么在把控件运用到APP的时候发现有刷新的问题。
一.WM_PAINT消息问题
一般情况我是认为通过重载PreTranslateMessage可以截获所有的WM_XX消息,但是我错。
通过调试我发现,
1.在 xxxx::OnInitDialog() 调用之后,会先触发xxxxx::OnEraseBkgnd(CDC* pDC)函数 再触发 xxxx::OnPaint() 函数,并且在PreTranslateMessage里面是无法截取到WM_PAINT消息的;
2.当有其他窗口覆盖后,就能够在PreTranslateMessage中截获到WM_PAINT消息;
二、WM_ERASEBKGND消息问题
正如我所说,以为PreTranslateMessage可以截获到所有消息,其实不然WM_ERASEBKGND消息无法在PreTranslateMessage获取到,只能通过添加函数消息绑定的方式,来得要刷新背景的请求,即添加了XXXX:OnEraseBkgnd(CDC* pDC) 函数。
为什么要处理这个刷新背景呢,主要是通过在XXXX:OnEraseBkgnd(CDC* pDC) 函数,中直接返回TRUE值,让系统不刷新背景,从而保证使用自己的绘制背景,另一方面也增加刷新速度。试想一下,假设在很短的时间内进行全屏刷新,那得多慢呀!!!
三、WM_TIMER问题
由于自己使用的GetDC的方式进行,所以接收到在PreTranslateMessage中收到WM_PAINT消息的,没有调用
CPaintDC dc(this);
或者
PAINTSTRUCT ps;
BeginPaint(m_hMainWnd,&ps);
EndPaint(m_hMainWnd,&ps);
从而促使系统认为一直处于窗口无效需要刷新,导致系统一直在狂发送WM_PAINT消息给窗口,进而导致WM_TIMER,无法触发。(WM_PAINT与WM_TIMER在系统中都属于低优先级的消息)。所以,很容易误认为在PreTranslateMessage函数中也是无法获取到WM_TIMER消息的。