文章目錄
- CWnd::OnCtlColor
- CWnd::OnPaint
- CWnd::OnNcPaint
- CWnd::OnDrawItem
- CWnd::OnEraseBkgnd
- CWnd::InvalidateRect
- CView::OnDraw
參考:https://learn.microsoft.com/
CWnd::OnCtlColor
即將繪制子控件時,框架會調用此成員函數。
afx_msg HBRUSH OnCtlColor(CDC* pDC,CWnd* pWnd,UINT nCtlColor);
參數
pDC
包含指向子窗口的顯示上下文的指針。 可能是暫時性指針。
pWnd
包含指向請求顏色的控件的指針。 可能是暫時性指針。
nCtlColor
包含以下用于指定控件類型的值之一:
CTLCOLOR_BTN 按鈕控件
CTLCOLOR_DLG 對話框
CTLCOLOR_EDIT 編輯控件
CTLCOLOR_LISTBOX 列表框控件
CTLCOLOR_MSGBOX 消息框
CTLCOLOR_SCROLLBAR 滾動條控件
CTLCOLOR_STATIC 靜態控件
返回值
OnCtlColor 必須返回用于繪制控件背景的畫筆的句柄。
注解
大多數控件將此消息發送到其父級(通常是一個對話框),以準備 pDC 來使用正確的顏色繪制控件。
若要更改文本顏色,請使用所需的紅綠藍 (RGB) 值調用 SetTextColor 成員函數。
若要更改單行編輯控件的背景色,請在 CTLCOLOR_EDIT 和 CTLCOLOR_MSGBOX 消息代碼中設置畫筆句柄,并調用 CDC::SetBkColor 函數來響應 CTLCOLOR_EDIT 代碼。
不會對下拉組合框的列表框調用 OnCtlColor,因為下拉列表框實際上是組合框的子級,而不是窗口的子級。 若要更改下拉列表框的顏色,請在 nCtlColor 參數中創建一個 CComboBox,并在其中包含一個用于檢查 CTLCOLOR_LISTBOX 的 OnCtlColor 重寫。 在此處理程序中,必須使用 SetBkColor 成員函數來設置文本的背景色。
備注
框架調用此成員函數來支持你的應用程序處理 Windows 消息。 傳遞到函數的參數反映了收到消息時框架所接收的參數。 如果調用此函數的基類實現,該實現將使用最初隨消息傳遞的參數,而不是你提供給該函數的參數。 若要將以下方法添加到對話框類,請使用 Visual Studio 屬性窗格添加 WM_CTLCOLOR 的消息處理程序。 或者,可以手動將 ON_WM_CTLCOLOR() 條目添加到消息映射。
示例
// This OnCtlColor handler will change the color of a static control
// with the ID of IDC_MYSTATIC. The code assumes that the CPenWidthsDlg
// class has an initialized and created CBrush member named m_brush.
// The control will be painted with red text and a background
// color of m_brush.
HBRUSH CPenWidthsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{// Call the base class implementation first! Otherwise, it may// undo what we're trying to accomplish here.HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);// Are we painting the IDC_MYSTATIC control? We can use// CWnd::GetDlgCtrlID() to perform the most efficient test.if (pWnd->GetDlgCtrlID() == IDC_MYSTATIC){// Set the text color to redpDC->SetTextColor(RGB(255, 0, 0));// Set the background mode for text to transparent // so background will show thru.pDC->SetBkMode(TRANSPARENT);// Return handle to our CBrush objecthbr = m_brush;}return hbr;
}
CWnd::OnPaint
當 Windows 或應用程序請求重繪應用程序窗口的一部分時,框架會調用此成員函數。
afx_msg void OnPaint();
注解
在調用 UpdateWindow 或 RedrawWindow 成員函數時發送 WM_PAINT 消息。
由于在設置了 RDW_INTERNALPAINT 標志的情況下調用了 RedrawWindow 成員函數,窗口可能會收到內部繪制消息。 在這種情況下,窗口可能不包含更新區域。 應用程序應調用 GetUpdateRect 成員函數來確定窗口是否包含更新區域。 如果 GetUpdateRect 返回 0,則應用程序不應調用 BeginPaint 和 EndPaint 成員函數。
應用程序需負責通過在其內部數據結構中查找每個 WM_PAINT 消息來檢查任何必要的內部重繪或更新,因為 WM_PAINT 消息可能是由無效區域以及在設置了 RDW_INTERNALPAINT 標志的情況下調用 RedrawWindow 成員函數而導致的。
Windows 僅發送內部 WM_PAINT 消息一次。 在 UpdateWindow 成員函數將內部 WM_PAINT 消息發送到某個窗口后,在該窗口失效或者在設置了 RDW_INTERNALPAINT 標志的情況下再次調用 RedrawWindow 成員函數之前,不會發送或發布更多的 WM_PAINT 消息。
CWnd::OnNcPaint
需要繪制非工作區時,框架會調用此成員函數。
afx_msg void OnNcPaint();
注解
默認實現繪制窗口框架。
應用程序可以重寫此調用并繪制其自身的自定義窗口框架。 剪切區域始終是矩形,即使框架的形狀已更改。
CWnd::OnDrawItem
當控件或菜單的視覺方面發生更改時,框架將對所有者繪制按鈕控件、組合框控件、列表框控件或菜單的所有者調用此成員函數。
afx_msg void OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDrawItemStruct);
參數
nIDCtl
包含發送了 WM_DRAWITEM 消息的控件的標識符。 如果菜單發送了消息,則 nIDCtl 包含 0。
lpDrawItemStruct
指定指向 DRAWITEMSTRUCT 數據結構的長指針,該結構包含有關要繪制的項和所需繪制類型的信息。
注解
DRAWITEMSTRUCT 結構的 itemAction 成員定義要執行的繪制操作。 此成員中的數據允許控件所有者確定所需的繪制操作。
在處理此消息后返回之前,應用程序應確保 DRAWITEMSTRUCT 結構的 hDC 成員所標識的設備上下文已還原到默認狀態。
如果 hwndItem 成員屬于 CButton、CMenu、CListBox 或 CComboBox 對象,則調用相應類的 DrawItem 虛擬函數。 重寫相應控件類的 DrawItem 成員函數可繪制項。
備注
框架調用此成員函數來支持你的應用程序處理 Windows 消息。 傳遞到函數的參數反映了收到消息時框架所接收的參數。 如果調用此函數的基類實現,該實現將使用最初隨消息傳遞的參數,而不是你提供給該函數的參數。
CWnd::OnEraseBkgnd
當 CWnd 對象背景需要擦除時(例如,調整大小時),框架會調用此成員函數。
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
參數
pDC
指定設備上下文對象。
返回值
如果擦除背景,則返回非零值;否則返回 0。
注解
調用它來準備一個用于繪制的失效區域。
默認實現使用窗口類結構的 hbrBackground 成員指定的窗口類背景畫筆來擦除背景。
如果 hbrBackground 成員為 NULL,則 OnEraseBkgnd 的重寫版本應擦除背景色。 該版本還應通過首先對畫筆調用 UnrealizeObject,然后選擇畫筆,將所需畫筆的原點與 CWnd 坐標對齊。
如果重寫的 OnEraseBkgnd 處理消息并擦除背景,則它應返回非零值以響應 WM_ERASEBKGND;這表示不需要進一步擦除。 如果它返回 0,則窗口將仍舊標記為需要擦除。 (通常,這意味著 PAINTSTRUCT 結構的 fErase 成員將是 TRUE。)
Windows 假設使用 MM_TEXT 映射模式來計算背景。 如果設備上下文使用任何其他映射模式,則擦除的區域可能不在工作區的可見部分內。
備注
框架調用此成員函數來支持你的應用程序處理 Windows 消息。 傳遞到函數的參數反映了收到消息時框架所接收的參數。 如果調用此函數的基類實現,該實現將使用最初隨消息傳遞的參數,而不是你提供給該函數的參數。
CWnd::InvalidateRect
通過將給定矩形添加到 CWnd 更新區域,使給定矩形中的工作區失效。
void InvalidateRect(LPCRECT lpRect,BOOL bErase = TRUE);
參數
lpRect
指向包含要添加到更新區域的矩形(以客戶端坐標表示)的 CRect 對象或 RECT 結構。 如果 lpRect 為 NULL,則將整個工作區添加到該區域。
bErase
指定是否要擦除更新區域中的背景。
注解
在發送下一條 WM_PAINT 消息時,會將失效矩形連同更新區域中的所有其他區域一起標記為可繪制。 失效區域在更新區域中累積到在下一次發生 WM_PAINT 調用時處理該區域,或者該區域被 ValidateRect 或 ValidateRgn 成員函數驗證為止。
bErase 參數指定在處理更新區域時是否要擦除更新區域中的背景。 如果 bErase 為 TRUE,則在調用 BeginPaint 成員函數時擦除背景;如果 bErase 為 FALSE,則背景將保持不變。 對于更新區域的任何部分,如果 bErase 為 TRUE,則會擦除整個區域(而不僅僅是給定部分)中的背景。
每當 CWnd 更新區域不為空并且該窗口的應用程序隊列中沒有其他消息時,Windows 就會發送一條 WM_PAINT 消息。
類似的函數
MFC中的CWnd::Invalidate、CWnd::InvalidateRgn
void Invalidate(BOOL bErase = TRUE);
void InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE);
WIN32API中的InvalidateRect
BOOL InvalidateRect([in] HWND hWnd,[in] const RECT *lpRect,[in] BOOL bErase
);
CView::OnDraw
由框架調用以呈現文檔的圖像。
virtual void OnDraw(CDC* pDC) = 0;
參數
pDC
指向用于呈現文檔圖像的設備上下文。
注解
框架調用此函數以執行屏幕顯示、打印和打印預覽,并在每種情況下傳遞不同的設備上下文。 沒有默認實現。
必須重寫此函數才能顯示文檔的視圖。 可以使用 pDC 參數所指向的 CDC 對象發出圖形設備接口 (GDI) 調用。 可以在繪圖前在設備上下文中選擇 GDI 資源(例如筆或字體),之后將取消選擇它們。 通常,繪圖代碼可以與設備無關;也就是說,不需要有關哪種類型的設備顯示圖像的信息。
若要優化繪圖,請調用設備上下文的 RectVisible 成員函數,以確定是否繪制給定的矩形。 如果需要區分普通屏幕顯示和打印,請調用設備上下文的 IsPrinting 成員函數。