How do I pinvoke to GetWindowLongPtr and SetWindowLongPtr on 32-bit platforms?

天大地大妈咪最大 提交于 2019-11-26 20:56:57

I'd recommend you deal with this the way Windows Forms does it internally:

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);
  1. Open the header file (on the MSDN page, this is listed as Winuser.h). Win32 headers are usually found at C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include
  2. Search for all instances of SetWindowLongPtr/GetWindowLongPtr.
  3. Note that when _WIN64 is defined, they are functions; when it's not, they are #define'd to SetWindowLong/GetWindowLong.

This implies that 32-bit OSes may not have SetWindowLongPtr/GetWindowLongPtr as an actual function, so it would appear that the comment on pinvoke.net is correct.

Update (more clarification on _WIN64):

_WIN64 is defined by the C/C++ compiler when compiling 64-bit code (that will only run on a 64-bit OS). So this means that any 64-bit code using SetWindowLongPtr/GetWindowLongPtr will use the actual functions, but any 32-bit code using them will use SetWindowLong/GetWindowLong instead. This includes 32-bit code running on a 64-bit OS.

To emulate the same behavior in C#, I recommend checking IntPtr.Size as done by pinvoke.net; that tells you whether you're running 32-bit or 64-bit code. (Keeping in mind that 32-bit code may run on a 64-bit OS). Using IntPtr.Size in managed code emulates the same behavior as _WIN64 does for native code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!