Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SetWindowPos compile error in 64-bit Windows

I'm currently changing our codebase to make it compile under 64-bit architecture. Most of the changes I'm having to make are obvious, but this one has got me stumped. SetWindowPos has a second argument, hWndInsertAfter, that can be either a window handle, or one of the predefined values HWND_TOP, HWND_BOTTOM, HWND_TOPMOST and HWND_NOTOPMOST (see here for MSDN info). These values are defined in WinUser.h.

In 32-bit architecture, using one of those in a call to SetWindowPos works fine, but in 64-bit, the compiler complains thus:

warning C4306: 'type cast' : conversion from 'int' to 'HWND' of greater size

This is because the #defines are casting [32-bit] integers as HWNDs, e.g.:

#define HWND_TOPMOST ((HWND)-1)

What do I need to change to make this compile in 64-bit architecture without the compiler throwing a warning? I can disable the warnings using #pragma warning( disable: 4306 ), or make my own definition using a 64-bit int in the #define, but surely there's a "proper" Microsoft way of doing this?

like image 631
Nick Shaw Avatar asked Nov 04 '13 16:11

Nick Shaw


2 Answers

The warning is triggered because you're casting the 32-bit int value -1 to a 64-bit pointer type void* without any intervening cast to a 64-bit integer type such as intptr_t. MSVC should have suppressed the warning in this case since (A) it's triggered only by the expansion of the system-provided macro HWND_TOPMOST and (B) the offending int is a decimal literal, but apparently MSVC's developers didn't think of those heuristics.

There's nothing you can do in your code to silence the warning, unless you're happy with

#undef HWND_TOPMOST
#define HWND_TOPMOST ((HWND)(intptr_t)-1)

Alternatively, you can try to suppress it in the IDE. This thread suggests

Project Settings | C/C++ | General and turn off "Detect 64-bit portability issues"

or pass /wd4306 on the command line.

like image 199
Quuxplusone Avatar answered Oct 15 '22 20:10

Quuxplusone


Ok, after MUCH testing, the problem was that my file was a .c file. I renamed it to .cpp and SetWindowPos then compiled without error (and conversely, in the new test app I created to try a 'bare bones' solution, when I renamed the default .cpp file to a .c file, it started complaining).

Looks like .c files don't want to be able to cast 32-bit int values to 64-bit pointers. Which makes sense, but doesn't explain why it works in .cpp files. If anyone has any ideas on why this is, do note it in the comments...

like image 23
Nick Shaw Avatar answered Oct 15 '22 22:10

Nick Shaw