消息处理程序 INT_PTR 返回值的目的是啥?

Posted

技术标签:

【中文标题】消息处理程序 INT_PTR 返回值的目的是啥?【英文标题】:What is the purpose of message handler INT_PTR return value?消息处理程序 INT_PTR 返回值的目的是什么? 【发布时间】:2011-05-31 18:35:56 【问题描述】:

我正在使用 Visual Studio 的 Windows 窗体,示例代码如下:

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    /*code cut*/
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;
    break;

虽然我的其他处理函数如下所示:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    /*code cut*/
    return 0; // no magical casting or anything, just plain int

我有一个线索,当我在 WndProc() 中执行 return 0; 时,这意味着默认消息处理程序不会处理该消息?但是如果你这样做return 1; 它会使用默认处理程序来处理?

但是return (INT_PTR)TRUE; 的意义何在?在那里使用普通的return 0; 样式是否安全?我尝试编译,它也只适用于纯整数值。

另外,我不确定什么时候应该使用哪个值,示例代码有这样的:

EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;

但是return (INT_PTR)TRUE; 有什么意义呢?我将其更改为FALSE,但在功能上看不到任何差异。

所以,我不确定这是在做什么,有谁能让我清醒一下,什么时候应该使用return 1,什么时候应该使用return 0,什么时候应该使用其他东西(如果我应该)?

【问题讨论】:

我非常怀疑您是在使用 WinForms 并遇到此代码 - WinForms 是一个基于 .NET 的框架。 @ildjarn,我在那里写了“windows-forms”,但这个网站出于某种原因将其重命名为“winforms”。我也想知道它为什么这样做,我认为它只是它的另一个别名,所以我没有费心去改变它(如果它甚至可能......),“windows-forms”甚至是正确的名称吗? “WinForms”只是“Windows Forms”的常见缩写,但同样,Windows Forms 是一种 .NET 技术,这显然是原生 C++。这通常称为 WinAPI 代码。 【参考方案1】:

第一段代码是一个DialogProc——引用the relevant docs:

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

第二段代码是一个WindowProc——引用the relevant docs:

返回值 类型:LRESULT 返回值是消息处理的结果,取决于发送的消息。

因此,/*code cut*/ 部分至关重要,因为您想要的返回值完全取决于正在处理的消息。

【讨论】:

哦,我明白了,所以它不像我想象的那么简单。【参考方案2】:

它们有些相同。 LRESULT 旨在成为一种返回值类型,它至少可以容纳给定平台上指针大小的东西。

来自Windows Data Types (Windows)

LRESULT消息处理的签名结果。该类型在WinDef.h中声明如下:

typedef LONG_PTR LRESULT;

LONG_PTR指针精度的有符号长类型。在将指针转换为 long 以执行指针运算时使用。此类型在 中声明如下:

#if defined(_WIN64)
 typedef __int64 LONG_PTR; 
#else
 typedef long LONG_PTR;
#endif

LRESULT 类型多年来经历了许多变化。我相信在 Win64 之前,它被定义为INT_PTR,但后来更新为在 Win64 下的可移植性。许多其他类型也经历了类似的变化,例如WPARAMLPARAM,在Win16中曾经是16位值,在Win32中是32位值,现在在Win64中是64位。

正如@ildjarn 所指出的,返回的实际值取决于 Windows 消息上下文。还有可能您正在阅读的示例源代码可能是在 Win64 成为大热门之前创建的,并且可能在编写后没有更新或检查可移植性。

为了可移植性,根据编译目标,符号的定义略有不同。因此,(INT_PTR)TRUE 更好,即使您知道应该返回的确切值恰好与您的构建相匹配。虽然return 0; 在返回值为空的情况下可能会返回正确的结果,但在可移植性很重要的情况下进行编译时,这是一种不好的形式。使用return -1; 甚至return 0x7FFFFFFF; 更糟糕,因为您可能会截断、屏蔽或以其他方式破坏应该为所有平台编译目标提供的响应。

最好使用预定义的符号和常量,因为当您更改编译目标时,将替换正确的值和类型。

【讨论】:

我认为问题不在于类型,而在于值。 这些值是不透明的;即使10 不会映射到每个平台目标的正确值的情况确实不多。我承认,现在这简直是令人毛骨悚然,但十年或更久以前,Win64 的出现是一件大事。此外,对于习惯于编写平台可移植 C 的任何人来说,这些语义仍然很重要。 我的意思是,我认为 OP 是在问为什么在一种情况下返回 TRUE 而在另一种情况下(有效地)返回FALSE 问题标题可能暗示(INT_PTR)TRUE(INT_PTR)1的使用差异的更广泛背景,而不仅仅是TRUE1,甚至(INT_PTR)FALSE或@ 987654343@ 而不是 FALSE0。事实证明,(LRESULT) 可以在 WindowProcDialogProc 中与 (INT_PTR) 互换,至少由 reference 验证。

以上是关于消息处理程序 INT_PTR 返回值的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 C 程序执行代码时支持从 db2/大型机返回值的可能数据类型是啥

sql动态查询返回值的意义是啥呢?

PHP中的fopen()函数的返回值是啥?

如何使用 PHP 处理 403 错误

如何在不返回值的情况下显示消息

shell里的exit 2是啥意思?