如何在32位平台上pinvoke到GetWindowLongPtr和SetWindowLongPtr?
我想P / Invoke到GetWindowLongPtr和SetWindowLongPtr ,我看到有关它们的相互矛盾的信息。
有些消息称,在32位平台上,GetWindowLongPtr只是一个调用GetWindowLong的预处理器宏,而GetWindowLongPtr不作为user32.dll中的入口点存在。 例如:
- SetWindowLongPtr的pinvoke.net条目有一个静态方法,它检查IntPtr.Size,然后调用SetWindowLong或SetWindowLongPtr,注释说“遗留操作系统不支持SetWindowLongPtr”。 没有解释“遗留操作系统”的含义。
- StackOverflow的答案是 “On 32bit系统GetWindowLongPtr只是一个指向GetWindowLong的C宏”。
因此,这些来源似乎表明* Ptr入口点根本不存在于32位Windows 7附带的user32.dll版本中。
但我在MSDN文档中没有看到这一点。 根据MSDN, SetWindowLongPtr取代了SetWindowLong,简单明了。 根据SetWindowLongPtr页面的要求部分,看起来SetWindowLongPtr自Windows 2000(客户端和服务器版本)以来一直在user32.dll中。 同样,没有提到32位操作系统中缺少的入口点。
我怀疑事实介于两者之间:当你告诉C ++编译器定位较旧的操作系统(即编译将在Win9x和NT4上运行的东西)时,头文件将SetWindowLongPtr声明为调用SetWindowLong的宏,但是入口点可能确实存在于Windows 2000及更高版本中,如果您告诉编译器定位这些平台,您将直接获取它(而不是宏)。 但这只是猜测; 我真的没有资源或技术可以深入挖掘并validation它。
目标平台也可能扮演一个角色 – 如果您为x86平台编译应用程序,那么就不应该在64位操作系统上调用SetWindowLongPtr。 再一次,我知道这个问题,但我不知道如何找到答案。 MSDN似乎暗示SetWindowLongPtr总是正确的。
有人能告诉我简单的P / Invoke到SetWindowLongPtr是否安全并完成它? (假设Windows 2000及更高版本。)P /调用SetWindowLongPtr会给我正确的入口点:
- 如果我在32位操作系统上运行针对x86平台的应用程序?
- 如果我在64位操作系统上运行针对x86平台的应用程序?
- 如果我在64位操作系统上运行针对x64平台的应用程序?
我建议你按照Windows Forms内部的方式处理这个问题:
public static IntPtr GetWindowLong(HandleRef hWnd, int nIndex) { if (IntPtr.Size == 4) { return GetWindowLong32(hWnd, nIndex); } return GetWindowLongPtr64(hWnd, nIndex); } [DllImport("user32.dll", EntryPoint="GetWindowLong", CharSet=CharSet.Auto)] private static extern IntPtr GetWindowLong32(HandleRef hWnd, int nIndex); [DllImport("user32.dll", EntryPoint="GetWindowLongPtr", CharSet=CharSet.Auto)] private static extern IntPtr GetWindowLongPtr64(HandleRef hWnd, int nIndex);
- 打开头文件(在MSDN页面上,这列为Winuser.h)。 Win32标头通常位于
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include
- 搜索
SetWindowLongPtr
/GetWindowLongPtr
所有实例。 - 注意,当定义
_WIN64
时,它们是函数; 如果不是,那么它们就是#define
到SetWindowLong
/GetWindowLong
。
这意味着32位操作系统可能没有SetWindowLongPtr
/ GetWindowLongPtr
作为实际函数,因此看起来pinvoke.net上的注释是正确的。
更新(有关_WIN64的更多说明):
_WIN64
由C / C ++编译器在编译64位代码时定义(仅在64位操作系统上运行)。 所以这意味着任何使用SetWindowLongPtr
/ GetWindowLongPtr
64位代码都将使用实际的函数,但使用它们的任何32位代码都将使用SetWindowLong
/ GetWindowLong
。 这包括在64位操作系统上运行的32位代码。
要在C#中模拟相同的行为,我建议检查IntPtr.Size
如IntPtr.Size
所做; 它告诉您是否正在运行32位或64位代码。 (请记住,32位代码可能在64位操作系统上运行)。 在托管代码中使用IntPtr.Size
可以模拟与_WIN64
对本机代码相同的行为。