【问题标题】:What do LRESULT, WPARAM and LPARAM mean?LRESULT、WPARAM 和 LPARAM 是什么意思?
【发布时间】:2013-07-24 22:51:23
【问题描述】:

我正在用 C# 导入 WinApi 函数、编写回调等 (example),我一直在想:

  • 它们是什么意思? LRESULT 作为最后的结果? W参数?左参数?
  • 如何安全地“包装”它们
    • WPARAMLPARAM 有时包含结构。所以我需要将它们用作IntPtrLRESULT 怎么样?我使用int 或更好的IntPtr 安全吗?

我在 C# 中为 LRESULT 使用什么类型? intIntPtr

【问题讨论】:

标签: c# winapi pointers intptr


【解决方案1】:

那是查尔斯·西蒙尼,他是微软应用软件部门的前负责人,该部门开发了 Word 和 Excel。他是制定标识符命名标准的人。由于没有人知道如何发音他的姓氏,他们选择了他出生的国家并称之为匈牙利符号。 Windows 小组也采用了它,但选择了“坏”的 System Hungarian。选择标识符的第一个字母以记录变量的类型。与“好”类型相反,Apps Hungarian,它通过逻辑类型名称而不是物理类型名称选择前缀。西蒙尼的版本。

所以在 Long 中是 L,在 Word 中是 W。 LPCWSTR 就是这样一个笨蛋,指向常量宽字符串的长指针。 System Hungarian 的一个明显问题是,当架构发生变化时,它不再那么好用了。最初选择用于 16 位操作系统(L=32 位,W=16 位),迁移到 32 位而不更改名称(W=32 位),我们现在是 64 位(L= W=64 位)。

所以忽略这些前缀,它们只是一个历史意外。您确实必须为 LRESULT 类型选择 IntPtr,它当然可以是 64 位版本的 Windows 上的 64 位值。如果您不这样做,则很难诊断出问题,这是一个常见问题。

题外话,你在照片背景中看到的模糊图像也是关于 Simonyi 的一个有趣的花絮。微软与员工分享了它的巨大成功,并将他们中的许多人变成了千万富翁。您在背景中看到的是停靠在国际空间站的航天飞机的照片。西蒙尼是七位“太空游客”之一,他给自己买了一张国际空间站的票。唯一这样做的人两次,让他损失了 6000 万美元 :)

【讨论】:

  • 伟大的历史描述,+1
  • 对 SDK 头文件和文档使用的 Systems Hungarian 的起源进行了微小的更正:documentation folks 显然引入了“一些严重的可读性更改”,其余的是历史。
  • 哇,微软没那么邪恶!
  • SDK typedefs 可以很好地帮助可移植性,即使名称令人困惑。
【解决方案2】:

这些名字来自历史原因。在 WIndows16 位 WPARAM 的时代,在匈牙利符号中表示 Word-Parameter 和 LPARAM Long-Parameter。移动到 32 位将两者折叠为相同的大小(32 位整数),但名称保持不变。 LRESULT 意味着长结果,并且由于历史原因再次保留名称。当 windows64 位出现时,另一个变化发生了。 请have a look here in MSDN 获取完整列表。 详细说明:LPARAMLRESULT 都是 LONG_PTR 的 typedef,其中 LONG_PTR 是:

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

WPARAMUINT_PTR 的 typedef,其中 UINT_PTR 是:

#if defined(_WIN64)
 typedef unsigned __int64 UINT_PTR;
#else
 typedef unsigned int UINT_PTR;
#endif

您基本上可以看到最终指向相同大小位的类型:唯一真正的区别是您使用的是 Windows 32 还是 64。 就用法的含义而言,它们是通用的pourpose参数,您可以根据窗口过程需要执行的操作来使用它们。通常,由于几个数字是不够的,因此使用复杂数据结构的指针并将它们的值作为 WPARAM 或 LPARAM 传递,因此除非您关注上下文,否则您无法指定任何特定含义。

【讨论】:

    【解决方案3】:

    这是匈牙利符号的一个例子:

    • LLPARAMLRESULT 中都表示“长”,指定一个32 位的int
    • wWPARAM 中的意思是“单词”(以前是 16 位 int,但现在也是 32 位 int — 至少在针对 32 位架构时)

    类型名称/别名的其余部分应该暗示它们的含义,即 LRESULT 包含某种结果值,LPARAMWPARAM 用于参数变量。

    wParamlParam 参数内容的实际含义取决于发送的特定消息;它们只是消息参数的通用存储桶。因此,您很可能无法绕过不安全的类型转换。

    【讨论】:

    • L 表示“长”,W 表示“单词”,但您应该澄清一下,这些天它们都是 32 位(或 64 位,具体取决于平台)。
    • @JonathanPotter:感谢您的更正,我正要检查。我相信 Win16 API 中的字体大小过去是不同的,所以我认为这些名称中的匈牙利语前缀具有历史背景。
    • @stakx 是的,you are correct
    • 有很多关于匈牙利符号的历史,以及这个版本如何成为每个人都知道的版本,而不是发明者希望前缀系统如何工作。见princeton.edu/~achaney/tmve/wiki100k/docs/…
    【解决方案4】:

    LPARAM 是 LONG_PTR 的 typedef,在 win32 上是 long(有符号 32 位),在 x86_64 上是 __int64(有符号 64 位)。

    WPARAM 是 UINT_PTR 的 typedef,在 win32 上是 unsigned int(无符号 32 位),在 x86_64 上是 unsigned __int64(无符号 64 位)。

    typedef UINT_PTR WPARAM;

    typedef LONG_PTR LPARAM;

    在c#中你可以使用IntPtr

    What are the definitions for LPARAM and WPARAM?

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多