問題:
我試圖將一個頭文件包含在工程的資源文件中。為此在.rc文件中添加了如下一行代碼:
#include "MyFile.h"
雖然運行沒有問題,但是每次在Visual Studio中打開資源時,它都把這一行代碼刪除掉了。我之所以要包含這個頭文件是因為想使用第三方定義的菜單項ID號。
解答:
討厭的IDE環境有時總是以刁難你的代碼為樂趣,你說是不是?請不要怕,莫高一尺、道高一丈,對於這種問題總是有辦法解決它的。在打開.rc文件的時候,App Studio(Visual Studio資源編輯器的老名稱)自己要對這個文件作一些處理。在存儲文件時,它並不重新產生這個文件並另存。特別是App Studio喜歡有一個而且只有一個頭文件來包含所定義的全部資源符號。通常,這個文件叫resource.h,但是你可以通過在MyApp上單擊右鍵並選擇“Resource Includes”(資源包含)來改變這個文件的名字。當App Studio寫入資源文件的時候,它產生一個而且只產生一個#include語句。任何用手東方式敲入的附加的#include都會像前面那樣被刪掉。
圖八 對話框邊空(Dialog Margins)
是否能對它進行處理呢?當然可以。你可能注意到了App Studio將自己專用的信息嵌入到資源文件中。例如,你可能創建了一個帶邊空的對話框(如圖八)。你是否知道App Studio將邊空尺寸存在哪了嗎?並沒有存在對話框的語句中,因為它沒有MARGINS選項。其實,App Studio將這些信息存在了一個特殊的段中:
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MYDIALOG, DIALOG
BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 502
TOPMARGIN, 8
BOTTOMMARGIN, 273
END
END
#endif // APSTUDIO_INVOKED
//
APSTUDIO_INVOKED是在當App Studio 處理.rc文件時定義的,而不是在通常資源編譯器編譯它的時候定義的。資源編譯器根本就不會明白“GUIDELINES”的意思;只有App Studio才會明白。為什麼#include的問題會牽扯到“GUIDELINES”呢?因為這個問題的答案依賴於APSTUDIO_INVOKED。你要做的全部工作只是將要包含的文件一下面的形式#include就可以了:
//
#ifndef APSTUDIO_INVOKED // if NOT defined
#include "MyOtherHeader.h"
#endif
//
App Studio在運行時,因為定義了APSTUDIO_INVOKED,所以它忽略掉你的#include。但當沒有定義APSTUDIO_INVOKED時,RC編譯器就會編譯你#include的文件。此外——也是最重要的一點——App Studio在它存儲你的.rc文件時會保護你的#include語句。它識別: “這裡的這個#ifndef塊不是我的,所以我想最好還是不刪除它...”
如果你的好奇心想知道為什麼App Studio總是要刪除開始那樣添加的代碼——那是另外一個故事! 我們下次再講吧。