How do I pinvoke to GetWindowLongPtr and SetWindowLongPtr on 32-bit platforms?
我想P /调用GetWindowLongPtr和SetWindowLongPtr,并且看到有关它们的冲突信息。
一些消息来源说,在32位平台上,GetWindowLongPtr只是一个调用GetWindowLong的预处理器宏,而GetWindowLongPtr在user32.dll中并不存在。例如:
- SetWindowLongPtr的pinvoke.net条目具有一个静态方法,该方法将检查IntPtr.Size,然后调用SetWindowLong或SetWindowLongPtr,并带有注释,指出"旧版OS不支持SetWindowLongPtr"。没有关于"旧版OS"的含义的解释。
- 关于StackOverflow的回答指出"在32位系统上,GetWindowLongPtr只是一个指向GetWindowLong的C宏"。
因此这些来源似乎表明,例如32位Windows 7附带的user32.dll版本中根本没有* Ptr入口点。
但是我在MSDN文档中看不到任何迹象。根据MSDN,SetWindowLongPtr取代了SetWindowLong(简单明了)。并且根据SetWindowLongPtr页面的需求部分,似乎SetWindowLongPtr自Windows 2000(客户端和服务器版本)以来就已经存在于user32.dll中。同样,没有提到32位操作系统中缺少入口点。
我怀疑事实是介于两者之间:当您告诉C编译器以较早的操作系统为目标(即,编译将在Win9x和NT4上运行的东西)时,头文件将SetWindowLongPtr声明为一个宏,该宏调用SetWindowLong,但是入口点可能确实存在于Windows 2000及更高版本中,如果您告诉编译器将目标对准那些平台,则可以直接获取(而不是宏)。但这只是一个猜测;我真的没有足够的资源或专门知识来进行验证。
目标平台也有可能发挥作用-如果您为x86平台编译应用程序,则不应在64位操作系统上调用SetWindowLongPtr。同样,我知道足够多的问题,但我不知道如何找到答案。 MSDN似乎建议SetWindowLongPtr总是正确的。
有人可以告诉我,简单地P / Invoke到SetWindowLongPtr并完成此操作是否安全? (假设Windows 2000及更高版本。)是否可以P /调用SetWindowLongPtr给我正确的入口点:
- 是否在32位操作系统上运行针对x86平台的应用程序?
- 是否在64位操作系统上运行针对x86平台的应用程序?
- 是否在64位操作系统上运行针对x64平台的应用程序?
我建议您以Windows窗体内部执行此操作的方式进行处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); |
这意味着32位操作系统可能没有
更新(有关_WIN64的更多说明):
要在C#中模拟相同的行为,我建议像pinvoke.net一样检查