作者:朱金燦
來源:http://blog.csdn.net/clever101/
下面是對話方塊的OnPaint函數(就是WM_PAINT訊息的響應函數)的兩種寫法。
寫法一:
view plaincopy to clipboardprint?
void CMyDlg::OnPaint()
{
CDC *pDC = GetDC();
// 我的繪製代碼
MyDrawFunction(pDC);
ReleaseDC(pDC);
}
void CMyDlg::OnPaint()
{
CDC *pDC = GetDC();
// 我的繪製代碼
MyDrawFunction(pDC);
ReleaseDC(pDC);
}
寫法二:
view plaincopy to clipboardprint?
void CMyDlg::OnPaint()
{
CPaintDC dc(this);
// 我的繪製代碼
MyDrawFunction(&dc);
}
void CMyDlg::OnPaint()
{
CPaintDC dc(this);
// 我的繪製代碼
MyDrawFunction(&dc);
}
開始以為這兩種寫法並無區別。今天偶然發現了這個區別。這個區別大家也可測試一下。建一個基於對話方塊的工程。然後添加下面繪圖代碼:
view plaincopy to clipboardprint?
void CColorPaletteDlg::DrawLine(CDC *pDC)
{
assert(NULL!=pDC);
Gdiplus::Pen red (Color(255, 255, 0, 0),2.0f);
Gdiplus::Graphics graphics(pDC->GetSafeHdc());
graphics.DrawLine(&red, 0, 0, 100,100);
}
void CColorPaletteDlg::DrawLine(CDC *pDC)
{
assert(NULL!=pDC);
Gdiplus::Pen red (Color(255, 255, 0, 0),2.0f);
Gdiplus::Graphics graphics(pDC->GetSafeHdc());
graphics.DrawLine(&red, 0, 0, 100,100);
}
然後把它放在兩個不同的OnPaint函數裡調用,如下:
view plaincopy to clipboardprint?
void CColorPaletteDlg::OnPaint()
{
CDC *pDC = GetDC();
DrawLine(pDC);
ReleaseDC(pDC);
}
void CColorPaletteDlg::OnPaint()
{
CDC *pDC = GetDC();
DrawLine(pDC);
ReleaseDC(pDC);
}
或是:
view plaincopy to clipboardprint?
void CColorPaletteDlg::OnPaint()
{
CPaintDC dc(this);
DrawLine(&dc);
}
void CColorPaletteDlg::OnPaint()
{
CPaintDC dc(this);
DrawLine(&dc);
}
一開始啟動程式二者並無區別,但是在切換到其它程式視窗,比如開啟一個txt檔案再開啟這個程式,你就會發現區別,寫法一的效果會變為如下:
寫法二的效果如下:
注意寫法二能正常顯示下面兩個按鈕。
讓我們看看MSDN對CPaintDC是如何解釋的?
CPaintDC objects encapsulate the common idiom of Windows, calling the BeginPaint function, then drawing in the device context, then calling the EndPaint function. The CPaintDC constructor calls BeginPaint for you, and the destructor calls EndPaint. The simplified process is to create the CDC object, draw, and destroy the CDC object. In the framework, much of even this process is automated. In particular, your OnDraw function is passed a CPaintDC already prepared (via OnPrepareDC), and you simply draw into it. It is destroyed by the framework and the underlying device context is released to Windows upon return from the call to your OnDraw function.
CClientDC objects encapsulate working with a device context that represents only the client area of a window. The CClientDC constructor calls the GetDC function, and the destructor calls the ReleaseDC function.CWindowDC objects encapsulate a device context that represents the whole window, including its frame.
大致的翻譯是:CPaintDC對象封裝了Windows的,調用BeginPaint函數,然後在裝置上下文上繪圖,然後調用EndPaint函數的常見用法。該CPaintDC建構函式調用BeginPaint函數,在解構函式調用EndPaint。簡化的處理過程就是創造CDC對象,繪製,並摧毀了CDC對象。在架構內,即使是這個過程的大部分是自動的。特別是,你的OnDraw函數傳遞一個CPaintDC已經準備通過OnPrepareDC(),你通過它進行簡單的繪圖。它是由架構銷毀和從調用您的OnDraw函數返回到基本裝置上下文被釋放後回Windows。(這一句的翻譯有問題)
CClientDC對象封裝與一個裝置上下文,表示只有一個視窗的客戶區。該CClientDC建構函式調用GetDC的功能,解構函式調用ReleaseDC function.CWindowDC對象封裝了表示整個視窗(包括它的架構)的裝置上下文。
也就是說,第二種寫法比第一種寫法做的工作要多。在此多謝VC知識庫的benben、bl、sjdev等諸位大俠。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/clever101/archive/2010/07/28/5772516.aspx