你无法阻止Visual Studio内置的资源编辑器这样做。每当你使用资源编辑器(即GUI)对资源文件中的项目进行更改时,它都会重新生成资源文件的代码。这将覆盖对资源文件进行的各种手动调整,包括用文字替换符号常量和/或算术、删除有条件定义的代码块、破坏仔细的手动格式等。因此,手动编辑资源文件不是一个好主意。
如果你需要能够对资源文件进行手动编辑而不被资源编辑器覆盖,那么你可以通过向项目添加第二个资源文件来实现。按照惯例,这个文件应该有一个.rc2
扩展名。Visual Studio的资源编辑器永远不会直接编辑这些资源,这意味着所有的编辑必须手动完成。但是一旦你正确设置了它,你放置在那里的所有资源仍然会链接到你的二进制文件中,使最终结果等效。
这几乎是获得合理版本控制的唯一方法,我在自己的项目中使用它。例如:
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif
#include "Version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_MYPROJ_MAJOR,VERSION_MYPROJ_MINOR,VERSION_MYPROJ_REVISION,0
PRODUCTVERSION VERSION_MYPROJ_MAJOR,VERSION_MYPROJ_MINOR,VERSION_MYPROJ_REVISION,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Cody Gray"
VALUE "FileDescription", "The World's Greatest Application"
VALUE "FileVersion", VERSION_MYPROJ_FULL
VALUE "InternalName", "MyProj"
VALUE "LegalCopyright", "Copyrights are for suckers!"
VALUE "OriginalFilename", "MyProj.exe"
VALUE "ProductName", "MyProj"
VALUE "ProductVersion", VERSION_MYPROJ_FULL
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
你也可以在这里放置其他资源。例如,在我现在正在开发的一个应用程序中,我有一个对话框资源,我只想将其链接到“调试”构建中(它是用于配置内部调试相关选项的)。我尝试使用#ifdef DEBUG
包装对话框的定义,但资源编辑器每次运行时都会剥离整个块,所以这是不可行的。相反,我将对话框的定义移动到了我的.rc2
文件中,并将其保持在#ifdef
中。我失去了使用资源编辑器编辑它的能力,但我并不太在意,因为在我需要进行更改的罕见情况下,我可以手动快速地进行编辑。至少它不会被自动剥离。
最后一个关键是让这个.rc2
文件通过资源编辑器编译并链接到您的二进制文件中。为此,您需要编辑您的主资源文件(.rc
),但这个更改将被保留。您要编辑的部分是TEXTINCLUDE
资源。在我的.rc
文件中,该部分看起来像这样:
1 TEXTINCLUDE
BEGIN
"Resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""TargetVer.h""\r\n"
"#endif\r\n"
"#include ""AfxRes.h""\r\n"
"#include ""VerRsrc.h""\r\n"
"#include ""Version.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"LANGUAGE 9, 1\r\n"
"#include ""MyProj.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""AfxRes.rc"" // standard components\r\n"
"#endif\r\n"
"\0"
END
#endif
重要的部分在于在第三个
TEXTINCLUDE
段中包含了
MyProj.rc2
。无论何时资源编译器运行,此处的任何文本都会直接转储到资源文件中,因此在您的资源文件末尾,您将会看到一个熟悉的自动生成的部分,例如:
#ifndef APSTUDIO_INVOKED
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#include "MyProj.rc2"
#include "AfxRes.rc"
#endif
#endif
值得一提的是,如果你无法从我的示例中搭配起来如何操作的话,Visual Studio 中的 MFC 项目模板可以自动为您完成此操作,如 这篇技术说明 所述。