一尘不染

我如何在32位平台上使用GetWindowLongPtr和SetWindowLongPtr?

c#

我想P /调用GetWindowLongPtrSetWindowLongPtr,并且看到有关它们的冲突信息。

一些消息来源说,在32位平台上,GetWindowLongPtr只是一个调用GetWindowLong的预处理程序宏,而GetWindowLongPtr在user32.dll中不存在作为入口点。例如:

  • SetWindowLongPtrpinvoke.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位OS中缺少入口点。

怀疑 事实是介于两者之间:当您告诉C
++编译器针对较旧的OS(即,编译将在Win9x和NT4上运行的东西)时,头文件将SetWindowLongPtr声明为调用SetWindowLong的宏,但是入口点可能确实存在于Windows
2000及更高版本中,如果您告诉编译器将目标对准那些平台,则可以直接获得该入口点(而不是宏)。但这只是一个猜测;我真的没有足够的资源或专门知识来进行验证。

目标平台也有可能发挥作用-
如果您为x86平台编译应用程序,则不应在64位OS上调用SetWindowLongPtr。同样,我知道足够多的问题,但我不知道如何找到答案。MSDN似乎建议SetWindowLongPtr总是正确的。

谁能告诉我简单地P /调用SetWindowLongPtr并完成操作是否安全?(假设Windows 2000及更高版本。)P
/调用SetWindowLongPtr是否可以为我提供正确的入口点:

  • 是否在32位操作系统上运行针对x86平台的应用程序?
  • 是否在64位操作系统上运行针对x86平台的应用程序?
  • 是否在64位操作系统上运行针对x64平台的应用程序?

阅读 577

收藏
2020-05-19

共1个答案

一尘不染

我建议您以Windows窗体内部执行的方式处理此问题:

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);
2020-05-19