翻译 《The Old New Thing》 - Returning values from a dialog procedure

Returning values from a dialog procedure - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20031107-00/?p=41923

Raymond Chen 2003年11月7日


简要

这篇文章由Raymond Chen撰写,解释了对话框过程如何从Windows编程中返回值。他详细说明了对话框过程需要返回两个信息,并且如何通过使用窗口的长整型属性来实现这一点。此外,还讨论了“特殊消息”的例外情况以及它们存在的原因。

正文

        出于某种原因,人们常常对对话框过程如何返回值感到困惑,所以我打算用不同的方式解释一下。

        对话框过程的关键在于,它们实际上需要返回两个信息:

  1. 消息是否已被处理?
  2. 如果是,返回值应该是什么?

        由于需要返回两个信息,但C函数只能有一个返回值,所以需要用其他方式返回第二个信息。

对话框过程的返回值是消息是否已被处理。第二条信息——应该是什么返回值——存储在DWLP_MSGRESULT的窗口长整型属性中。

        换句话说,DefDlgProc的大致工作流程如下:

LRESULT CALLBACK DefDlgProc(
    HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    DLGPROC dp = (DLGPROC)GetWindowLongPtr(hdlg, DWLP_DLGPROC);
    SetWindowLongPtr(hdlg, DWLP_MSGRESULT, 0);
    BOOL_PTR fResult = dp(hdlg, uMsg, wParam, lParam);
    if (fResult) return GetWindowLongPtr(hdlg, DWLP_MSGRESULT);
    else ... 执行默认行为 ...
}

        如果返回除0以外的任何值,则通过 SetWindowLongPtr(hdlg, DWLP_MSGRESULT, value) 设置的值将被用作消息结果。

        例如,许多WM_NOTIFY通知允许通过返回TRUE来覆盖默认行为。要防止列表视图标签被编辑,您可以从LVN_BEGINLABELEDIT通知返回TRUE。但如果您从对话框过程这样做,您必须分两步进行:

SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE); 
return TRUE;

        第二行设置了对话框过程的返回值,这告诉DefDlgProc消息已被处理,应该抑制默认处理。第一行告诉DefDlgProc返回给消息发送者(列表视图控件)的值是什么。如果您忘记了这两个步骤中的任何一个,期望的值就不会到达列表视图控件。

        请注意,DefDlgProc在发送消息之前将DWLP_MSGRESULT设置为零。这样,如果对话框过程忘记显式设置消息结果,结果将为零。

        这也突出了在从对话框过程返回之前立即调用SetWindowLongPtr的重要性,而且不要更早。如果您在设置返回值和返回TRUE之间做任何操作,可能会触发向对话框过程发送消息,这将把消息结果重置为零。

        注意:有一些“特殊消息”不遵循这个规则。这些例外情况在DialogProc的文档中给出。为什么存在这些例外?

        因为在最初设计对话框管理器时,确定对这些消息进行特殊处理将使对话框过程更容易编写,因为您不必经历设置DWLP_MSGRESULT的额外步骤。幸运的是,时至今日,没有人添加任何新的例外。记住这些例外所增加的心理复杂性超过了不必编写一行代码的心理节省(“SetWindowLongPtr(hdlg, DWLP_MSGRESULT, desiredResult)”)。

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0x0007

可不可奖励我吃只毛嘴鸡 馋😋

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值