`

【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 之,找到下面的文章:

http://blog.csdn.net/jasonM2008/article/details/3869296

但是 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 ,终于找到了这篇文章:

http://www.powerbasic.com/support/pbforums/showthread.php?t=18613

也就是说,当对话框接收到的是上面列出的消息时,因为它们的返回值是固定类型的,所以就直接返回 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)


0
0
分享到:
评论

相关推荐

    SetWindowLong 系统 最大化 最小化 关闭 开关

    SetWindowLong 是Windows API中的一个函数,用于修改窗口或控件的属性,这些属性包括窗口的各种行为和样式。在Windows编程中,理解并熟练运用这个函数对于定制窗口的行为至关重要。让我们深入探讨一下SetWindowLong...

    functions.rar_Windows编程_C/C++_

    3. **窗口类(Window Class)**:在创建窗口之前,需要先注册一个窗口类,这涉及到`RegisterClassEx`函数。窗口类定义了窗口的基本属性,如窗口过程、图标、光标等。 4. **窗口过程(Window Procedure)**:每个...

    VS2019版本下 rebbion 界面

    3. **实现全屏功能**: - 在CDialog派生类中添加一个成员变量,如m_bFullScreen,用于记录当前是否为全屏状态。 - 定义一个成员函数,例如OnFullScreen(),用于切换全屏。在该函数中,可以利用SetWindowPos()函数...

    Windows CE开发常见问题解答

    ::SetWindowLongPtr(m_hWnd, DWLP_USER, (LPARAM)&shidi); // 移动对话框位置以避免全屏 CRect rect; GetWindowRect(&rect); ScreenToClient(rect); MoveWindow(rect.left, rect.top, rect.Width(), rect....

    VC 窗体F11全屏切换

    标题“VC 窗体F11全屏切换”指的是利用Visual C++ 6.0的MFC(Microsoft Foundation Classes)库来实现窗体在按F11键时进行全屏和非全屏状态的切换。这个功能可以提高用户的沉浸感,特别是在设计游戏或多媒体应用时。...

    用mfc实现基于对话框有背景图片源程序

    下面,我们将会详细讲解实现这一功能的关键步骤和技术。 首先,我们需要创建一个MFC对话框应用项目。在Visual Studio中,选择“文件”&gt;“新建”&gt;“项目”,然后在模板列表中找到"MFC应用程序",按照向导的指引完成...

    hook 自定义消息 (delphi 7)

    3. Hook回调函数:定义和实现`TGetMsgProc`类型的函数,处理自定义消息。 4. 发送自定义消息:在需要的地方使用`PostMessage`或`SendMessage`函数发送自定义消息。 5. 卸载Hook:在程序退出前或不再需要Hook时,卸载...

    vc/MFC实现窗口的淡入淡出

    这个函数接受三个参数:窗口句柄、颜色键、透明度值和一个标志。颜色键用于指定窗口中的哪个颜色应被视为完全透明,而透明度值则在0(完全透明)到255(完全不透明)之间,影响窗口的可见度。 为了实现淡入效果,...

    透明对话框

    3. **重写 OnInitDialog()**:在`OnInitDialog()`中,添加代码设置`WS_EX_LAYERED`样式并设置透明度。 ```cpp BOOL CTransparentDlg::OnInitDialog() { CDialog::OnInitDialog(); // 设置层叠窗口样式 ...

    对话框背景贴图

    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT); SetLayeredWindowAttributes(m_hWnd, 0, 255, LWA_ALPHA); return TRUE; } ``` 通过以上步骤,我们就...

    子对话框半透明

    在Windows编程中,MFC(Microsoft Foundation Classes)是一个C++库,用于构建用户界面和应用程序。本主题将深入探讨如何在MFC应用中创建一个半透明的子对话框,利用`SetLayeredWindowAttributes`函数来实现这一效果...

    duilib之源码分析

    3. **销毁控件**:消息处理函数中对 `WM_NCDESTROY` 消息进行处理,调用原始的消息处理函数,重置 `GWLP_USERDATA`,并调用虚函数 `OnFinalMessage()` 来做最后的清理工作。 #### 三、绘制过程解析 duilib的绘制...

    VS2010操作WindowsMediaPlayer

    Windows Media Player控件是Microsoft提供的一种ActiveX控件,它允许开发者在应用程序中集成媒体播放功能,支持各种音频和视频格式。 首先,我们需要在Visual Studio 2010环境中创建一个新的MFC应用程序项目。打开...

    Windows API一日一练TXT版

    Windows API 一日一练(1)第一个应用程序 ---------------------------------------------------------------3 Windows API 一日一练(2)使用应用...Windows API一日一练(21)SetWindowLongPtr 和 GetWindowLongPtr 函数

    MFC热键例程hotkey

    SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)MyWndProc); // 注册热键 UINT hotKeyId = 1; if (!RegisterHotKey(NULL, hotKeyId, MOD_CTRL | MOD_ALT, VK_H)) { // 错误处理,无法注册热键 } ``` 其中,`...

    windows 窗口过程函数

    Windows窗口过程函数是Windows编程中非常核心的概念,它负责响应和处理发送给窗口的消息。窗口过程函数是属于某个特定窗口类的,这个类定义了窗口的默认行为和外观。窗口类是通过WNDCLASS结构体定义的,其中...

    mfc 窗口放大和缩小 两个实例 源代码

    在MFC(Microsoft Foundation Class)库中,窗口的放大和缩小是通过处理Windows消息来实现的。MFC提供了一种方便的方式来处理这些消息,使得窗口及其控件能够根据窗口大小的改变自动调整布局。本篇将详细介绍两个...

    mfc--非模式对话框

    3. **显示对话框**:使用`Create`或`DoModal`方法创建和显示对话框。对于非模式对话框,应使用`Create`: ```cpp if (!m_myNonModalDlg.Create(NULL, this)) { // 错误处理... } ``` 4. **消息循环处理**:非模式...

    鼠标穿透窗体

    例如,`SetWindowLongPtr`和`GetWindowLongPtr`函数用于设置和获取窗口的额外风格,` GWL_EXSTYLE`是一个常量,表示窗口的扩展风格。`WS_EX_TRANSPARENT`则是扩展风格中表示透明的一个标志。 ```csharp using ...

    Delphi 给窗口增加系统菜单

    在 Delphi 中,为窗口添加系统菜单是一项常见的任务,它涉及到对 Windows API 的深入理解和使用。系统菜单通常包含了像“最小化”、“最大化”、“关闭”等操作,这些操作是用户与应用程序交互的重要部分。本篇文章...

Global site tag (gtag.js) - Google Analytics