包含winuser.h时出错。它将ChangeMenu定义为ChangeMenuW或ChangeMenuA
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了包含winuser.h时出错。它将ChangeMenu定义为ChangeMenuW或ChangeMenuA相关的知识,希望对你有一定的参考价值。
在Windows上使用Qt应用程序。我只在我的源文件中包含QVboxLayout,这会导致错误,因为它的宏会覆盖我的方法名称。
foo.hpp
class foo
{
ChangeMenu();
}
foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h
foo::ChangeMenu(){};
现在发生的事情是winuser.h有一个宏
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
这会将我的函数定义更改为ChangeMenuW,但我的声明仍然是ChangeMenu。
我该怎么解决这个问题? winuser.h如何将这样一个“普通”名称定义为宏?
winuser.h的版本是“windows kits 10 include 10.0.16299.0”
答案
几乎任何处理字符串的Windows API实际上都是一个解析为A或W版本的宏。没有办法,你可以:
- 避免包括
windows.h
,但正如你所注意到的那样,它会穿过; - 在定义/使用你的函数之前,残酷的
#undef
宏;这是囤积这种普通和非宏观标识符的合理惩罚,但是繁琐而其他一些代码实际上可能需要Win32功能; - 只是接受它作为一个悲伤的生活事实,并避免所有相关的Win32 API名称;如果您使用Qt并遵循其命名约定,它应该很容易,因为Qt函数使用lowerCamelCase(而不是Win32 UpperCamelCase);
- 在你的标题中明确地直接包括
windows.h
(可能在#ifdef _WIN32
下);这将确保您的标识符将在所有实例中被宏替换,因此即使编译器实际编译具有不同名称的函数,一切都将正常工作;适用于独立项目,不适合图书馆。 (感谢@Jonathan Potter建议这个)
另一答案
您可以不关心这个问题,虽然您的方法名称将与Windows API相同,但系统不会混合它们(只需在定义/调用的位置统一Unicode)。如果你直接打电话给ChangeMenu()
,你会打电话给winapi,如果
foo f;
f.ChangeMenu();
要么
foo::ChangeMenu();
(静态)
你会打电话给你的方法。
如果你想禁用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
(看起来很乏味。)
以上是关于包含winuser.h时出错。它将ChangeMenu定义为ChangeMenuW或ChangeMenuA的主要内容,如果未能解决你的问题,请参考以下文章