2015-07-03 71 views
1

案例:初學者在MFC C++中,爲什麼設備上下文需要創建一箇舊的Font/Bitmap/etc指針,然後在最後使用selectObject()?

void CMainWindow::OnPaint() 
{ 
    CRect rect; 
    GetClientRect (&rect); 

    CPaintDC dc (this); 
    dc.SetViewportOrg (rect.Width()/2, rect.Height()/2); 
    dc.SetBkMode (TRANSPARENT); 

    for (int i=0; i<3600; i+=150) { 
     LOGFONT lf; 
     ::ZeroMemory (&lf, sizeof (lf)); 
     lf.lfHeight = 160; 
     lf.lfWeight = FW_BOLD; 
     lf.lfEscapement = i; 
     lf.lfOrientation = i; 
     ::lstrcpy (lf.lfFaceName, _T ("Arial")); 

     CFont font; 
     font.CreatePointFontIndirect (&lf); 

     CFont* pOldFont = dc.SelectObject (&font); 
     dc.TextOut (0, 0, CString (_T ("   Hello, MFC"))); 

     //WHY THIS LINE? 
     dc.SelectObject (pOldFont); 
    } 
} 

代碼打印「Hello,MFC」在原點周圍的圓(其移動到窗口的中心)。

Output

這是爲什麼的CFont指針創建,然後直流選擇它作爲字體?這只是一個好的編程習慣,還是這個應用程序真的需要它?

我在網上看到了類似的代碼,用Bitmaps和其他設備上下文對象做這件事。目的是什麼?

當我刪除代碼的最後一行時,沒有任何更改。先謝謝您的幫助。

回答

3

Device Context

的設備上下文是定義了一組圖形對象及其相關屬性,以及影響輸出的圖形模式的結構。 graphic objects包括用於畫線的畫筆,用於繪畫和填充的畫筆,用於複製或滾動畫面部分的位圖,用於定義可用顏色集合的調色板,用於裁剪和其他操作的區域以及用於繪畫的路徑和繪圖操作。

在任何時候,只有一個圖形對象被選入設備上下文中。由於系統在創建時將一組默認對象存儲到設備上下文中,因此當設備上下文被交還給系統進行清理時,應用程序必須保持該狀態。那是什麼

dc.SelectObject (pOldFont); 

負責。

此要求SelectObject下記載:

此函數返回指定類型的先前選擇的對象。應用程序應該總是在用新對象完成繪圖之後用原始默認對象替換新對象。


注:這是不相關的MFC,而是Windows的GDI。 MFC僅實現一個自動資源管理包裝器。國家管理仍然需要明確的代碼。

+0

我對你的解釋感到困惑。 MFC具有自動資源管理。你的意思是'dc.SelectObject(pOldFont)'仍然是必要的嗎? –

+0

@Barmak:你引用的代碼行執行** state **管理。這對MFC也是必需的。我指的是**資源**管理:您不必在'font'對象上調用'DeleteObject';這是爲你做的。 – IInspectable

+0

如果是這樣的話,我很麻煩。我認爲MFC的新版本不需要這個。我不恢復'oldfont'。我使用'GetGuiResources(GetCurrentProcess(),GR_GDIOBJECTS)'來監視GDI句柄,它仍然顯示零泄漏。 Taskmanager的「GDI對象」在恢復'oldfont'(Windows 8測試)時看起來相同或不相同。 早些時候,我瀏覽過'CDC :: SelectObject'和'CDC',我總結MFC自動恢復'oldfont'。但現在我又看了一遍,我不確定它在做什麼。無論如何,我將同時使用'SaveDC'和'RestoreDC'。 –

相關問題