在 MFC 開發中,常需要使用 CColorDialog 讓使用者選取顏色,並透過 OnCtlColor 將該顏色套用至特定控制項(如靜態文字)。但許多開發者遇到一個疑慮:如何保存使用者在 CColorDialog 中選擇的顏色,避免每次重繪都重新呼叫對話框?
關鍵在於將選取的顏色儲存為成員變數,並在 OnCtlColor 中直接使用該變數建立畫筆,而非每次都彈出對話框。以下是完整實作範例:
// 標頭檔宣告
class CApp2Dlg : public CDialog
{
// ...
COLORREF m_color; // 保存使用者選擇的顏色
CBrush m_brush; // 對應的畫筆
// ...
};
// 1. 按鈕點擊事件:彈出調色盤並保存顏色
void CApp2Dlg::OnButton1()
{
CColorDialog colorDia;
if (colorDia.DoModal() == IDOK)
{
m_color = colorDia.GetColor(); // 保存到成員變數
GetDlgItem(IDC_STATIC_1)->InvalidateRect(NULL); // 觸發重繪
}
}
// 2. OnCtlColor 重寫:使用已保存的顏色
HBRUSH CApp2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// 只針對特定控制項(IDC_STATIC_1)套用自訂顏色
if (pWnd->GetDlgCtrlID() == IDC_STATIC_1)
{
// 重建畫筆(若顏色未變可優化為僅建立一次)
m_brush.CreateSolidBrush(m_color);
pDC->SetBkColor(m_color);
pDC->SetBkMode(OPAQUE);
return m_brush;
}
return hbr;
}
m_color 在對話框關閉後仍保留顏色值。InvalidateRect 觸發 WM_CTLCOLOR,而非在 OnCtlColor 內部彈出對話框。m_brush 應在顏色改變時重建,避免資源洩漏。此模式同樣適用於字型、背景圖等其他視覺屬性的動態切換。