How to connect to GetWindowLongPtr and SetWindowLongPtr on 32-bit platforms?

I want P / Invoke on GetWindowLongPtr and SetWindowLongPtr , and I see conflicting information about them.

Some sources say that on 32-bit platforms, GetWindowLongPtr is just a preprocessor macro that calls GetWindowLong, and GetWindowLongPtr does not exist as an entry point to user32.dll. For example:

  • The pinvoke.net entry for SetWindowLongPtr has a static method that checks IntPtr.Size and then calls SetWindowLong or SetWindowLongPtr, commenting that "legacy OSs do not support SetWindowLongPtr." There is no explanation of what is meant by "obsolete OS".
  • The answer at https://stackoverflow.com/a/312588/12 reads: "On 32-bit systems, GetWindowLongPtr is just a C macro that points to GetWindowLong."

Thus, these sources seem to indicate that * Ptr entry points are simply missing from the user32.dll version that ships with, say, 32-bit Windows 7.

But I do not see any signs of this in the MSDN documentation. According to MSDN, SetWindowLongPtr replaces SetWindowLong, simple and simple. And according to the requirements section of the SetWindowLongPtr page , it looks like SetWindowLongPtr is in user32.dll with Windows 2000 (both client and server versions). Again, entry points are not mentioned on 32-bit operating systems.

I suspect the truth is somewhere in between: when you tell the C ++ compiler to focus on older OSs (i.e. to compile something that will work on Win9x and NT4), then the header files declare SetWindowLongPtr as a macro, which calls SetWindowLong, but the entry point probably exists in Windows 2000 and later, and you will get it directly (instead of a macro) if you tell the compiler to target these platforms. But this is just a hunch; I really don't have the resources or the know-how to peek and test it.

It is also possible that the target platform plays a role - if you compile your application for the x86 platform, you should not call SetWindowLongPtr on a 64-bit OS. Again, I know enough to think about it, but I do not know how to find the answer. MSDN seems to suggest that SetWindowLongPtr is always valid.

Can someone tell me if it is safe to just P / Invoke to SetWindowLongPtr and do with it? (Assume that Windows 2000 and later.) Will P / Invoking to SetWindowLongPtr give me the correct entry point:

  • if I run an application targeting the x86 platform on a 32-bit OS?
  • if I run an application targeting the x86 platform on a 64-bit OS?
  • Should I run an x64-based application on a 64-bit OS?
+11
c # pinvoke
Jul 27 '10 at 12:45
source share
2 answers

I would recommend you deal with how Windows Forms does this inside:

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); 
+15
Jul 27 '10 at 13:46 on
source share
  • Open the header file (on the MSDN page this is indicated as Winuser.h). Win32 headers are usually found in C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include
  • Search for all instances of SetWindowLongPtr / GetWindowLongPtr .
  • Note that when _WIN64 defined, they are functions; if it is not, they SetWindowLong before SetWindowLong / GetWindowLong .

This means that 32-bit operating systems may not have SetWindowLongPtr / GetWindowLongPtr as a valid function, so it seems like the pinvoke.net comment is correct.

Update (clarification on _WIN64):

_WIN64 determined by the C / C ++ compiler when compiling 64-bit code (which will only work on a 64-bit OS). Thus, 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 . This includes 32-bit code running on a 64-bit OS.

To emulate the same behavior in C #, I recommend checking IntPtr.Size , as pinvoke.net does; which tells you if you are using 32-bit or 64-bit code. (Remember that 32-bit code can run on a 64-bit OS). Using IntPtr.Size in managed code emulates the same behavior as _WIN64 for native code.

+3
Jul 27 '10 at 13:01
source share



All Articles