[英]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.