消息处理程序 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 下的可移植性。许多其他类型也经历了类似的变化,例如WPARAM
和LPARAM
,在Win16中曾经是16位值,在Win32中是32位值,现在在Win64中是64位。
正如@ildjarn 所指出的,返回的实际值取决于 Windows 消息上下文。还有可能您正在阅读的示例源代码可能是在 Win64 成为大热门之前创建的,并且可能在编写后没有更新或检查可移植性。
为了可移植性,根据编译目标,符号的定义略有不同。因此,(INT_PTR)TRUE
更好,即使您知道应该返回的确切值恰好与您的构建相匹配。虽然return 0;
在返回值为空的情况下可能会返回正确的结果,但在可移植性很重要的情况下进行编译时,这是一种不好的形式。使用return -1;
甚至return 0x7FFFFFFF;
更糟糕,因为您可能会截断、屏蔽或以其他方式破坏应该为所有平台编译目标提供的响应。
最好使用预定义的符号和常量,因为当您更改编译目标时,将替换正确的值和类型。
【讨论】:
我认为问题不在于类型,而在于值。 这些值是不透明的;即使1
和0
不会映射到每个平台目标的正确值的情况确实不多。我承认,现在这简直是令人毛骨悚然,但十年或更久以前,Win64 的出现是一件大事。此外,对于习惯于编写平台可移植 C 的任何人来说,这些语义仍然很重要。
我的意思是,我认为 OP 是在问为什么在一种情况下返回 TRUE
而在另一种情况下(有效地)返回FALSE
。
问题标题可能暗示(INT_PTR)TRUE
或(INT_PTR)1
的使用差异的更广泛背景,而不仅仅是TRUE
或1
,甚至(INT_PTR)FALSE
或@ 987654343@ 而不是 FALSE
或 0
。事实证明,(LRESULT)
可以在 WindowProc 或 DialogProc 中与 (INT_PTR)
互换,至少由 reference 验证。以上是关于消息处理程序 INT_PTR 返回值的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章