代码之家  ›  专栏  ›  技术社区  ›  Joe White

如何在32位平台上获取windowlongptr和setwindowlongptr?

  •  13
  • Joe White  · 技术社区  · 15 年前

    我想请求 GetWindowLongPtr SetWindowLongPtr 我看到了关于它们的相互矛盾的信息。

    有消息称,在32位平台上,getwindowlongptr只是一个调用getwindowlong的预处理器宏,getwindowlongptr在user32.dll中不作为入口点存在。例如:

    • 这个 pinvoke.net entry for SetWindowLongPtr 具有一个静态方法,该方法检查intptr.size,然后调用setwindowlong或setwindowlongptr,其中一个注释表示“旧操作系统不支持setwindowlongptr”。对于“遗留操作系统”的含义没有任何解释。
    • answer on StackOverflow 状态“在32位系统上,getwindowlongptr只是指向getwindowlong的C宏”。

    因此,这些来源似乎表明,*ptr入口点在32位Windows7附带的user32.dll版本中根本不存在。

    但我在msdn文档中没有看到这一点。根据msdn, 设置窗口长度指针 取代了setwindowlong、plain和simple。根据要求章节 SetWindowLongPtr page ,似乎自Windows 2000(客户端和服务器版本)以来,setwindowlongptr一直在user32.dll中。同样,没有提到32位操作系统中缺少入口点。

    犯罪嫌疑人 真相是介于两者之间:当你告诉C++编译器针对旧的OSES(即编译在WIN9X和NT4上运行的东西)时,头文件将SetWindowLongPtr声明为调用StWistWOWLUN的宏,但是入口点可能在Windows 2000和之后存在,并且直接得到(而不是TH)。e macro)如果告诉编译器以这些平台为目标。但这只是一个猜测;我没有真正的资源或技术去挖掘和验证它。

    目标平台也可能扮演一个角色——如果您为x86平台编译应用程序,那么不应该在64位操作系统上调用setwindowlongptr。再说一次,我知道足够多的问题,但我不知道如何找到答案。msdn似乎建议setwindowlongptr总是正确的。

    有人能告诉我,简单地对setwindowlongptr进行p/invoke操作是否安全吗?(假设Windows 2000及更高版本。)P/调用setWindowLongPTR会给我正确的入口点:

    • 如果我在32位操作系统上运行一个针对x86平台的应用程序?
    • 如果我在64位操作系统上运行一个针对x86平台的应用程序?
    • 如果我在64位操作系统上运行一个针对x64平台的应用程序?
    2 回复  |  直到 15 年前
        1
  •  17
  •   Hans Passant    15 年前

    我建议您以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);
    
        2
  •  4
  •   Stephen Cleary    15 年前
    1. 打开头文件(在msdn页面上,这列为winuser.h)。Win32头通常位于 C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include
    2. 搜索的所有实例 SetWindowLongPtr / GetWindowLongPtr .
    3. 注意什么时候 _WIN64 是定义的,它们是函数;如果不是,它们是 #define D到 SetWindowLong / GetWindowLong .

    这意味着32位操作系统可能没有 设置窗口长度指针 / 获取窗口长指针 作为一个实际函数,在pinvoke.net上的注释似乎是正确的。

    更新(更多关于Win64的说明):

    Win 64 在编译64位代码(只在64位OS上运行)时,由C/C++编译器定义。这意味着任何64位代码 设置窗口长度指针 / 获取窗口长指针 将使用实际函数,但使用它们的任何32位代码都将使用 设置窗口长 / 获得窗口长 相反。这包括在64位操作系统上运行的32位代码。

    为了在C中模拟相同的行为,我建议检查 IntPtr.Size 正如pinvoke.net所做的那样,它告诉您运行的是32位还是64位代码。(记住32位代码可以在64位操作系统上运行)。使用 尺寸大小 在托管代码中,模拟与 Win 64 对于本机代码。

    推荐文章