標準 CColorDialog 僅支援單顏色選擇,如何修改為「前景色」+「背景色」雙顏色同時設定?
核心思路:繼承 CColorDialog,在 OnInitDialog 中動態添加「前景/背景」切換按鈕,內部維護兩組顏色狀態。
class CDualColorDialog : public CColorDialog
{
COLORREF m_fgColor, m_bgColor;
BOOL m_bForegroundActive; // 當前編輯哪組
CButton m_btnFg, m_btnBg; // 切換按鈕
// ...
};
OnInitDialog 注入 UI:
BOOL CDualColorDialog::OnInitDialog()
{
CColorDialog::OnInitDialog();
// 動態創建兩個按鈕,位置布局在標準色板旁
m_btnFg.Create(_T("前景色"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, rectFg, this, IDC_BTN_FG);
m_btnBg.Create(_T("背景色"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, rectBg, this, IDC_BTN_BG);
// 設置初始狀態
m_bForegroundActive = TRUE;
UpdateButtonStates();
return TRUE;
}
void CDualColorDialog::OnBtnFg() { m_bForegroundActive = TRUE; UpdateButtonStates(); }
void CDualColorDialog::OnBtnBg() { m_bForegroundActive = FALSE; UpdateButtonStates(); }
void CDualColorDialog::UpdateButtonStates()
{
// 將當前活動顏色同步到標準色板控制項
SetCurrentColor(m_bForegroundActive ? m_fgColor : m_bgColor);
// 按鈕視覺反饋(按下/彈起)
m_btnFg.SetCheck(m_bForegroundActive);
m_btnBg.SetCheck(!m_bForegroundActive);
}
void CDualColorDialog::OnOK()
{
// 從標準色板讀取當前顏色存入對應成員
if (m_bForegroundActive) m_fgColor = GetColor();
else m_bgColor = GetColor();
CColorDialog::OnOK();
}
| 方案 | 優點 | 缺點 |
|---|---|---|
| 繼承 CColorDialog 擴展 | 復用標準色板、自定義色、拾色器邏輯 | 需處理 MFC 內部佈局細節 |
| 兩次彈出標準 CColorDialog | 零代碼修改,最簡單 | 用戶體驗差,流程繁瑣 |
| 完全自繪對話框 | UI 完全可控 | 開發量大,需自行實現色板、HSV/RGB 轉換 |
推薦方案一,平衡開發效率與用戶體驗。