C语言 listView中的颜色填充子项不起作用

raogr8fs  于 2023-04-29  发布在  其他
关注(0)|答案(1)|浏览(93)

如果单元格为1,我希望子项为绿色,如果单元格为0,则为红色。我不太明白如何正确地子类化列表视图,使其工作。我从here中获取子类实现,完全复制了将子项背景转换为不同颜色的相关代码。
从代码的注解来看,WM_NOTIFY应该被调用几次,但我只调用了一次,我需要修复什么才能使着色工作?
这是我离开的地方:

#pragma once
#include <Windows.h>
#include <string>
#include <commctrl.h>
#define WIN32_LEAN_AND_MEAN

int wWrkPls = 655;
int hWrkPls = 200;

static HWND Matrix = NULL;

static HINSTANCE hInst;

LRESULT CALLBACK MainProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);

void CreateMatrix(HWND hWnd) {

    HWND Matrix = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"", WS_CHILD | WS_VISIBLE | LVS_REPORT, 0, 0, wWrkPls - 18, hWrkPls - 38, hWnd, NULL, NULL, NULL);

    DWORD dwStyle = SendMessage(Matrix, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
    dwStyle |= LVS_EX_GRIDLINES;
    SendMessageW(Matrix, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);

    dwStyle = ListView_GetExtendedListViewStyle(Matrix);
    dwStyle |= LVS_EX_FULLROWSELECT;
    ListView_SetExtendedListViewStyle(Matrix, dwStyle);

    ::Matrix = Matrix;

    LVCOLUMN lvColumn;
    lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
    for (int i = 0; i < 5; i++) {

        lvColumn.cx = 30;
        lvColumn.pszText = (LPWSTR)L" ";
        SendMessage(Matrix, LVM_INSERTCOLUMN, i, (LPARAM)&lvColumn);

    }

    LVITEM lvItem;
    lvItem.mask = LVIF_STATE | LVIF_TEXT;
    lvItem.state = LVIF_PARAM;
    lvItem.stateMask = NULL;

    for (int i = 0; i < 5; i++) {

        lvItem.iSubItem = 0;
        lvItem.iItem = i;
        lvItem.pszText = (LPWSTR)L"0";
        SendMessage(Matrix, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
    
        for (int j = 1; j < 5; j++) {

            lvItem.iSubItem = j;
            lvItem.pszText = (LPWSTR)L"0";
            SendMessage(Matrix, LVM_SETITEM, 0, (LPARAM)&lvItem);

        }
    
    }

}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPr, LPSTR args, int ncmdshow) {

    WNDCLASS WindowClass = { 0 };
    //WindowClass.hbrBackground = CreatePatternBrush(LoadBitmap(hInst, 0));
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.hInstance = hInst;
    //WindowClass.hIcon = LoadIcon(hInst, 0);
    WindowClass.lpszClassName = L"MainWindClass";
    WindowClass.lpfnWndProc = MainProc;

    ::hInst = hInst;

    if (!RegisterClassW(&WindowClass)) {

        return -1;

    }

    int wCntr = GetSystemMetrics(SM_CXSCREEN) / 2;
    int hCntr = GetSystemMetrics(SM_CYSCREEN) / 2;

    HWND MainWindow = CreateWindowA("MainWindClass", "", WS_OVERLAPPEDWINDOW | WS_VISIBLE, wCntr - (wWrkPls / 2), hCntr - (hWrkPls / 2), wWrkPls, hWrkPls, NULL, NULL, NULL, NULL);

    MSG MainMsg = { 0 };
    while (GetMessage(&MainMsg, NULL, NULL, NULL)) {

        TranslateMessage(&MainMsg);
        DispatchMessage(&MainMsg);

    }

    return 0;

}

LRESULT ProcessCustomDraw(LPARAM lp)
{
    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lp;

    switch (lplvcd->nmcd.dwDrawStage) {
    
        case CDDS_PREPAINT: //Before the paint cycle begins

            return CDRF_NOTIFYITEMDRAW;

        case CDDS_ITEMPREPAINT: { //Before an item is drawn
    
            return CDRF_NOTIFYSUBITEMDRAW;
        }
        break;

        case CDDS_SUBITEM | CDDS_ITEMPREPAINT: { //Before a subitem is drawn
    
            switch (lplvcd->iSubItem) {
        
                case 0: {
        
                    lplvcd->clrText = RGB(255, 255, 255);
                    lplvcd->clrTextBk = RGB(240, 55, 23);
                    return CDRF_NEWFONT;

                }
                break;

                case 1: {
        
                    lplvcd->clrText = RGB(255, 255, 0);
                    lplvcd->clrTextBk = RGB(0, 0, 0);
                    return CDRF_NEWFONT;

                }
                break;

                case 2: {
        
                    lplvcd->clrText = RGB(20, 26, 158);
                    lplvcd->clrTextBk = RGB(200, 200, 10);
                    return CDRF_NEWFONT;

                }
                break;

                case 3: {
        
                    lplvcd->clrText = RGB(12, 15, 46);
                    lplvcd->clrTextBk = RGB(200, 200, 200);
                    return CDRF_NEWFONT;

                }
                break;

                case 4: {
        
                    lplvcd->clrText = RGB(120, 0, 128);
                    lplvcd->clrTextBk = RGB(20, 200, 200);
                    return CDRF_NEWFONT;

                }
                break;

                case 5: {
        
                    lplvcd->clrText = RGB(255, 255, 255);
                    lplvcd->clrTextBk = RGB(0, 0, 150);
                    return CDRF_NEWFONT;

                }
                break;
        
            }

        }

    }
    
}

LRESULT CALLBACK MainProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {

    switch (msg) {

    case WM_NOTIFY: {
    
        LPNMLISTVIEW pnm = (LPNMLISTVIEW)lp;

        if (pnm->hdr.hwndFrom == Matrix && pnm->hdr.code == NM_CUSTOMDRAW) {
            SetWindowLong(hWnd, 0, (LONG)ProcessCustomDraw(lp));

        }

    }

    break;

    case WM_CREATE: {

        CreateMatrix(hWnd);

    }

    break;

    case WM_DESTROY: {

        PostQuitMessage(0);

    }

    break;

    default:

        return DefWindowProc(hWnd, msg, wp, lp);

    }

}
pgvzfuti

pgvzfuti1#

谢谢大家的帮助!我按如下方式完成了我的要求。该主题已关闭。

#include <Windows.h>
#include <string>
#include <commctrl.h>

int wWrkPls = 655;
int hWrkPls = 200;

static HWND Matrix = NULL;

static HINSTANCE hInst;

LRESULT CALLBACK MainProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);

void CreateMatrix(HWND hWnd) {

    HWND Matrix = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"", WS_CHILD | WS_VISIBLE | LVS_REPORT, 0, 0, wWrkPls - 18, hWrkPls - 38, hWnd, NULL, NULL, NULL);

    DWORD dwStyle = SendMessage(Matrix, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
    dwStyle |= LVS_EX_GRIDLINES;
    SendMessageW(Matrix, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);

    dwStyle = ListView_GetExtendedListViewStyle(Matrix);
    dwStyle |= LVS_EX_FULLROWSELECT;
    ListView_SetExtendedListViewStyle(Matrix, dwStyle);

    ::Matrix = Matrix;

    LVCOLUMN lvColumn;
    lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
    for (int i = 0; i < 5; i++) {

        lvColumn.cx = 30;
        lvColumn.pszText = (LPWSTR)L" ";
        SendMessage(Matrix, LVM_INSERTCOLUMN, i, (LPARAM)&lvColumn);

    }

    LVITEM lvItem;
    lvItem.mask = LVIF_STATE | LVIF_TEXT;
    lvItem.state = LVIF_PARAM;
    lvItem.stateMask = NULL;

    for (int i = 0; i < 5; i++) {

        lvItem.iSubItem = 0;
        lvItem.iItem = i;
        lvItem.pszText = (LPWSTR)L"0";
        SendMessage(Matrix, LVM_INSERTITEM, 0, (LPARAM)&lvItem);

        for (int j = 1; j < 5; j++) {

            lvItem.iSubItem = j;
            lvItem.pszText = (LPWSTR)L"1";
            SendMessage(Matrix, LVM_SETITEM, 0, (LPARAM)&lvItem);

        }

    }

}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPr, LPSTR args, int ncmdshow) {

    WNDCLASS WindowClass = { 0 };
    //WindowClass.hbrBackground = CreatePatternBrush(LoadBitmap(hInst, 0));
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.hInstance = hInst;
    //WindowClass.hIcon = LoadIcon(hInst, 0);
    WindowClass.lpszClassName = L"MainWindClass";
    WindowClass.lpfnWndProc = MainProc;

    ::hInst = hInst;

    if (!RegisterClassW(&WindowClass)) {

        return -1;

    }

    int wCntr = GetSystemMetrics(SM_CXSCREEN) / 2;
    int hCntr = GetSystemMetrics(SM_CYSCREEN) / 2;

    HWND MainWindow = CreateWindowA("MainWindClass", "", WS_OVERLAPPEDWINDOW | WS_VISIBLE, wCntr - (wWrkPls / 2), hCntr - (hWrkPls / 2), wWrkPls, hWrkPls, NULL, NULL, NULL, NULL);

    MSG MainMsg = { 0 };
    while (GetMessage(&MainMsg, NULL, NULL, NULL)) {

        TranslateMessage(&MainMsg);
        DispatchMessage(&MainMsg);

    }

    return 0;

}

LRESULT ProcessCustomDraw(HWND hWnd, LPARAM lp) {

    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lp;

    TCHAR szText[10];

    ListView_GetItemText(hWnd, lplvcd->nmcd.dwItemSpec, lplvcd->iSubItem, szText, 100);

    switch (lplvcd->nmcd.dwDrawStage) {

        case CDDS_PREPAINT: { //Before the paint cycle begins

            return CDRF_NOTIFYITEMDRAW;

        }
        break;

        case CDDS_ITEMPREPAINT: { //Before an item is drawn

            return CDRF_NOTIFYSUBITEMDRAW;

        }
        break;

        case CDDS_SUBITEM | CDDS_ITEMPREPAINT: { //Before a subitem is drawn

            if (wcscmp(szText, L"1") == 0) {
        
                lplvcd->clrTextBk = RGB(0, 255, 0);
        
            }

            else {
        
                lplvcd->clrTextBk = RGB(255, 0, 0);
        
            }

            return CDRF_NEWFONT;
        }

    }

}

LRESULT CALLBACK MainProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {

    switch (msg) {

    case WM_NOTIFY: {

        LPNMLISTVIEW pnm = (LPNMLISTVIEW)lp;

        if (pnm->hdr.hwndFrom == Matrix && pnm->hdr.code == NM_CUSTOMDRAW) {

            return ProcessCustomDraw(pnm->hdr.hwndFrom, lp);

        }

    }
    break;

    case WM_CREATE: {

        CreateMatrix(hWnd);

    }
    break;

    case WM_DESTROY: {

        PostQuitMessage(0);

    }
    break;

    default:

        return DefWindowProc(hWnd, msg, wp, lp);

    }

}

相关问题