我有一个代码库,其中MFC消息映射以这种形式编写:

BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
    ON_COMMAND(CID_ButtonAction, OnButtonAction)
END_MESSAGE_MAP()

这在MSVC中可以正常编译。当我想在Clang中编译相同的代码时,出现call to non-static member function without an object argument错误,因为OnButtonAction不是用于指定成员函数指针的正确形式。该代码可以轻松修复:
    ON_COMMAND(CID_ButtonAction, &SomeForm::OnButtonAction)

或者我们可以使用BEGIN_MESSAGE_MAP()宏中的ThisClass typedef:
    ON_COMMAND(CID_ButtonAction, &ThisClass::OnButtonAction)

到目前为止,很好...唯一的问题是我在许多单独的文件中有数百个这样的消息映射条目。有什么工具可以解决此问题?一些模糊的Visual Studio魔术吗?还是可以在这里通过正则表达式使用替换?

最佳答案

最后,我想出了我从MinGW运行的sed命令:

sed -b -i -re '/^BEGIN_MESSAGE_MAP/,/^END_MESSAGE_MAP/{/(BEGIN_MESSAGE_MAP|\/\/)/!s/(.*),\s{0,}/\1, \&ThisClass::/;}' *.cpp

要解释它的作用:
  • -b将文件视为二进制文件(可选,以在Windows中保留行尾)*
  • -re支持扩展的正则表达式
  • -i就地替换
  • /^BEGIN_MESSAGE_MAP/,/^END_MESSAGE_MAP/仅匹配这两个字符串之间的文本
  • /!s替换命令,它将忽略您之前匹配的任何内容
  • /\(BEGIN_MESSAGE_MAP\|\/\/\)/匹配要忽略的行开头(消息映射的第一行或注释掉的行)
  • /(.*),\s{0,}/\1, \&ThisClass::/将一行中的最后一个逗号替换为, &ThisClass::后面的0+空格

  • 输入样例:
    BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
        ON_COMMAND(CID_ButtonAction, OnButtonAction)
        ON_NOTIFY_EX(CID_Notify, 0, OnNotify)
    END_MESSAGE_MAP()
    

    输出:
    BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
        ON_COMMAND(CID_ButtonAction, &ThisClass::OnButtonAction)
        ON_NOTIFY_EX(CID_Notify, 0, &ThisClass::OnNotify)
    END_MESSAGE_MAP()
    

    效果很好,对于大约500个文件,我只需要在已经使用了类方法成员资格表示法的情况下进行两次手动调整。可以调整sed命令以解决此问题(例如,检查行中的最后一个逗号后面是否有&),但这对我而言已经足够好了。

    编辑-添加了-b选项。这会将文件视为二进制文件。在Windows上,这可以防止用Unix字符替换原始的换行符-如果未启用此选项,则任何处理的文件的git diff看起来都将删除并重新添加整个文件。

    08-04 13:07