簡體   English   中英

無法收到ListView的所有NM_CUSTOMDRAW dwDrawStage

[英]Unable to receive all NM_CUSTOMDRAW dwDrawStage for a ListView

我有一個帶有MDI框架窗口的Win32應用程序(無mfc)。

MDI主框架窗口將具有MDICLIENT窗口。 但是在我的應用程序中,主框架窗口還有另一個tabctrl子窗口,它在主框架的底部顯示一些listview Wnd:

//create the tab first, as a child of main MDI frame with 800px width and 300px height, at point (0, 600) of main frame window.
HWND hWndTabCtrl = CreateWindow(WC_TABCONTROL, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | TCS_BOTTOM, 0, 600, 800, 300, hWndMainFrame, NULL, hInstance, NULL);

//add one tab item for test:
TCITEM item;
item.mask = TCIF_TEXT;
item.pszText = L"Test List View";
TabCtrl_InsertItem(hWndTabCtrl , 0, &item);

//And then create a listview, this list view is a child window of tab ctrl (hWndTabCtrl)
HWND hWndListView = CreateWindow(WC_LISTVIEW, L"", WS_CHILD | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS | WS_VISIBLE, 0, 0,800, 280, hWndTabCtrl , NULL, hInstance, NULL);

//Now insert two columns:
LVCOLUMN column;
column.mask = LVCF_WIDTH | LVCF_TEXT;
column.cx = 200;
column.pszText = L"Column 0";
ListView_InsertColumn(hWndListView , 0, &column); //column for sub item 0
column.pszText = L"Column 1";
ListView_InsertColumn(hWndListView , 1, &column); //column for sub item 1

現在,我想更改子項目1的文本顏色。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message){
        case WM_NOTIFY:
            if (((LPNMHDR)lParam)->hwndFrom == hWndListView && ((LPNMHDR)lParam)->code == NM_CUSTOMDRAW){

                LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;

                switch (lplvcd->nmcd.dwDrawStage){
                    case CDDS_PREPAINT:
                        //I can receive this value 
                        return CDRF_NOTIFYITEMDRAW;
                        break;
                    case CDDS_ITEMPREPAINT:
                        //I cann't receive this value:
                        return CDRF_NOTIFYSUBITEMDRAW;
                        break;
                    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
                        //I cann't receive this value:
                        lplvcd->clrText = RGB(255,0, 0);
                        return CDRF_NEWFONT;
                        break;
                }
                return CDRF_DODEFAULT;
            }
            break;
        case ...
            ...
            break;
    default:
    return DefFrameProc(hWnd, hWndMainFrame, message, wParam, lParam);

    }
}

在WM_NOTIFY代碼塊的情況下,我只能接收一次lplvcd-> nmcd.dwDrawStage,其值為CDDS_PREPAINT。 我相信這是因為返回值CDRF_NOTIFYITEMDRAW未返回正確的“父級”。

是TabCtrl的問題還是MDI窗口的問題?

盡管文檔中有說明,但返回值實際上是位掩碼,因此您可以一次返回多個值。 同樣, dwDrawingStage也是位掩碼,因此您應該在尋找感興趣的特定位。

嘗試更多類似這樣的方法:

LPNMHDR pnmhdr = (LPNMHDR) lParam;
if ((pnmhdr->hwndFrom == hWndListView) && (pnmhdr->code == NM_CUSTOMDRAW))
{
    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW) lParam;

    if (lplvcd->nmcd.dwDrawStage & CDDS_ITEM)
    {
        if (lplvcd->nmcd.dwDrawStage & CDDS_ITEMPREPAINT)
        {
            if (lplvcd->nmcd.dwDrawStage & CDDS_SUBITEM)
            {
                lplvcd->clrText = RGB(255,0, 0);
                ...
                return CDRF_DODEFAULT | CDRF_NEWFONT;
            }
            else
            {
                ...
                return CDRF_DODEFAULT | CDRF_NOTIFYSUBITEMDRAW;
            }
        }
        ...
    }
    else
    {
        switch (lplvcd->nmcd.dwDrawStage)
        {
            case CDDS_PREPAINT:
            {
                ...
                return CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYSUBITEMDRAW;
            }
            ...
        }
    }
    return CDRF_DODEFAULT;
}

我有一個類似的問題(對話框中的ListView),但有一個共同因素:沒有MFC。 結果相同:接收CDDS_PREPAINT,但不接收CDDS_ITEMPREPAINT或其組合(CDDS_SUBITEM | CDDS_PREPAINT和CDDS_ITEM | CDDS_SUBITEM | CDDS_PREPAINT)。 經過3天的挖掘,我在https://www.codeproject.com/Articles/2890/Using-ListView-control-under-Win-API中找到了答案。

在我的DialogProc中,我將NM_CUSTOMDRAW的結果返回給WM_NOTIFY,如下所示:

    case WM_NOTIFY:
        NMHDR* pHdr = (NMHDR*) lParam;
        if (pHdr->idFrom == IDC_LIST_RESULTS  &&  pHdr->code == NM_CUSTOMDRAW)
        {
            return HandleCustomDraw((NMLVCUSTOMDRAW*)pHdr);
        }
        break;

但是正確的行為是將結果發送給所有者:

    case WM_NOTIFY:
        NMHDR* pHdr = (NMHDR*) lParam;
        if (pHdr->idFrom == IDC_LIST_RESULTS  &&  pHdr->code == NM_CUSTOMDRAW)
        {
            SetWindowLong(hDlg, DWL_MSGRESULT, (LONG)HandleCustomDraw((NMLVCUSTOMDRAW*)pHdr));
            return TRUE;
        }
        break;

希望能幫助到你!

編輯:當然,現在我在另一個stackoverflow問題中已經找到了相同的答案:-) 虛擬列表視圖未獲取CDDS_ITEMPREPAINT c ++

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM