共用方式為


TN035: 使用 Visual C++ 的多個資源檔和標頭檔

注意事項注意事項

由於它第一次線上文件中包含尚未更新下列技術提示。如此一來,某些程序和主題可能已經過期或不正確。如需最新資訊,建議您先搜尋線上文件索引中有興趣的主題。

這張便箋說明 Visual C++ 資源編輯器支援多個資源檔的方式,並於同一個共用的標頭檔的專案或跨多個專案,以及如何可以讓您的支援共用。 這張便箋回答下列問題:

  • 何時您可能想要分割成多個資源檔及/或標頭檔的專案以及如何進行,所以?

  • 您要如何共用常見的標頭。H 檔案中兩個之間。RC 檔案嗎?

  • 您要如何分成多個將專案資源。RC 檔案嗎?

  • 如何您 (和工具) 管理組建之間的相依性。RC。CPP,和。H 檔案嗎?

您應該注意如果您將額外的資源檔加入專案時,類別精靈將不能識別加入的檔案中的資源。

這個註解的結構,如下所示回答上述問題:

  • Overview of How Visual C++ Manages Resource Files and Header Files提供如何設定包括 [資源] 命令,Visual C++ 可讓您使用多個資源檔和標頭檔,在同一個專案的概觀。

  • Analysis of AppWizard-created .RC and .H Files討論使用 AppWizard 自建應用程式的多個資源和標頭檔。 這些檔案做為額外的資源檔和標頭檔,您可能想要新增至您的專案適合。

  • Including Additional Header Files說明您可能會想要包含多個標頭檔,並提供如何執行這項操作的詳細資料。

  • Sharing a Header File Between Two .RC Files顯示您可以共用多重之間的一個標頭檔的方式。在不同的專案,或可能是在同一個專案中的 RC 檔案。

  • Using Multiple Resource Files in the Same Project說明您可以分割成多個專案。RC 檔案,並提供如何執行這項操作的詳細資料。

  • Enforcement of Non-Editable Visual C++ Files說明如何讓確定 Visual C++ 無法編輯且會不小心地重新格式化自訂的資源。

  • Managing Symbols Shared by Multiple Visual C++-Edited .RC Files說明如何在多個共用相同的符號。RC 檔,以及如何避免指派重複的 ID 數字的值。

  • Managing Dependencies Between .RC, .CPP, and .H Files說明如何 Visual C++ 可以避免不必要的重新編譯。CPP 檔案具有相依性資源的符號檔。

  • How Visual C++ Manages Set Includes Information提供如何 Visual C++ 會追蹤的倍數 (巢狀結構) 的技術詳細資料。RC 檔,並會藉由 include'd # 的多個標頭檔。RC 檔案。

概觀如何 Visual C++ 會管理資源檔和標頭檔

Visual C++ 會將 single 管理。RC 資源檔及其相關。H 標頭檔,當做組緊密結合的檔案。 當您編輯並儲存中的資源。RC 檔,您間接編輯並儲存在對應的符號。H 檔案中。 雖然您可以開啟並編輯多個。一次 (使用 Visual C++ MDI 使用者介面) 的任何給定的 RC 檔案。間接編輯正好與其中一個對應的標頭檔的 RC 檔案。

符號標頭檔

根據預設,Visual C++ 永遠命名對應的標頭檔資源。H,不論名稱的資源檔 (例如,MYAPP。RC)。 使用資源包含 指令從 檢視 功能表 Visual C++ 中的,您可以藉由更新的符號標頭檔的檔案中變更這個標頭檔名稱 集合包含對話方塊。

唯讀符號指示詞

雖然 Visual C++ 只能編輯一個標頭檔,任何給定的。RC 檔,Visual C++ 支援額外的讀寫標頭檔中所定義的符號參考。 使用資源包含 指令從 檢視功能表在 Visual C++ 中,您可以指定其他的唯讀標頭檔的任何數字為唯讀符號指示詞。 "唯讀"限制指的是當您將加入新的資源中。RC 檔,您可以使用唯讀的標頭檔中 ; 中所定義的符號 但如果您刪除資源時,該符號仍保留已定義在唯讀的標頭檔中。 您無法變更指派給唯讀符號的數字值。

編譯時期指示詞

Visual C++ 會在一個地方,也支援資源檔中,巢狀的結構。另 include'd # RC 檔案。 編輯時指定。使用 Visual C++ 中,# include'd 檔案中的任何資源的 RC 檔不會顯示。 但當您編譯。RC 檔,也會編譯 # include'd 檔案。 使用資源包含 指令從 檢視功能表 Visual C++ 中的,您可以指定任意數量的 # include'd。RC 檔案儲存為編譯時期指示詞。

會發生什麼事的附註如果您讀到 Visual C++。使用 # include 包含的 RC 檔案的另一個。RC 檔是做為編譯時期指示詞所指定。 當您將 Visual C++ 時,可能會發生這種情況。您已經被先前維護以手動方式使用文字編輯器的 RC 檔案。 當 Visual C++ 會讀取 include'd #。RC 檔,它會合併 # include'd 資源到父代。RC 檔案。 當您儲存父代。RC 檔,# include 陳述式中,事實上,都會被取代的 # include'd 資源。 如果不想使用這項合併發生,您應該移除 # 包含從父代的陳述式。RC 檔先前要讀入 Visual C++; 然後使用 Visual C++ 中,新增回相同 # include 陳述式做為編譯時期指示詞。

Visual C++ 會將儲存在。RC 檔案三種集合包含上述 # 中的資訊 (符號標頭檔、 唯讀符號指示詞,並產生編譯時期指示詞) 包含指示詞 TEXTINCLUDE 資源中。 TEXTINCLUDE 資源,您通常不需要應付,實作的細節將會說明如何 Visual C++ 會管理設定包含了資訊。

即 AppWizard 自建的分析。RC 和。H 檔案

檢查 AppWizard 產生的應用程式程式碼提供深入 Visual C++ 管理多個資源檔和標頭檔的方式。 檢查下面程式碼區段是來自所產生的 [使用預設的選項即 AppWizard MYAPP 應用程式。

即 AppWizard 自建應用程式使用多個資源檔和多個標頭檔,如圖所示的合併彙算:

   RESOURCE.H     AFXRES.H                    
          \       /                              
           \     /                                
          MYAPP.RC                               
              |                                
              |                              
        RES\MYAPP.RC2  
        AFXRES.RC                   
        AFXPRINT.RC                 

您可以檢視這些使用 Visual C++ 檔案/組準則包含指令的多個檔案關聯。

  • MYAPP。RC
    您可以編輯使用 Visual C++ 應用程式資源檔。

資源。H 是應用程式專屬的標頭檔。 它永遠被命名的資源。H AppWizard 一致以預設的 Visual C++ 所命名的標頭檔。 使用 # include 包含這個標頭檔是第一個陳述式,在資源檔 (MYAPP。RC):

//Microsoft Visual C++ generated resource script
//
#include "resource.h"
  • RES\MYAPP。RC2
    包含 Visual C++ 將不會編輯,但將會包含在最終編譯的資源。EXE 檔案。 即 AppWizard 建立根據預設,沒有這類資源,因為 Visual C++ 可以編輯所有標準的資源,包括版本資源 (此版本中的新功能)。 如果您想要對這個檔案加入您自己的自訂格式化的資源即 AppWizard 會產生空的檔案。

如果您使用自訂格式的資源時,您可以將它們加入 RES\MYAPP。RC2 使用 Visual C++ 的文字編輯器進行編輯。

AFXRES。RC 和 AFXPRINT。RC 包含標準架構的特定功能所需的資源。 就像 RES\MYAPP。RC2,這兩個架構所提供的資源檔是 # include'd MYAPP 結尾處。RC,而且它們詳列於對話方塊的 [集合包含編譯時期指示詞。 因此,您無法直接檢視或編輯 MYAPP 時編輯這些架構資源。RC Visual C++ 中,但它們會編譯成應用程式的二進位檔。RES 檔案,而且最後。EXE 檔案。 如需標準的架構資源,包括程序來修改它們,請參閱技術注意事項 23

AFXRES。H 定義的標準符號,例如ID_FILE_NEW、 架構所使用,特別是用於 AFXRES。RC。 AFXRES。H 也使用 # include 包含的與使用許多。H,含有 WINDOWS 的子集。所需的 Visual C++,產生的 H。RC 檔案,以及 AFXRES。RC。 在 AFXRES 中所定義的符號。H 都會提供的因為您編輯應用程式資源檔 (MYAPP。RC)。 例如, ID_FILE_NEW用於 MYAPP 的開新檔案] 功能表項目。RC 的功能表資源。 您不能變更或刪除這些架構所定義的符號。

包括額外的標頭檔

即 AppWizard 自建應用程式包含只有兩個標頭檔: 資源。H 和 AFXRES。H. 僅有資源。H 是特定的應用程式。 您可能需要將額外的讀寫標頭檔案包含在下列情況:

標頭檔由外部來源,或您想要共用的各項多個專案或同一個專案的多個部分的標頭檔。

在標頭檔案的格式和註解您不想要變更,或將檔案儲存時,篩選出的 Visual C++。 例如,也許您想要保留 # 定義的使用符號的算術運算,例如:

#define RED 0
#define BLUE 1
#define GREEN 2
#define ID_COLOR_BUTTON 1001
#define ID_RED_BUTTON (ID_COLOR_BUTTON + RED)
#define ID_BLUE_BUTTON (ID_COLOR_BUTTON + BLUE)
#define ID_GREEN_BUTTON (ID_COLOR_BUTTON + GREEN)

您可以加入額外的讀寫標頭檔,只要使用資源包含的 # include 陳述式做為第二個唯讀符號指示詞,請按照所指定的命令:

#include "afxres.h"
#include "second.h"

新的檔案關聯性圖表現在看起來應該像這樣:

                   AFXRES.H       
    RESOURCE.H     SECOND.H                    
          \       /                              
           \     /                                
          MYAPP.RC   
              |                                
              |                              
        RES\MYAPP.RC2  
        AFXRES.RC                   
        AFXPRINT.RC                 

共用的兩個之間的標頭檔。RC 檔案

若要共用的兩個之間的標頭檔。在不同的專案,或可能是同一個專案中的 RC 檔案。 若要這麼做,只需套用上述兩者的唯讀] 指示詞技巧。RC 檔案。 在這種情況下,這兩個。適用於不同的應用程式的 RC 檔案 (不同的專案),結果以如下圖所示:

     RESOURCE.H   AFXRES.H   RESOURCE.H  
    (for MYAPP1)  SECOND.H   (for MYAPP2)             
          \       /     \       /           
           \     /       \     /             
          MYAPP1.RC      MYAPP2.RC                 
           /    \        /     \                   
          /      \      /       \            
RES\MYAPP1.RC2  AFXRES.RC     RES\MYAPP2.RC2              
                AFXPRINT.RC                 

大小寫,第二個標頭檔由兩個共用的位置。下面討論中同一個應用程式 (專案) 的 RC 檔案。

使用相同專案中的多個資源檔

Visual C++ 及資源編譯器支援多種。RC 檔案透過 # 相同專案中的包含的其中之一。在另一個的 RC 檔案。 允許多個巢狀結構。 因而較受到分成多個分割您的專案資源。RC 檔案:

  • 很容易管理大量的多個專案小組成員間的資源,如果您將資源分成多個。RC 檔案。 如果您使用原始檔控制的管理套件的簽出檔案,並簽入變更時,分成多個分割的資源。RC 檔案會提供您更精細地控制管理對資源的變更。

  • 如果您想要使用前置處理器指示詞,例如 # ifdef,# endif 和 # 定義,部分的資源,而您必須將它們隔離在唯讀就編譯資源編譯器的資源。

  • 元件。RC 檔案仍然可以載入和儲存 Visual C++ 的速度比一個複合稿。RC 檔案。

  • 如果您想要維護資源,但人們可讀取的表單中的文字編輯器,您應該將它保存在。有別於一個 Visual C++ 編輯 RC 檔案。

  • 如果您需要保留二進位或文字的表單,則 [解譯由另一個的特定的資料編輯器的使用者定義的資源,然後您應該隨時在不同的。所以 Visual C++ 不會變更以十六進位的資料格式的 RC 檔案。 。MFC 進階概念的範例中的 WAV (聲音) 檔案資源 SPEAKN 是一個極佳範例。

您可以 # 包括第二個。在對話方塊中的集合包含編譯時期指示詞的 RC:

#include "res\myapp.rc2"  // non-Visual C++ edited resources
#include "second.rc"  // THE SECOND .RC FILE

#include "afxres.rc"  // Standard components
#include "afxprint.rc"  // printing/print preview resources

結果是以如下圖所示:

   RESOURCE.H     AFXRES.H                    
          \       /                              
           \     /                                
          MYAPP.RC
              |                                
              |                              
        RES\MYAPP.RC2
        SECOND.RC  
        AFXRES.RC                   
        AFXPRINT.RC                 

使用編譯時期指示詞,您可以分成多個組織您的 Visual C++ 可編輯和不可編輯資源。RC 檔,其中 「 主要 」 MYAPP。RC 不執行任何動作,但使用 # include 包含另。RC 檔案。 如果您使用 Visual C++ 專案。MAK 檔案,那麼您應該會包含 「 主要 」。在專案中的 RC 檔案,以便與您的應用程式編譯 # include'd 的所有資源。

強制執行不可編輯的 Visual C++ 檔案

即 AppWizard 自建的 RES\MYAPP。RC2 檔案會包含您所做的資源檔的範例要不小心讀入 Visual C++,並再將其寫回喪失格式設定資訊。 為了防護措施,請將下列幾行置於 RES\MYAPP 開頭。RC2 檔案:

#ifdef APSTUDIO_INVOKED
    #error this file is not editable by Visual C++
#endif //APSTUDIO_INVOKED

Visual C++ 編譯的時機。它會定義 RC 檔, APSTUDIO_INVOKEDRC_INVOKED。 如果 AppWizard 建立檔案結構已損毀,Visual C++ 會讀取上面這行 「 # 錯誤 」 報告嚴重錯誤,並中止讀取。RC 檔案。

管理由多個 Visual C++ 編輯共用的符號。RC 檔案

當您切割分成多個資源,就會發生兩個問題。您想要在 Visual C++ 中,請編輯個別的 RC 檔案:

  • 您可以在多個共用相同的符號。RC 檔案。

  • 您需要協助 Visual C++,避免將相同的 ID 數字的值指派給不同資源 (符號)。

下圖說明的組織。RC 和。H 檔案處理的第一個問題:

              MYAPP.RC
             /         \
            /           \
MYSTRS.H   / MYSHARED.H  \  MYMENUS.H
     \    /    /      \   \    \
      \  /    /        \   \    \
   MYSTRS.RC           MYMENUS.RC

在這個範例中,字串資源會存放在一個資源檔,MYSTRS。RC 和功能表都位在另一個,MYMENUS。RC。 某些符號,例如,命令,可能需要兩個檔案之間共用。 例如,ID_TOOLS_SPELL 可能是功能表命令 ID,魔法中之項目的 [工具] 功能表中。 此外,也可能是由架構應用程式的主視窗的狀態列中顯示的命令提示字元的字串識別碼。

ID_TOOLS_SPELL 符號會保留在共用的標頭檔中,MYSHARED。H. 您維護這個共用的標頭檔以手動方式使用文字編輯器。 Visual C++ 不會直接編輯它。 在兩個資源中的 MYSTRS 檔案。RC 和 MYMENUS。您指定 # RC,包括 MYSHARED。H 中針對 MYAPP 的唯讀屬性指示詞。RC,使用資源包含命令,如稍早所述。

會比較方便預測符號,您會共用之前,您嘗試使用它來識別任何資源。 將符號新增到共用的標頭檔,而且如果您還未 # include'd 共用標頭檔的唯讀] 指示詞中。RC 檔案時,請先使用的符號。 如果您沒有預期共用的符號,如此一來,那麼您必須以手動方式 (使用文字編輯器) 移動 # define 陳述式的符號,例如 MYMENUS。H,MYSHARED。MYSTRS 在使用之前,先 H。RC。

當您管理多重的符號。RC 檔,您也必須協助 Visual C++,避免將相同的 ID 數字的值指派給不同資源 (符號)。 任何列。以累加方式 RC 檔,Visual C++ 會將識別碼指派每個四個 ID 網域中。 編輯工作階段之間 Visual C++ 會追蹤的它指派給每個網域中的符號標頭檔中的最後一個 ID。RC 檔案。 下面是 APS_NEXT 的值為何 (新) 空的。RC 檔:

#define _APS_NEXT_RESOURCE_VALUE  101
#define _APS_NEXT_COMMAND_VALUE   40001
#define _APS_NEXT_CONTROL_VALUE   1000
#define _APS_NEXT_SYMED_VALUE     101

_APS_NEXT_RESOURCE_VALUE 就是下一步將用於對話方塊資源、 功能表資源等的符號值。 資源符號值的有效範圍是 1 到 0x6FFF。

_APS_NEXT_COMMAND_VALUE 是一個命令的識別資訊適用於下一個符號值。 命令的符號值的有效範圍是 0x8000 到 0xDFFF。

_APS_NEXT_CONTROL_VALUE 是用於對話方塊控制項的下一個符號值。 對話方塊控制項的符號值的有效範圍是 8 到 0xDFFF。

_APS_NEXT_SYMED_VALUE 就是下一步] 以手動方式將指定的符號瀏覽器中使用 [新增] 命令的符號值就會發出的符號值。

值略高值的最小的合法值的時機的 visual C++ 開頭建立新的。RC 檔案。 即 AppWizard 也會初始化這些值變得更適用於 MFC 應用程式。 如需有關 ID 值範圍的詳細資訊,請參閱技術的附註 20

現在每次您建立新的資源檔,即使是在同一個專案時,Visual C++ 會定義相同 _APS_NEXT_ 的值。 這表示如果新增,請說出,多個對話方塊中兩個不同。RC 檔,它是極有可能同一個 # define 值將被指派到不同的對話方塊。 例如,IDD_MY_DLG1 第一次。RC 檔可能會指派相同數字,101,為在第二個 IDD_MY_DLG2。RC 檔案。

若要避免這個問題,您應該為每個 Id 的四個網域中之個別保留不同的數字範圍。RC 檔案。 執行這項操作,手動更新 _APS_NEXT 中的每一個值。RC 檔案before開始新增資源。 比方說,如果第一個。RC 檔案使用預設的 _APS_NEXT ,您可能想要指派下列值 _APS_NEXT 第二個值。RC 檔:

#define _APS_NEXT_RESOURCE_VALUE  2000
#define _APS_NEXT_COMMAND_VALUE   42000
#define _APS_NEXT_CONTROL_VALUE   2000
#define _APS_NEXT_SYMED_VALUE     2000

當然,平時,是 Visual C++ 將會指派這麼多的 Id,第一次。數字的值會開始重疊那些保留給第二個的 RC 檔案。RC 檔案。 這樣不是這樣,您應該保留夠大的範圍。

管理之間的相依性。RC。CPP,和。H 檔案

當 Visual C++ 會將儲存。RC 檔,它也會儲存符號變更為相對應的資源。H 檔案中。 任何程式。CPP 檔案中的資源,請參閱。RC 檔必須 # 包含資源。H 檔案中的,通常是與在您專案的主要標頭檔。 這會導致非預期的副作用因掃瞄原始程式檔的標頭的相依性的開發環境內部的專案管理。 每當您在 Visual C++ 中,新增新的符號所有。使用 # include 包含資源的 CPP 檔。H,就需要重新編譯。

Visual C++ 中,卻會規避上資源的相依性。藉由為該資源的第一行包含下列註解 H。H 檔案中:

//{{NO_DEPENDENCIES}}

在開發環境會解譯這個註解,以忽略對資源的變更。H 也依賴。CPP 檔案將不需要重新編譯。

Visual C++ 永遠會加入 //{{NO_DEPENDENCIES}} 行加上註解。它會將檔案儲存時的 RC 檔案。 在某些情況下,資源上的組建相依性,進而規避。H,可能會導致在連結階段未偵測到的執行階段錯誤。 比方說,如果您使用符號瀏覽器來變更數字的值指派給資源的符號時,資源將不正確地找到及載入於應用程式執行階段 if。指的資源的 CPP 檔不會重新編譯。 請重新在這種情況下,您應該明確地編譯任何。您知道的 CPP 檔會受到資源符號的變更。H 或 select 全部重建。 如果您有經常變更某一組資源的符號值的需求,您可能會發現它來說更為方便且更安全,若要分割成個別的唯讀欄位名稱檔案,這些符號上面的節中所描述包括額外的標頭檔。

如何管理 Visual C++ 組初衷所設計

如上文所述,集合包含指令的 [檔案] 功能表可讓您指定三種類型的資訊:

  • 符號標頭檔

  • 唯讀符號指示詞

  • 編譯時期指示詞

以下說明 Visual C++ 會在這項資訊的維護。RC 檔案。 您不需要此資訊來使用 Visual C++ 中,而它可能會增加您了解,以便您能更充滿信心地將該集合包含的功能。

每個上述三種集合包含的資訊儲存在。以兩種形式的 RC 檔: (1) 為 # 包含或其他指示詞解譯,資源編譯器,以及 (2) 特殊 TEXTINCLUDE 資源解譯只能由 Visual C++。

TEXTINCLUDE 資源的目的是要安全地將設定包含資訊儲存中的表單,則 Visual C++ 中,隨時可以呈現集合包含對話方塊。 TEXTINCLUDE 是資源類型由 Visual C++ 所定義。 Visual C++ 會辨識具有資源識別碼 1、 2 及 3 三個特定 TEXTINCLUDE 資源:

TEXTINCLUDE 資源 ID

集合包含的資訊類型

1

符號標頭檔

2

唯讀符號指示詞

3

編譯時期指示詞

預設 MYAPP 說明每種三種類型的集合包含的資訊。RC 和資源。H 建立的檔案即 AppWizard,如下所述。 額外的 \ 0 和"",BEGIN 和 END 區塊之間的語彙基元才能 RC 語法所分別指定零個已經終止的字串和雙引號字元。

符號標頭檔

資源編譯器所解譯的符號標頭檔資訊的格式是 # include 包含陳述式:

#include "resource.h"

相對應的 TEXTINCLUDE 資源為:

1 TEXTINCLUDE DISCARDABLE
BEGIN
   #resource.h\0"
END

唯讀符號指示詞

唯讀符號指示詞會包含在 MYAPP 頂端項目。資源編譯器所解譯的下列形式的 RC:

#include "afxres.h"

相對應的 TEXTINCLUDE 資源為:

2 TEXTINCLUDE DISCARDABLE
BEGIN
   "#include ""afxres.h""\r\n"
   "\0"
END

編譯時期指示詞

編譯時期指示詞是包含在 MYAPP 的結尾。資源編譯器所解譯的下列形式的 RC:

#ifndef APSTUDIO_INVOKED
///////////////////////
//
// From TEXTINCLUDE 3
//
#include "res\myapp.rc2"  // non-Visual C++ edited resources

#include "afxres.rc"  // Standard components
#include "afxprint.rc"  // printing/print preview resources
#endif  // not APSTUDIO_INVOKED

#Ifndef APSTUDIO_INVOKED 指示詞會指示要跳過編譯時期指示詞的 Visual C++。

相對應的 TEXTINCLUDE 資源為:

3 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""res\myapp.rc2""  // non-Visual C++ edited resources\r\n"
"\r\n"
"#include ""afxres.rc""  // Standard components\r\n"
"#include ""afxprint.rc""  // printing/print preview resources\r\n"
"\0"
END

請參閱

其他資源

技術的備忘稿編號

依類別的技術注意事項