void Invalidate( BOOL bErase = TRUE );
该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。
它和 UpdateWindow( )区别在于:
UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。
当需要更新窗口的时候可以使用Invalidate()来重绘整个窗口,但是重绘整个窗口计算量是很大的,这会导致屏幕出现闪烁,为了防止这种情况,可以用InvalidateRect()来替代Invalidate(),毕竟计算一个矩形里面要绘制的内容计算量会要小很多。
函数原型:
BOOL InvalidateRect(
HWND hWnd, //需要重绘的窗口的句柄
LPCRECT lpRect, //要重绘的矩形区域
BOOL bErase = TRUE //重绘矩形的方式。
);
InvalidateRect()的第一个参数是需要重绘的窗口的句柄,但是似乎在CView类及它的派生类中可以不要填写,第二个参数是一个CRect矩形类,矩形的坐标必须是逻辑坐标。第三个参数是重绘矩形的方式,为FALSE是重绘传入的矩形,为TRUE的时候似乎是重绘整个窗口。
关于逻辑坐标(LP - Logical Point)和设备坐标(DP – Device Point)
对于屏幕,逻辑坐标的原点在最左下角,让整个屏幕在坐标轴的第一象限。设备坐标是在输出设备上定点绘制图形对象是用的,它采用笛卡尔坐标系,原点在屏幕的最左上角,x轴的值自左向右增加,y轴自右向左增加,单位为像素(设备单位)。另外设备坐标是绝对的,逻辑坐标是相对的,可以根据窗口的位置变化来变化的,引用逻辑坐标,就是为了更加直观的来表示屏幕的坐标。还有一种物理坐标,实际上就是设备坐标。
关于逻辑坐标和设备坐标的转换
逻辑坐标转换成设备坐标的函数:
函数原型:
BOOL LptoDP(
LPPOINT lpPoints, 指向POINT结构数组的指针,每一个POINT结构中的X坐标和Y坐标将被转换
int nCount, //指定数组中点的数目,不写则为1
HDC hdc //指向设备环境的句柄。我在写程序的时候,似乎没有写哦,不过也通过了,会不会又是因为写在了CView类里面的原因呢?
);
如果函数调用成功,返回值为非零值。否则为零。
使用:
CPoint pt(0, 0);
pDC->LPtoDP(&pt);
逻辑坐标转换成设备坐标的函数:
函数原型:
BOOL DptoLP(
HDC hdc, //指向设备环境的句柄。还是没有写过……-_-!!!...
LPPOINT lpPoints, //指向POINT结构数组的指针,每个POINT结构中的X和Y坐标将被转换
int nCount, //规定数组中点的数目,不写则为1
);
如果函数调用成功,返回值为非零值。否则为零。
使用:
CPoint pt(0, 0);
pDC->DPtoLP(&pt);
注意,里面接的参数不是矩形,而是CPoint类。
———————————————————————————————————————————————
当客户区需要重绘时,调用CWnd的Invalidate或InvalidateRect成员函数来触发Windows的WM_PAINT消息,从而引起对OnDraw函数的调用。下面将详述 InvalidateRect。