【Chapter 3 - Kernel Objects】SetWindowLongPtr 和 DWLP_MSGRESULT / DWL_MSGRESULT

学习《Windows via C/C++》的时候,看到了一个宏~

chHANDLE_DLGMSG(hwnd, WM_COMMAND,    Dlg_OnCommand);

于是查了一下,原来这个宏是这样子的:

/// chHANDLE_DLGMSG Macro /


// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
// boxes because DlgProc returns a BOOL instead of an LRESULT (like
// WndProcs). This chHANDLE_DLGMSG macro corrects the problem:
#define chHANDLE_DLGMSG(hWnd, message, fn)                 \
   case (message): return (SetDlgMsgResult(hWnd, uMsg,     \
      HANDLE_##message((hWnd), (wParam), (lParam), (fn))))

于是乎 HANDLE_##message 又不明白了,然后 google 之,找到下面的文章:

关于HANDLE_##MESSAGE , chHANDLE_DLGMSG宏的理解!!!!_jasonM2008的专栏-CSDN博客

但是 SetDlgMsgResult 函数依旧令人费解,VS2010 的 MSDN 上居然找不到,后来终于在 windowsX.h 上发现它的踪影了:

#define     SetDlgMsgResult(hwnd, msg, result) (( \
        (msg) == WM_CTLCOLORMSGBOX      || \
        (msg) == WM_CTLCOLOREDIT        || \
        (msg) == WM_CTLCOLORLISTBOX     || \
        (msg) == WM_CTLCOLORBTN         || \
        (msg) == WM_CTLCOLORDLG         || \
        (msg) == WM_CTLCOLORSCROLLBAR   || \
        (msg) == WM_CTLCOLORSTATIC      || \
        (msg) == WM_COMPAREITEM         || \
        (msg) == WM_VKEYTOITEM          || \
        (msg) == WM_CHARTOITEM          || \
        (msg) == WM_QUERYDRAGICON       || \
        (msg) == WM_INITDIALOG             \
    ) ? (BOOL)(result) : (SetWindowLongPtr((hwnd), DWLP_MSGRESULT, (LPARAM)(LRESULT)(result)), TRUE))

怎么样?够繁杂吧!看来看去看不懂,只好继续 google ,终于找到了这篇文章:

INFO: DWL_MSGRESULT - PowerBASIC Peer Support Community

也就是说,当对话框接收到的是上面列出的消息时,因为它们的返回值是固定类型的,所以就直接返回 result 了。

但如果接收到其他消息的时候,程序员可能希望返回一些其他东西,比如句柄啊,指针啊,等等。

此时如果直接以返回值的形式返回 result,则会将结果返回到默认的对话框处理函数 DefDlgProc 中,而程序员是无法进入 DefDlgProc 去取得这个返回值的(一般来说)。这时微软为每个窗口所定义的额外字节便可以粉墨登场了!程序员可以将需要返回的特殊值写入到那4个额外字节中:

SetWindowLongPtr (hwnd, DWLP_MSGRESULT, result) ;

然后,程序员就可以在其他的地方通过 GetWindowLongPtr 取得原先存储在额外字节中的内容了。

result = GetWindowLongPtr (hwnd, DWLP_MSGRESULT) ;

当然,前提是一旦设置了 SetWindowLongPtr 以后就不能再对窗口进行其他的操作,比如 SetWindowText ,这样一来会清空窗口的额外字节中的内容~~

哦,对了。DWLP_MSGRESULT 和 DWL_MSGRESULT 是差不多的~~具体看定义:

#include <winuser.h>
/* 
 * Get/SetWindowWord/Long offsets for use with WC_DIALOG windows
 */
#define DWL_MSGRESULT   0
#define DWL_DLGPROC     4
#define DWL_USER        8

#ifdef _WIN64

#undef DWL_MSGRESULT
#undef DWL_DLGPROC
#undef DWL_USER

#endif /* _WIN64 */

#define DWLP_MSGRESULT  0
#define DWLP_DLGPROC    DWLP_MSGRESULT + sizeof(LRESULT)
#define DWLP_USER       DWLP_DLGPROC + sizeof(DLGPROC)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

写代码的安徒生

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值