I want to make a item gray. According to docs I set TVIS_CUT
in stateMask
and mask
.
But it doesn't work (the item is black as usual). TVIS_BOLD
works perfect.
I use CodeBlocks17 (gcc)/Win7x64. Also I tried VS2005 and another OS (WinXP) with the same result.
What did I miss?
#define _UNICODE
#define UNICODE
#include <windows.h>
#include <commctrl.h>
LRESULT CALLBACK cbMain (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) {
MSG msg;
WNDCLASSEX wc{0};
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("MyAppClass");
wc.lpfnWndProc = cbMain;
wc.style = CS_DBLCLKS;
wc.cbSize = sizeof (WNDCLASSEX);
wc.hIcon = LoadIcon(0, IDC_ICON);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.lpszMenuName = 0;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wc))
return EXIT_FAILURE;
HWND hMainWnd = CreateWindowEx (0, TEXT("MyAppClass"), NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 500, 600, 160, 300, HWND_DESKTOP, NULL, hInstance, NULL);
HWND hTreeWnd = CreateWindowEx(0, WC_TREEVIEW, NULL, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS, 0, 0, 150, 200, hMainWnd, (HMENU)100, hInstance, NULL);
TVITEM tvi{0};
tvi.mask = TVIF_TEXT | TVIF_STATE;
tvi.pszText = TEXT("Item");
tvi.cchTextMax = 40;
tvi.stateMask = TVIS_CUT;
tvi.state = TVIS_CUT;
TVINSERTSTRUCT tvins{0};
tvins.item = tvi;
tvins.hInsertAfter = TVI_ROOT;
tvins.hParent = TVI_ROOT;
SendMessage(hTreeWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK cbMain (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
I used Custom Draw
as Jonathan Potter said.
Here is one pitfall: while a current item changing, old item has CDIS_FOCUS
and CDIS_SELECTED
flags in pCustomDraw->nmcd.uItemState
member, and new item doesn't have. So pCustomDraw->clrText = (pNMTVCD->nmcd.uItemState & CDIS_FOCUS) == CDIS_FOCUS) ? ...
will works a little bit strange. I checked pCustomDraw->clrTextBk
instead. But it can be broken when user used a custom theme.
I use this article and an applied code to build the example.
#define _UNICODE
#define UNICODE
#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0500
#include <windows.h>
#include <commctrl.h>
#define IDC_TREEVIEW 100
LRESULT CALLBACK cbMain (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) {
MSG msg;
WNDCLASSEX wc{0};
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("MyAppClass");
wc.lpfnWndProc = cbMain;
wc.style = CS_DBLCLKS;
wc.cbSize = sizeof (WNDCLASSEX);
wc.hIcon = LoadIcon(0, IDC_ICON);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.lpszMenuName = 0;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wc))
return EXIT_FAILURE;
HWND hMainWnd = CreateWindowEx (0, TEXT("MyAppClass"), NULL, WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU, 500, 600, 160, 300, HWND_DESKTOP, NULL, hInstance, NULL);
HWND hTreeWnd = CreateWindowEx(0, WC_TREEVIEW, NULL, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS, 0, 0, 150, 200, hMainWnd, (HMENU)IDC_TREEVIEW, hInstance, NULL);
TVITEM tvi{0};
TVINSERTSTRUCT tvins{0};
tvi.mask = TVIF_TEXT | TVIF_STATE;
tvi.pszText = TEXT("Item1");
tvi.cchTextMax = 40;
tvi.stateMask = 0;
tvi.state = 0;
tvins.item = tvi;
tvins.hInsertAfter = TVI_ROOT;
tvins.hParent = TVI_ROOT;
SendMessage(hTreeWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
tvi.pszText = TEXT("Item2");
tvins.item = tvi;
SendMessage(hTreeWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
tvi.stateMask = TVIS_CUT;
tvi.state = TVIS_CUT;
tvi.pszText = TEXT("Item3");
tvins.item = tvi;
SendMessage(hTreeWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK cbMain (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY: {
PostQuitMessage (0);
}
break;
case WM_NOTIFY: {
NMHDR* pHdr = (LPNMHDR)lParam;
if (pHdr->idFrom == IDC_TREEVIEW && pHdr->code == NM_CUSTOMDRAW) {
LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam;
if (pCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
return CDRF_NOTIFYITEMDRAW;
if (pCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {
BOOL isCut = TreeView_GetItemState(pHdr->hwndFrom, (HTREEITEM)pCustomDraw->nmcd.dwItemSpec, TVIS_CUT) & TVIS_CUT;
pCustomDraw->clrText = pCustomDraw->clrTextBk != RGB( 255, 255, 255) ? RGB( 255, 255, 255) :
isCut ? RGB( 128, 128, 128 ) : RGB( 0, 0, 0);
}
return CDRF_DODEFAULT;
}
}
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}