vuko_zrno
vuko_zrno

Reputation: 667

Error when including winuser.h. It defines ChangeMenu to ChangeMenuW or ChangeMenuA

Working on a Qt app on Windows. I include QVboxLayout in my source file only and this causes errors because its macro overwrites my method name.

foo.hpp
class foo
{
    ChangeMenu();
}

foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h

foo::ChangeMenu(){};

Now what happens is winuser.h has a macro

#ifdef UNICODE
#define ChangeMenu  ChangeMenuW
#else
#define ChangeMenu  ChangeMenuA
#endif // !UNICODE

This changes my function definition to ChangeMenuW but my declaration is still ChangeMenu.

How should I solve this? How can winuser.h define such a "normal" name as a macro?

Version of winuser.h is "windows kits\10\include\10.0.16299.0"

Upvotes: 2

Views: 1872

Answers (2)

Drake Wu
Drake Wu

Reputation: 7170

You could take no care about this issue, Although your method name will be the same as the windows API, but the system will not mix them(just unify Unicode on both the place to define/call). If you call the ChangeMenu() directly, you will call the winapi, and if

foo f;
f.ChangeMenu();

or

foo::ChangeMenu();(static)

You will call your method.

And if you want to disable the winapi:

#ifdef ChangeMenu
#undef ChangeMenu
    //code place that you define/call your own ChangeMenu().
#ifdef UNICODE
#define ChangeMenu  ChangeMenuW
#else
#define ChangeMenu  ChangeMenuA
#endif // !UNICODE
#endif

(It looks very tedious.)

Upvotes: 0

Matteo Italia
Matteo Italia

Reputation: 126787

Pretty much any Windows API that deals with strings is actually a macro that resolves to a A or W version. There's no way around, you can either:

  • avoid including windows.h, but as you noticed, it creeps through;
  • brutally #undef the macro before defining/using your function; this is a fit punishment for hoarding such normal and non-macro-looking identifiers, but is tedious and some other code may actually need the Win32 function;
  • just accept it as a sad fact of life and avoid all the relevant Win32 APIs names; if you use Qt and follow its naming convention, it should be easy, as Qt functions use lowerCamelCase (as opposed to Win32 UpperCamelCase);
  • include windows.h explicitly straight in your header (possibly under an #ifdef _WIN32); this will make sure that your identifier will get replaced by the macro in all instances, so everything will work fine even if the compiler will actually compile a function with a different name; suitable for standalone projects, not suitable for libraries. (Thanks @Jonathan Potter for suggesting this)

Upvotes: 2

Related Questions