Winapi 在按钮上处理NM_CUSTOMDRAW-但Windows仍然绘制文本

Winapi 在按钮上处理NM_CUSTOMDRAW-但Windows仍然绘制文本,winapi,ownerdrawn,custom-draw,Winapi,Ownerdrawn,Custom Draw,我正在试验在我的win32应用程序中使用NM_CUSTOMDRAW而不是WM_DRAWITEM作为位图按钮。WM_DRAWITEM功能正常-除了在启用桌面主题的WINE下不工作(出于某种原因,启用主题后,WINE仅在单击按钮时发送WM_DRAWITEM) 不管怎样,我试着从下面的OK按钮上删除了BS_OWNERDRAW,剩下的就不管了。为了测试处理WM_NOTIFY,我只需将所需字段从NMCUSTOMDRAW结构复制到DRAWITEMSTRUCT,并将其传递给现有的WM_DRAWITEM处理程序

我正在试验在我的win32应用程序中使用NM_CUSTOMDRAW而不是WM_DRAWITEM作为位图按钮。WM_DRAWITEM功能正常-除了在启用桌面主题的WINE下不工作(出于某种原因,启用主题后,WINE仅在单击按钮时发送WM_DRAWITEM)

不管怎样,我试着从下面的OK按钮上删除了BS_OWNERDRAW,剩下的就不管了。为了测试处理WM_NOTIFY,我只需将所需字段从NMCUSTOMDRAW结构复制到DRAWITEMSTRUCT,并将其传递给现有的WM_DRAWITEM处理程序。按钮绘制得很好,但Windows在我的上方绘制OK文本(我的文本被移动,以便为复选标记腾出空间)。我已将代码粘贴到下面。我认为如果我返回CDRF_SKIPDEFAULT以响应所有NM_CUSTOMDRAW通知,Windows将不会尝试绘制任何内容。显然我还有别的事要做


如果不返回(CDRF\u SKIPDEFAULT),会发生什么情况
lpNMC->dwDrawStage!=CDDS_预先绘制
,但让它直接进入
DefWindowProc()
?同样的事情-除了现在Windows在OK中加下划线-当按钮有焦点时绘制一个焦点矩形-当按钮失去焦点时淡出。你能在非WINE Windows系统上重现它吗?这发生在Windows 7上。如果我在启用主题的WINE上运行相同的代码,它会对OK按钮设置主题(即根本不调用WM_NOTIFY处理程序),并且根本不绘制Cancel和Help按钮(即不发送WM_DRAWITEM消息)。在没有启用桌面的WINE上,它完全绘制OK按钮(不调用我的WM_NOTIFY stuff),取消和帮助按钮通常由我通过WM_DRAWITEM绘制。因此,显然,处理NM_CUSTOMDRAW并不能解决我的葡萄酒主题问题——但我仍然想了解如何做到这一点……返回值应该在对话框(通知消息发送到的窗口)上设置。如果您从
CDDS\u PREPAINT
返回
CDRF\u SKIPDEFAULT
,则您告诉Windows您已经完成了所有的绘制。如果返回
CDRF_DODEFAULT
(0,换句话说是默认值),则表示您告诉Windows您自己没有进行任何绘制。你到底想画什么?如果你不返回(CDRF_SKIPDEFAULT),会发生什么
lpNMC->dwDrawStage!=CDDS_预先绘制
,但让它直接进入
DefWindowProc()
?同样的事情-除了现在Windows在OK中加下划线-当按钮有焦点时绘制一个焦点矩形-当按钮失去焦点时淡出。你能在非WINE Windows系统上重现它吗?这发生在Windows 7上。如果我在启用主题的WINE上运行相同的代码,它会对OK按钮设置主题(即根本不调用WM_NOTIFY处理程序),并且根本不绘制Cancel和Help按钮(即不发送WM_DRAWITEM消息)。在没有启用桌面的WINE上,它完全绘制OK按钮(不调用我的WM_NOTIFY stuff),取消和帮助按钮通常由我通过WM_DRAWITEM绘制。因此,显然,处理NM_CUSTOMDRAW并不能解决我的葡萄酒主题问题——但我仍然想了解如何做到这一点……返回值应该在对话框(通知消息发送到的窗口)上设置。如果您从
CDDS\u PREPAINT
返回
CDRF\u SKIPDEFAULT
,则您告诉Windows您已经完成了所有的绘制。如果返回
CDRF_DODEFAULT
(0,换句话说是默认值),则表示您告诉Windows您自己没有进行任何绘制。你到底想画什么?
    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;