【问题标题】:SetWindowLong with DWL_MSGRESULTSetWindowLong 与 DWL_MSGRESULT
【发布时间】:2021-11-05 13:13:33
【问题描述】:

据我所知,SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)CustomDraw(lParam)) 其中CustomDraw 是我的自定义绘制过程,设置NM_CUSTOMDRAW 的返回值,然后返回true:

SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)CustomDraw(lParam));
return TRUE;

它怎么可能设置返回值并且这个值是指向CustomDraw()的指针,然后它返回true所以它返回2个值?

DialogBox() 究竟在哪里返回值?是进一步处理这些值,还是直接跳过它们?

如果它设置CustomDraw(LPARAM lParam))被多次调用的返回值怎么可能?我的意思是,SetWindowLong(hWnd, DWL_MSGRESULT(LONG)CustomDraw(lParam)); 是如何让它调用这么多次的,它需要如何获得适当的消息?

return SetWindowLong(...) 和返回自定义绘图的指针有什么区别?

case NM_CUSTOMDRAW:
{
    LONG_PTR p = 0;
    p = SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)CustomDraw(lParam));
    return  TRUE; // why  return (LONG)CustomDraw(lParam)) wont work if setwindowlong "set return value " of message so of  NM_CUSTOMDRAW
}
LRESULT __stdcall CustomDraw (LPARAM lParam)
{
    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;

    switch(lplvcd->nmcd.dwDrawStage) 
    {
        case CDDS_PREPAINT : //Before the paint cycle begins
            return CDRF_NOTIFYITEMDRAW;
            
        case CDDS_ITEMPREPAINT: //Before an item is drawn
        {
            return CDRF_NOTIFYSUBITEMDRAW;
        }
        break;

        case CDDS_SUBITEM | CDDS_ITEMPREPAINT: //Before a subitem is drawn
        {
            switch(lplvcd->iSubItem)
            {
                case 0:
                {
                    lplvcd->clrText   = RGB(255,255,255);
                    lplvcd->clrTextBk = RGB(240,55,23);
                    return CDRF_NEWFONT;
                }
                break;

                case 1:
                {
                    lplvcd->clrText   = RGB(255,255,0);
                    lplvcd->clrTextBk = RGB(0,0,0);
                    return CDRF_NEWFONT;
                }
                break;  

                case 2:
                {
                    lplvcd->clrText   = RGB(20,26,158);
                    lplvcd->clrTextBk = RGB(200,200,10);
                    return CDRF_NEWFONT;
                }
                break;

                case 3:
                {
                    lplvcd->clrText   = RGB(12,15,46);
                    lplvcd->clrTextBk = RGB(200,200,200);
                    return CDRF_NEWFONT;
                }
                break;

                case 4:
                {
                    lplvcd->clrText   = RGB(120,0,128);
                    lplvcd->clrTextBk = RGB(20,200,200);
                    return CDRF_NEWFONT;
                }
                break;

                case 5:
                {
                    lplvcd->clrText   = RGB(255,255,255);
                    lplvcd->clrTextBk = RGB(0,0,150);
                    return CDRF_NEWFONT;
                }
                break;
            }
        }
    }
    return CDRF_DODEFAULT;
}

【问题讨论】:

  • 始终使用SetWindowLongPtrDWLP_MSGRESULT
  • @IInspectable 这篇文章不回答每个问题
  • 它不是作为答案发布的,所以,是的,预计它不是一个完整的答案。

标签: c++ c listview winapi


【解决方案1】:

SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)CustomDraw(lParam)); 不返回指向CustomDraw() 的指针。它调用CustomDraw(),然后将SetWindowLong()dwNewLong参数设置为CustomDraw()的返回值。

至于为什么需要DWL_MSGRESULT,文档中有介绍:

NM_CUSTOMDRAW notification code

返回值

您的应用程序可以返回的值取决于当前的绘图阶段。关联的NMCUSTOMDRAW 结构的dwDrawStage 成员包含一个指定绘图阶段的值。您必须返回以下值之一。

...

如果在对话过程中处理此消息,则必须在返回 TRUE 之前将返回值设置为窗口数据的一部分。有关详细信息,请参阅DialogProc

DLGPROC callback function

通常,如果对话框过程处理了消息,则应返回 TRUE,否则应返回 FALSE。如果对话框过程返回 FALSE,则对话框管理器执行默认对话框操作以响应消息。

如果对话框过程处理需要特定返回值的消息,则对话框过程应通过在返回 TRUE 之前立即调用 SetWindowLong(hwndDlg, DWL_MSGRESULT, lResult) 来设置所需的返回值。 请注意,您必须调用SetWindowLong 在返回 TRUE 之前;提前这样做可能会导致 DWL_MSGRESULT 值被嵌套对话框消息覆盖。

所以,代码正在处理NM_CUSTOMDRAW

  • 致电CustomDraw(lParam)
  • 然后将其返回值设置为DWL_MSGRESULT,以将值返回给发出NM_CUSTOMDRAW的调用者
  • 然后返回TRUE 以向DialogBox() 表明NM_CUSTOMDRAW 消息已被处理

【讨论】:

  • 好的,但是这个返回值是怎么回事,什么过程返回值?如果 DefDlgProc 过程值类似于 BOOL_PTR fResult = DialogProcedure(hdlg, uMsg, wParam, lParam); if (fResult) return GetWindowLongPtr(hdlg, DWLP_MSGRESULT);它在哪里返回这个值
  • 消息的原始发件人处理return'ed到它调用DialogProcedure()之后的任何值。如果DialogProcedure() 返回TRUE,则发送者是return'ed 保存在DWLP_MSGRESULT 中的值。否则,如果DialogProcedure() 返回FALSEDialogBox() 本身会根据需要处理消息,return 是一个适当的值。我不明白为什么这很难理解。这都是记录在案的行为。
猜你喜欢
  • 1970-01-01
  • 2012-03-06
  • 2010-09-22
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2013-08-13
  • 2012-10-12
  • 2014-09-07
相关资源
最近更新 更多