SetWindowLong/GetWindowLong and 32-bit/64-bit CPUs
20,816
I guess you are wondering if you chose the type UInt32 correctly. The answer is yes. The docs explicitly say it is always 32 bit value: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx
Your code is correct.
Author by
Żubrówka
Updated on April 25, 2020Comments
-
Żubrówka about 4 years
I'm using the following code:
const int GWL_STYLE = (-16); const UInt32 WS_POPUP = 0x80000000; const UInt32 WS_CHILD = 0x40000000; [DllImport("user32.dll", SetLastError = true)] static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, UInt32 dwNewLong);
and somewhere...
SetWindowLong(this.Handle, GWL_STYLE, ((GetWindowLong(this.Handle, GWL_STYLE) & ~(WS_POPUP)) | WS_CHILD));
Will this run properly on both 32-bit and 64-bit machines?
If not, if I compile my application to be ran as a x86 process, will it still work fine on a 64-bit machine?
And how can I rewrite the following code to be OK in both 32-bit and 64-bit machines?
-
Cody Gray over 12 yearsRight, but it also says: "Note This function has been superseded by the
SetWindowLongPtr
function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use theSetWindowLongPtr
function." So simply getting the declaration forSetWindowLong
correct is not sufficient for 64-bit versions of Windows. -
ChrisV over 12 yearsSetWindowLong still works fine on 64-bit platforms as long as you're not passing anything that's officially pointer-sized (e.g., window procedures).
-
Cody Gray over 12 years@Chris: Yes, but the
SetWindowLong
function is frequently used to pass things like pointers... It seems like a much better idea to write the code correctly the first time so you don't have to remember to worry about it later when you decide to reuse the same definition, but this time pass a pointer. -
ChrisV over 12 years@Cody: I agree completely. Easier to use SetWindowLongPtr all around.
-
arx over 12 years@CodyGray: SetWindowLongPtr is a macro on 32-bit platforms so you won't get very far trying to P/Invoke it.
-
Cody Gray over 12 years@arx: Where in the world did I say to P/Invoke
SetWindowLongPtr
? The point was and is that this answer is incorrect. You should not useSetWindowLong
on a 32-bit platform. For 64-bit platforms, you need to useSetWindowLongPtr
. You have to write code to do this. I would have posted an answer of my own, but the question has already been answered, so I voted to close as a duplicate. -
arx over 12 years@CodyGray: You quoted "to write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function". I don't think it's a stretch to imagine someone reading that quote in a C#/pinvoke thread and thinking you intended it as good advice for C#/pinvoke. Although you didn't, it could easily have been misinterpreted (and it plainly was by ChrisV).
-
Cody Gray over 12 years@arx: I was quoting the documentation, not suggesting a plan of action. Again, the point was that the original answer is incorrect. I'm still not sure how you arrived at a conclusion otherwise. You do need to P/Invoke
SetWindowLongPtr
on 64-bit Windows. You need to fall back toSetWindowLong
on 32-bit Windows. These comment boxes aren't long enough for me to write full answers, you know. There are some details that get omitted. -
Żubrówka almost 12 years@CodyGray Feel free to add your answer if you feel so