2

I'm experimenting with using NM_CUSTOMDRAW instead of WM_DRAWITEM for bitmap buttons in my win32 app. The WM_DRAWITEM stuff works fine - except that it doesn't work under WINE with a desktop theme enabled (for some reason, with a theme enabled, WINE only sends WM_DRAWITEM when you click a pushbutton).

Anyway, I tried removing the BS_OWNERDRAW from the OK button below - leaving the others alone. To test processing the WM_NOTIFY, I just copy the fields I need from the NMCUSTOMDRAW struct to a DRAWITEMSTRUCT and pass that to my existing WM_DRAWITEM handler. The button draws fine, but then Windows draws the OK text over mine (my text is shifted to make room for the checkmark). I've pasted the code below. I thought that if I returned CDRF_SKIPDEFAULT in response to all NM_CUSTOMDRAW notifications, Windows wouldn't try to draw anything. There's obviously something else I need to do...

enter image description here

 case WM_NOTIFY: // Only intrested in NM_CUSTOMDRAW messages here. nmh = (LPNMHDR) lParam; if (nmh->code != NM_CUSTOMDRAW) break; // Only interested in CDDS_PREPAINT. lpNMC = (LPNMCUSTOMDRAW) lParam; if (lpNMC->dwDrawStage != CDDS_PREPAINT) return(CDRF_SKIPDEFAULT); // Copy fields we need from NMCUSTOMDRAW to a DRAWITEMSTRUCT. memset(&dis, 0, sizeof(dis)); dis.hwndItem = nmh->hwndFrom; dis.hDC = lpNMC->hdc; dis.rcItem = lpNMC->rc; if (lpNMC->uItemState & CDIS_FOCUS) dis.itemState |= ODS_FOCUS; if (lpNMC->uItemState & CDIS_SELECTED) dis.itemState |= ODS_SELECTED; if (lpNMC->uItemState & CDIS_DEFAULT) dis.itemState |= ODS_DEFAULT; if (lpNMC->uItemState & CDIS_DISABLED) dis.itemState |= ODS_DISABLED; DrawBitmapButtonOnWindowsDialog(wParam, (LPARAM) &dis, -1); return(CDRF_SKIPDEFAULT); case WM_DRAWITEM: DrawBitmapButtonOnWindowsDialog(wParam, lParam, -1); break; 
11
  • What happens if you don't return(CDRF_SKIPDEFAULT); when lpNMC->dwDrawStage != CDDS_PREPAINT, but rather let it just fall through to DefWindowProc()? Commented Oct 26, 2016 at 17:15
  • Same thing - except that now Windows underlines the O in OK - and draws a focus rectangle when the button has focus - and fades it out when the button loses focus. Commented Oct 26, 2016 at 17:41
  • Are you able to reproduce this on a non-WINE Windows system? Commented Oct 26, 2016 at 18:02
  • 1
    This is happening on Windows 7. If I run the same code on WINE with a theme enabled, it themes the OK button (i.e. doesn't call my WM_NOTIFY handler at all), and doesn't paint the Cancel and Help buttons at all (i.e., no WM_DRAWITEM messages sent). On WINE without a desktop them enabled, it draws the OK button completely (doesn't call my WM_NOTIFY stuff), and the Cancel and Help buttons get ownerdrawn by me normally via WM_DRAWITEM. So, apparently handling NM_CUSTOMDRAW isn't going to fix my WINE themeing problem - but I'd still like to understand how to do it... Commented Oct 26, 2016 at 19:07
  • 1
    The return value should be set on the dialog (the window the notification message was send to). If you return CDRF_SKIPDEFAULT from CDDS_PREPAINT you are telling Windows you have done all the painting yourself. If you return CDRF_DODEFAULT (0, the default value in other words) you are telling Windows you haven't done any painting yourself. Exactly what painting is it you want to do? Commented Oct 27, 2016 at 1:49

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.