包含winuser.h时出错。它将ChangeMenu定义为ChangeMenuW或ChangeMenuA

时间:2018-12-17 20:56:55

标签: windows visual-studio winapi visual-studio-2017

在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”

2 个答案:

答案 0 :(得分:2)

几乎所有处理字符串的Windows API实际上都是一个解析为A或W版本的宏。无法解决,您可以:

  • 避免包含def send_img(host, port, file_name, num_pkt): try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setblocking(0) sock.settimeout(60) client_addr = (host, port) # send the file name while num_pkt > 0: img_part = requested_file.read(BUF_SIZE + 8) sock.sendto(img_part + seq_num) num_pkt -= 1 ,但正如您所注意到的,它会蔓延;
  • 在定义/使用函数之前粗略windows.h宏;这是such积此类正常且非宏外观的标识符的适当惩罚,但它很繁琐,并且某些其他代码实际上可能需要Win32函数;
  • 将其视为生活中的不幸事实,并避免使用所有相关的Win32 API名称;如果您使用Qt并遵循其命名约定,则应该很容易,因为Qt函数使用lowerCamelCase(与Win32 UpperCamelCase相对);
  • 在标头中直接直接包含#undef(可能在windows.h下);这将确保您的标识符在所有实例中均被宏替换,因此即使编译器实际上将编译具有不同名称的函数,一切也将正常工作;适合独立项目,不适合。 (感谢 @Jonathan Potter 提出的建议)

答案 1 :(得分:0)

您可能不会在意这个问题,尽管您的方法名称将与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

(看起来很乏味。)