2

作为更大项目(Mozilla Firefox 的 ff activex 插件)的一部分,有以下代码片段:

if (CombineRgn(hrgnClip, hrgnClip, hRGN, RGN_AND) != ERROR)
{
        ::InvalidateRgn(m_hWndParent, hrgnClip, fErase);
}

当我在 VS2012 中构建时,我得到“错误 C2065:'ERROR':未声明的标识符”错误在wingdi.h 中定义如下:

...
/* Region Flags */
#define ERROR               0  // it wont build when this macro is used
#define NULLREGION          1  // it builds when this macro is used
#define SIMPLEREGION        2
#define COMPLEXREGION       3
#define RGN_ERROR ERROR
...

奇怪的是,如果我在上面的if语句中用 NULLREGION 或 SIMPLEREGION (它们是同一文件中的宏,仅在有问题的行下方两行)替换 ERROR(只是为了查看它是否构建正常),则代码构建正常。当我使用 ERROR 时,代码不会构建。上面定义的 ERROR 宏是否有可能被某个关键字或另一个宏或 Visual Studio 中的某个宏所掩盖?

4

1 回答 1

3

这里的问题是 ERROR 实际上出现在编译错误消息中。这不应该发生,预处理器应该用 0 代替它。

因此,在您在 windows.h 之后#included 的 .h 文件中的某个地方,一些程序员使用了 10 秒的快捷方式来解决宏名称冲突问题并写下:

  #undef ERROR

您需要找到该行并将其删除。这可能很困难,而且可能会给您带来维护上的麻烦,因为这是您不拥有的文件,并且将来很可能会更新,从而迫使您一遍又一遍地进行更改。另一种方法是自己重新定义它:

#define MYGDIERROR 0
...
if (CombineRgn(hrgnClip, hrgnClip, hRGN, RGN_AND) != MYGDIERROR)
//etc...

这仍然会给您带来维护问题,并要求您打赌 CombineRgn() 的返回值定义永远不会改变。这是一个非常安全的赌注,GDI 是一成不变的。

于 2013-05-31T08:34:48.750 回答