?? 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 + -