UpdateWindow函数通过发送一个WM_PAINT消息来刷新窗口,UpdateWindow将WM_PAINT消息直接发送给了窗口过程函数进行处理,而没有放到消息队列里。
MFC消息映射机制的具体实现方法是:在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,即消息映射表。在消息映射表中,消息与对应的消息处理函数指针是成对出现的。某个类能处理的所有消息及其对应的消息处理函数的地址都列在这个类所对应的静态表中。当有消息需要处理时,程序只要搜索该消息静态表,查看表中是否含有该消息,就可知道该类能否处理此消息。如果能处理该消息,则同样依照静态表能很容易找到并调用对应的消息处理函数。
MFC在后台维护了一个窗口句柄与对应的C++对象指针的对照表。当收到某一消息时,消息的第一个参数就指明了该消息与哪个窗口句柄相关,通过对照表,就可以找到与之相关的C++对象指针。然后把这个指针传递给应用程序框架窗口类的基类,后者会调用一个名为WindowProc的函数。
_T宏
Windows 98及以前的版本使用8位的ANSI字符集,它类似于ASCII字符集。Windows NT使用16位的Unicode字符集,它是ANSI字符集的一个超集。Unicode包含了各种各样来自非US字母表的字符。
使用ANSI字符编译的程序可以在Windows NT上运行,但Unicode程序运行起来要稍微快点,因为Windows NT不需要在每个字符上执行ANSI到Unicode的转换。Unicode应用程序不能在Windows 98上运行。
_T("Hello"):如果定义了预处理_UNICODE,编译器将使用Unicode字符。如果没有定义则使用ANSI字符。使用_T宏修饰字符串常量同时还需要做以下工作:
(1)将字符声明为TCHAR而不是char。
(2)使用TCHAR*来声明TCHAR字符串指针或者更佳的LPTSTR(指向TCHAR字符串的指针)和LPCTSTR(指向const TCHAR字符串的指针)。
如果只是用指定的画刷填充一块区域,并不需要把画刷选入设备描述表。设备描述表中存在一个默认的白色画刷。
创建CBitmap对象时,仅调用其构造函数并不能得到一个有用的位图对象,还需要调用一个初始化函数来初始化这个位图对象,如LoadBitmap、CreateBitmap等。
void CTESTADlg::OnLButtonDown(UINT nFlags, CPoint point) { CBitmap bitmap; bitmap.LoadBitmapW(IDB_BITMAP1); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(CPoint(0, 0), point), &brush); CDialogEx::OnLButtonDown(nFlags, point); }
VC++为我们提供的位图编辑器只能编辑256色或更少颜色的位图,超过256色的位图就不能被加载了,但这幅位图在程序中是能正常使用的。
位图的显示
一种显示位图的方法如下:
CreateCompatibleDC函数将创建一个内存设备上下文,与参数pDC所指定的DC兼容。内存设备上下文实际上是一个内存块,表示一个显示的表面。如果想把图像复制到实际的DC中,可以先用其兼容的内存设备上下文在内存中准备这些图像,然后再将这些数据复制到实际DC中。
窗口的绘制包含两个步骤:擦除窗口背景,然后对窗口重新进行绘制。擦除窗口背景时,程序会发送一个WM_ERASEBKGND消息。
BitBlt函数是将源设备上下文中的位图复制到目标设备上下文中。调用BitBlt复制位图后,又调用了视类的基类的OnEraseBkgnd函数,该函数的调用把窗口背景擦除了,所以会看到我们设置的位图一闪就消失了。
StretchBlt函数可以实现位图的拉伸或压缩,以适合目的矩形区域的尺寸。
OnDraw中显示位图也可以,但窗口会有闪烁现象,这是因为当窗口尺寸发生变化时,会引起窗口重绘操作,它会首先擦除背景,然后再重新贴上位图。
1 BOOL CBitView::OnEraseBkgnd(CDC* pDC) 2 { 3 CBitmap bitmap; 4 bitmap.LoadBitmapW(IDB_BITMAP2); 5 BITMAP bmp; 6 bitmap.GetBitmap(&bmp); 7 8 CDC dcCompatible; 9 dcCompatible.CreateCompatibleDC(pDC); 10 11 dcCompatible.SelectObject(&bitmap); 12 13 CRect rect; 14 GetClientRect(rect); 15 //pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY); 16 pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY); 17 //return CView::OnEraseBkgnd(pDC); 18 return TRUE; 19 }