📄 sy0305.htm
字号:
<html>
<HEAD>
<TITLE>Visual C++与计算机接口</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=gb2312" >
</HEAD>
<body>
<font color="#0000FF">内存DC和内存位图</font>
<p>
(一)实验目的:<BR>
学会使用内存DC解决重画问题<BR><BR>
(二)实验内容:<BR><BR>
当Windows系统需要重画窗口时,会向窗口发送一条WM_PAINT消息,应用程序需要在WM_PAINT消息响应函数(或View类中的OnDraw)中重画整个窗口(即重新显示窗口中的信息)。<BR>
可以把所有绘图的工作放到OnDraw、OnPaint等函数中作,但这样作可能会出现三个缺点:速度慢、屏幕闪烁、不方便。<BR>
所以,对于需要较复杂绘图的程序,一般方法是在内存中保存窗口内容的一个拷贝(内存DC)来实现重画。每次收到WM_PAINT消息时,将内存DC的内容复制到屏幕上。<BR><BR>
1、重建一个工程,在View类的头文件中向View类添加成员变量:指向内存DC的指针和指向内存位图的指针<BR>
CDC* m_pMemDC;<BR>
CBitmap* m_pBitmap;<BR>
2、在View类的构造函数中添加代码创建CDC和CBitmap对象<BR>
m_pMemDC=new CDC();<BR>
m_pBitmap=new CBitmap();<BR>
3、在View类的析构函数中添加代码销毁CDC和CBitmap对象<BR>
delete m_pMemDC;<BR>
delete m_pBitmap;<BR>
4、用Class Wizard为View类添加一个WM_CREATE消息处理函数OnCreate(LPCREATESTRUCT lpCreateStruct),在处理函数中添加代码创建内存DC和位图<BR>
//得到屏幕尺寸<BR>
int maxX=GetSystemMetrics(SM_CXSCREEN);<BR>
int maxY=GetSystemMetrics(SM_CYSCREEN);<BR>
//创建内存DC和位图<BR>
CDC* pDC=GetDC();<BR>
m_pMemDC->CreateCompatibleDC(pDC);<BR>
m_pBitmap->CreateCompatibleBitmap(pDC,maxX,maxY);<BR>
m_pMemDC->SelectObject(m_pBitmap);<BR>
ReleaseDC(pDC);<BR>
//初始化内存DC为全白<BR>
CBrush brush;<BR>
brush.CreateStockObject(WHITE_BRUSH);<BR>
CBrush* poldbrush=m_pMemDC->SelectObject(&brush);<BR>
m_pMemDC->PatBlt(0,0,maxX,maxY,PATCOPY);<BR>
m_pMemDC->SelectObject(poldbrush);<BR>
5、在OnDraw中添加重画代码<BR>
CRect rect;<BR>
GetClientRect(rect);<BR>
pDC->BitBlt(0,0,rect.Width(),rect.Height(),m_pMemDC,0,0,SRCCOPY);<BR>
6、用Class Wizard为View类添加一个WM_LBUTTONDOWN消息处理函数,用于响应鼠标左键单击消息。<BR>
7、在该鼠标消息处理函数中,添加绘图代码<BR>
m_pMemDC->TextOut(point.x,point.y,"Test");<BR>
Invalidate(FALSE);<BR>
8、编译运行程序,在鼠标左键点击的地方都会显示出“Test”。最小化窗口,再恢复窗口,可以发现前面显示的“Test”仍然保留。<BR><BR>
说明:<BR>
Invalidate函数刷新整个窗口,如果每次绘图修改的区域较小,可以使用InvalidateRect函数代替Invalidate函数以加快显示速度。例如鼠标消息处理函数中的绘图代码可以改为如下代码:<BR>
CString str="Test";<BR>
CRect rect(point.x,point.y,point.x,point.y);<BR>
m_pMemDC->DrawText(str,&rect,DT_CALCRECT|DT_LEFT); //得到要绘制的文本在屏幕上的尺寸<BR>
m_pMemDC->DrawText(str,&rect,DT_LEFT);<BR>
InvalidateRect(rect,FALSE); //只刷新需要绘制文本的区域<BR>
如果绘图次数很频繁,位图很大,用这种方法可以明显改善绘图性能。<BR>
Invalidate(TRUE)先清除DC再重画,Invalidate(FALSE)直接在原图上画,性能更好,两者可以视情况选用。<BR>
<p></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -