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.

Share:
20,816
Żubrówka
Author by

Żubrówka

Updated on April 25, 2020

Comments

  • Żubrówka
    Ż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
    Cody Gray over 12 years
    Right, 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 the SetWindowLongPtr function." So simply getting the declaration for SetWindowLong correct is not sufficient for 64-bit versions of Windows.
  • ChrisV
    ChrisV over 12 years
    SetWindowLong 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
    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
    ChrisV over 12 years
    @Cody: I agree completely. Easier to use SetWindowLongPtr all around.
  • arx
    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
    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 use SetWindowLong on a 32-bit platform. For 64-bit platforms, you need to use SetWindowLongPtr. 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
    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
    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 to SetWindowLong 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
    Żubrówka almost 12 years
    @CodyGray Feel free to add your answer if you feel so