【C++/MFC】リストビューに色を塗る

 リストビュー(CListCtrlクラス)の任意の行/列/セルに色を付ける方法。

開発環境Visual Studio 2022
言語C++
フレームワークMFC
動作確認Windows 11
Windows 10
Windows 7

(1) リストビューを実装しているダイアログクラスに、メンバー関数を追加。(関数名は任意)


    void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);

(2) メッセージマップに、以下を追加。(リストビューのIDは、IDC_LIST1の場合)


    ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, OnCustomDraw)

(3) メンバー関数を記述。行と列のインデックスはゼロ開始。色指定の方法は、後述する。

特定の行のみ色を付ける場合

行に色を付けた例

void CXxxxDlg::OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVCUSTOMDRAW lpLvCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);

    if (lpLvCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
    {
        // 最初に、ここに入る
        // 次にCDDS_ITEMPREPAINTのステージに移行するために、このif文は必要
        *pResult = CDRF_NOTIFYITEMDRAW;
        return;
    }

    if (lpLvCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    {
        // 行指定
        if (lpLvCustomDraw->nmcd.dwItemSpec == 行インデックス)
        {
            // テキストの色指定
            lpLvCustomDraw->clrText = 色;

            // 背景の色指定
            lpLvCustomDraw->clrTextBk = 色;
        }

        *pResult = CDRF_NEWFONT;
        return;
    }

    *pResult = 0;
}

特定のセル(または列のみ)に色を付ける場合

セルに色を付けた例
列に色を付けた例

void CXxxxDlg::OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVCUSTOMDRAW lpLvCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);

    if (lpLvCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
    {
        // 最初に、ここに入る
        // 次にCDDS_ITEMPREPAINTのステージに移行するために、このif文は必要
        *pResult = CDRF_NOTIFYITEMDRAW;
        return;
    }

    if (lpLvCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    {
        // 2番目に、ここに入る
        // 次にCDDS_SUBITEMのステージに移行するために、このif文は必要
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
        return;
    }

    if (lpLvCustomDraw->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
    {
        // 行と列指定
        if (lpLvCustomDraw->nmcd.dwItemSpec == 行インデックス &&
            lpLvCustomDraw->iSubItem == 列インデックス)
        {
            // テキストの色指定
            lpLvCustomDraw->clrText = 色;

            // 背景の色指定
            lpLvCustomDraw->clrTextBk = 色;
        }
        else
        {
            // 色を変更しないセルのデフォルト色を指定
            // これを指定しない場合、色を変更した列以降は、同じ色になってしまう

            // テキストのデフォルト色
            lpLvCustomDraw->clrText = GetSysColor(COLOR_WINDOWTEXT);

            // 背景のデフォルト色
            lpLvCustomDraw->clrTextBk = GetSysColor(COLOR_WINDOW);
        }

        *pResult = CDRF_NEWFONT;
        return;
    }

    *pResult = 0;
}

色指定の記述例


// RGB指定(10進) (黄色の例)
RGB(255, 242, 0)

// RGB指定(16進) (黄色の例)
RGB(0xFF, 0xF2, 0x00)

 GetSysColorを使用すると、Windowsの設定色を指定できる。 この色は、Windows 11の場合、[設定]-[アクセシビリティ]-[コントラスト テーマ]を変更すると連動する (Windows 10は、[設定]-[簡単操作]-[ハイ コントラスト]。Windows 7は、[ウィンドウの色とデザイン])。 ただし、[設定]-[個人用設定]-[色]のライト/ダークモードとは連動しない。

カスタマイズ項目GetSysColor引数デフォルト色
背景COLOR_WINDOW
テキストCOLOR_WINDOWTEXT
ハイパーリンクCOLOR_HOTLIGHT
アクティブでないテキストCOLOR_GRAYTEXT
選択されたテキストCOLOR_HIGHLIGHTTEXT
選択されたテキスト(背景)COLOR_HIGHLIGHT
ボタンのテキストCOLOR_BTNTEXT
ボタンのテキスト(背景)COLOR_3DFACE
GetSysColorの例

リファレンス

NMLVCUSTOMDRAW structure
https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcustomdraw

NMCUSTOMDRAW structure
https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmcustomdraw

GetSysColor function
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor