Поделиться через


TN035: Использование нескольких файлов ресурсов и файлов заголовков с помощью Visual C++

Замечание

Следующая техническая заметка не была обновлена, так как она была впервые включена в онлайн-документацию. В результате некоторые процедуры и темы могут быть устаревшими или неверными. Для получения последних сведений рекомендуется искать интересующую тему в индексе веб-документации.

В этом примечание описывается, как редактор ресурсов Visual C++ поддерживает несколько файлов ресурсов и файлов заголовков, общих в одном проекте или совместном использовании нескольких проектов, а также о том, как воспользоваться этой поддержкой. Эта заметка отвечает на следующие вопросы:

  • Когда может возникнуть необходимость разделить проект на несколько файлов ресурсов и/или файлов заголовков, и как это сделать

  • Как совместно использовать общий файл заголовка .H между двумя .RC файлами

  • Как разделить ресурсы проекта на несколько .RC файлов

  • Как вы и инструменты управляете зависимостями сборки между файлами .RC, .CPP и .H?

Следует помнить, что при добавлении дополнительного файла ресурсов в проект КлассWizard не распознает ресурсы в добавленном файле.

Это примечание структурировано для ответа на приведенные выше вопросы следующим образом:

  • Общие сведения о том, как Visual C++ управляет файлами ресурсов и файлами заголовков, содержит общие сведения о том, как команда "Набор ресурсов включает" в Visual C++ позволяет использовать несколько файлов ресурсов и файлов заголовков в одном проекте.

  • Анализ файлов, созданных AppWizard, .RC и .H рассматривает разнообразные файлы ресурсов и заголовков, используемые приложением AppWizard. Эти файлы служат хорошей моделью для дополнительных файлов ресурсов и файлов заголовков, которые может потребоваться добавить в проект.

  • Включение дополнительных файлов заголовков описывает, где может понадобиться включить несколько файлов заголовков и предоставляет подробные сведения о том, как это сделать.

  • Совместное использование файла заголовка между двумя .RC файлами показывает, как совместно использовать один файл заголовка между несколькими файлами в разных .RC проектах или, возможно, в одном проекте.

  • Использование нескольких файлов ресурсов в одном проекте описывает, где может потребоваться разбить проект на несколько .RC файлов и получить подробные сведения о том, как это сделать.

  • Обеспечение нередактируемости файлов Visual C++ описывает, как удостовериться, что Visual C++ не может редактировать и непреднамеренно переформатировать пользовательский ресурс.

  • Управление символами, общими для нескольких измененных файлов Visual C++.RC, описывает, как совместно использовать одни и те же символы в нескольких .RC файлах и как избежать назначения повторяющихся числовых значений идентификатора.

  • Управление зависимостями между .RCфайлами и .CPP.H файлами описывает, как Visual C++ позволяет избежать ненужных перекомпиляции .CPP файлов, зависящих от файлов символов ресурсов.

  • Как Visual C++ управляет информацией о включениях предоставляет технические детали о том, как Visual C++ отслеживает несколько вложенных .RC файлов и множество заголовочных файлов, включенных в .RC файл.

Общие сведения о том, как Visual C++ управляет файлами ресурсов и файлами заголовков

Visual C++ управляет одним .RC файлом ресурсов и соответствующим .H файлом заголовка в виде тесно связанной пары файлов. При редактировании и сохранении ресурсов в .RC файле вы косвенно редактируете и сохраняете символы в соответствующем .H файле. Хотя вы можете открывать и изменять несколько .RC файлов одновременно (с помощью пользовательского интерфейса MDI Visual C++), для любого конкретного .RC файла вы косвенно редактируете именно один соответствующий файл заголовка.

Диалоговое окно "Ресурс представления ресурсов"

Чтобы получить доступ к включениям ресурса, откройте обозреватель ресурсов, затем щелкните правой кнопкой на файле .RC и выберите включения ресурса.

Файл заголовка символов

По умолчанию Visual C++ всегда называет соответствующий заголовочный файл RESOURCE.H, независимо от имени файла ресурса (например, MYAPP.RC). Файл заголовка символов: раздел в диалоговом окне "Включает ресурсы" в Visual C++, позволяет изменить имя этого файла заголовка. Введите новое имя файла в поле редактирования раздела.

Замечание

Файлы ресурсов, не расположенные в том же каталоге, что и файл .RC, должны предварять относительный путь экранированным символом '\', чтобы их можно было правильно прочитать.

Директивы символов Read-Only

Хотя Visual C++ редактирует только один файл заголовка для любого заданного .RC файла, Visual C++ поддерживает ссылки на символы, определенные в дополнительных файлах заголовков только для чтения. Директивы символовRead-Only: раздел в диалоговом окне «Включения ресурсов» позволяет указать любое количество дополнительных файлов заголовков только для чтения в виде директив символов Read-Only. Ограничение только для чтения означает, что при добавлении нового ресурса в .RC файл можно использовать символ, определенный в файле заголовка только для чтения. Однако при удалении ресурса символ по-прежнему определяется в файле заголовка только для чтения. Нельзя изменить числовое значение, назначенное символу только для чтения.

Директивы Compile-Time

Visual C++ также поддерживает вложение файлов ресурсов, где один .RC файл входит в другой с помощью директивы #include . При изменении заданного .RC файла с помощью Visual C++все ресурсы в включенных файлах не отображаются. Но когда вы компилируете файл .RC, компилируются также и включенные файлы. ДирективыCompile-Time: в диалоговом окне "Включение ресурсов" можно указать любое количество .RC файлов для включения в качестве директив Compile-Time.

Обратите внимание, что происходит при чтении в Visual C++ .RC файла, включающего другой .RC файл, который не указан в качестве директивы Compile-Time. Эта ситуация может возникнуть при переносе в Visual C++ .RC файла, который вы ранее поддерживали вручную с помощью текстового редактора. Когда Visual C++ считывает включенный .RC файл, он объединяет включенные ресурсы в родительский .RC файл. При сохранении родительского .RC файла инструкция #include фактически будет заменена включенными ресурсами. Если вы не хотите, чтобы это слияние произошло, необходимо удалить #include инструкцию из родительского .RC файла перед его чтением в Visual C++. Затем с помощью Visual C++добавьте ту же #include инструкцию, что и директива Compile-Time.

Visual C++ сохраняет в .RC файле сведения, включенные в указанный выше набор (файл заголовка символов, директивы символов Read-Only и директивы Compile-Time) в директивах #includeи ресурсах TEXTINCLUDE. Ресурсы TEXTINCLUDE, являющиеся частью реализации и с которыми обычно не нужно иметь дело, описаны в статье Как Visual C++ управляет наборами, включая информацию.

Анализ созданных .RC и .H файлов AppWizard

Изучение кода приложения, созданного AppWizard, содержит сведения о том, как Visual C++ управляет несколькими файлами ресурсов и файлами заголовков. Приведенные ниже фрагменты кода относятся к приложению, созданному MYAPP AppWizard с помощью параметров по умолчанию.

Созданное приложение AppWizard использует несколько файлов ресурсов и несколько файлов заголовков, как показано на схеме ниже:

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

Эти связи с несколькими файлами можно просмотреть с помощью команды Visual C++ File/Set Includes.

MYAPP.RC
Файл ресурса приложения, который вы редактируете с помощью Visual C++.

RESOURCE.H — это файл заголовка для конкретного приложения. Оно всегда называется RESOURCE.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, эти два файла ресурсов, предоставляемые платформой, включены в конце MYAPP.RC и указаны в директивах Compile-Time в диалоговом окне "Включение набора". Таким образом, вы не просматриваете или редактируете эти ресурсы платформы при редактировании MYAPP.RC в Visual C++, но они компилируются в двоичный .RES файл приложения и окончательный .EXE файл. Дополнительные сведения о стандартных ресурсах платформы, включая процедуры их изменения, см. в техническом примечание 23.

AFXRES.H определяет стандартные символы, такие как ID_FILE_NEW, используемые платформой и специально используемые в AFXRES.RC. AFXRES.H также использует #include для включения WINRES.H, который содержит подмножество WINDOWS.H, необходимое для созданных файлов .RC Visual C++ и AFXRES.RC. Символы, определенные в AFXRES.H, доступны при редактировании файла ресурса приложения (MYAPP.RC). Например, ID_FILE_NEW используется для FileNew элемента меню в ресурсе MYAPP.RC меню файла. Вы не можете изменить или удалить эти символы, определенные платформой.

Включение дополнительных файлов заголовков

Созданное приложение AppWizard включает только два файла заголовка: RESOURCE.H и AFXRES.H. Только RESOURCE.H зависит от конкретного приложения. В следующих случаях может потребоваться включить дополнительные файлы заголовков только для чтения:

Файл заголовка предоставляется внешним источником или требуется предоставить общий доступ к файлу заголовка между несколькими проектами или несколькими частями одного проекта.

Файл заголовка имеет форматирование и примечания, которые не требуется, чтобы Visual C++ изменял или отфильтровывать при сохранении файла. Например, может быть, вы хотите сохранить #define, которые используют символьную арифметику, такие как:

#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)

Вы можете добавить дополнительные файлы заголовков, доступных только для чтения, используя команду Resource Includes, чтобы указать #include инструкцию в качестве второй директивы символов Read-Only, как в следующем примере:

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

Теперь новая схема связей файлов выглядит следующим образом:

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

Использование общего файла заголовка между двумя .RC файлами

Может потребоваться предоставить общий доступ к файлу заголовка между двумя .RC файлами, которые находятся в разных проектах или, возможно, в одном и том же проекте. Для этого примените метод директив Read-Only, описанный выше, к обоим .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 файлов в одном проекте с помощью #include директив, которые включают один .RC файл в другой. Допускается многократное вложение. Существуют различные причины разделения ресурсов проекта на несколько .RC файлов:

  • Проще управлять большим количеством ресурсов среди нескольких участников группы проектов, если разделить ресурсы на несколько .RC файлов. Если вы используете пакет управления версиями для проверки файлов и проверки изменений, разделение ресурсов на несколько .RC файлов дает более точное управление изменениями в ресурсах.

  • Если вы хотите использовать директивы препроцессора, такие как #ifdef, #endifи #defineдля частей ресурсов, необходимо изолировать их в ресурсах только для чтения, которые будут компилироваться компилятором ресурсов.

  • Файлы компонентов .RC загружают и сохраняются быстрее в Visual C++, чем один составной .RC файл.

  • Если вы хотите поддерживать ресурс в виде, доступном для чтения, с помощью текстового редактора, следует сохранить его в отдельном от файлов, редактируемых Visual C++, .RC файле.

  • Если необходимо сохранить определяемый пользователем ресурс в двоичном или текстовом формате, который интерпретируется другим специализированным редактором данных, его следует сохранить в отдельном .RC файле, чтобы Visual C++ не изменял формат на шестнадцатеричные данные. Ресурсы звуковых файлов .WAV в образце Расширенные концепции MFC SPEAKN являются хорошим примером.

В диалоговом окне "Включения набора" можно включить SECOND.RC в директивы Compile-Time:

#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

Используя директивы Compile-Time, вы можете упорядочить редактируемые и не редактируемые ресурсы Visual C++в несколько .RC файлов, где основное MYAPP.RC не делает ничего, кроме #include других .RC файлов. Если вы используете файл проекта .MAK Visual Studio C++, необходимо включить в проект основной .RC файл, чтобы все включенные ресурсы компилировались с приложением.

Принудительное применение не редактируемых файлов 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_INVOKED, и RC_INVOKED. Если структура файла, созданного с помощью AppWizard, повреждена и Visual C++ считывает приведённую выше строку #error, то она сообщает о фатальной ошибке и прекращает чтение файла .RC.

Управление символами, общими для нескольких измененных .RC файлов Visual C++.

При разбиение ресурсов на несколько .RC файлов, которые необходимо изменить отдельно в Visual C++, возникают две проблемы:

  • Возможно, вам потребуется предоставить общий доступ к одинаковым символам в нескольких .RC файлах.

  • Вам нужно помочь Visual C++ избежать назначения одинаковых числовых значений идентификатора отдельным ресурсам (символам).

На следующей схеме показана организация файлов .RC и .H, которые решают первую проблему.

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

В этом примере строковые ресурсы хранятся в одном файле ресурсов, MYSTRS.RCа меню хранятся в другом MYMENUS.RC. Некоторые символы, такие как команды, могут потребоваться для разделения между двумя файлами. Например, ID_TOOLS_SPELL может быть идентификатором команды меню для элемента "Проверка орфографии" в меню "Инструменты", а также строковым идентификатором командной подсказки, отображаемой платформой в строке состояния главного окна приложения.

Символ ID_TOOLS_SPELL хранится в общем файле заголовка. MYSHARED.H Этот общий файл заголовка сохраняется вручную с помощью текстового редактора; Visual C++ не изменяет его напрямую. В двух файлах ресурсов MYSTRS.RC и MYMENUS.RC вы указываете #include "MYSHARED.H" в директивах Read-Only для MYAPP.RC, используя команду Resource Includes, как описано ранее.

Наиболее удобно заранее предусмотреть символ, который вы будете использовать для идентификации какого-либо ресурса. Добавьте символ в общий файл заголовка и, если вы еще не включили общий файл заголовка в директивы Read-Only для .RC файла, сделайте это перед использованием символа. Если вы не ожидали совместного использования символа подобным образом, вам придется вручную (с помощью текстового редактора) переместить инструкцию #define для символа, скажем, из MYMENUS.H в MYSHARED.H перед его использованием в MYSTRS.RC.

При управлении символами в нескольких .RC файлах также необходимо помочь Visual C++ избежать назначения одинаковых числовых значений идентификатора отдельным ресурсам (символам). Для любого заданного .RC файла Visual C++ добавочно назначает идентификаторы в каждом из четырех доменов идентификаторов. Между сеансами редактирования Visual C++ отслеживает последний идентификатор, назначенный в каждом из доменов в файле заголовка символов для .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 — следующее значение символа, которое будет выдано вручную при назначении значения символа с помощью команды New в браузере символов.

Visual C++ начинается с немного более высоких значений, превышающих наименьшее допустимое значение при создании нового .RC файла. AppWizard также инициализирует эти значения в чем-то более подходящим для приложений MFC. Дополнительные сведения о диапазонах значений идентификаторов см. в техническом примечание 20.

Теперь каждый раз, когда вы создаете новый файл ресурсов, даже в одном проекте, Visual C++ определяет одни и те же _APS_NEXT_ значения. Это означает, что при добавлении нескольких диалоговых окон в двух разных файлах весьма вероятно, что одно и то же #define значение будет назначено разным .RC диалогам. Например, IDD_MY_DLG1 в первом .RC файле может быть назначено то же число, 101, что IDD_MY_DLG2 и во втором .RC файле.

Чтобы избежать этой проблемы, следует зарезервировать отдельный числовой диапазон для каждого из четырех доменов идентификаторов в соответствующих .RC файлах. Задайте диапазоны, вручную обновив _APS_NEXT значения в каждом из .RC файлов перед началом добавления ресурсов. Например, если первый .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++ назначит столько идентификаторов в первом .RC файле, что числовые значения начнут перекрываться с теми, которые зарезервированы для второго .RC файла. Вы должны зарезервировать достаточно большие диапазоны, чтобы это столкновение не произошло.

Управление зависимостями между .RC, .CPPи .H файлами

Когда Visual C++ сохраняет .RC файл, он также сохраняет изменения символов в соответствующем RESOURCE.H файле. Ваши .CPP файлы, которые ссылаются на ресурсы в .RC файле, должны использовать #include для включения RESOURCE.H файла, как правило, из основного заголовочного файла вашего проекта. Это включение приводит к нежелательному побочному эффекту из-за внутренней системы управления проектом в среде разработки, которая сканирует исходные файлы на наличие зависимостей заголовочных файлов. Каждый раз при добавлении нового символа в Visual C++все .CPP файлы с #include "RESOURCE.H" директивами должны быть перекомпилированы.

Visual C++, обходит зависимость от RESOURCE.H , включая следующий комментарий в качестве первой строки файла RESOURCE.H:

//{{NO_DEPENDENCIES}}

Среда разработки интерпретирует этот комментарий, игнорируя изменения в RESOURCE.H, чтобы зависимые файлы .CPP не требовали перекомпиляции.

Visual C++ всегда добавляет //{{NO_DEPENDENCIES}} строку комментариев в .RC файл при сохранении файла. В некоторых случаях обход зависимостей RESOURCE.H сборки может привести к ошибкам во время выполнения, незамеченным во время соединения. Например, если вы используете браузер символов для изменения числового значения, назначенного символу ресурса, ресурс не будет правильно найден и загружен во время выполнения приложения, если .CPP файл, ссылающийся на ресурс, не перекомпилируется. В таких случаях необходимо явно перекомпилировать все .CPP файлы, которые, как известно, затронуты изменениями символов в RESOURCE.H или выберите "Перестроить все". Если у вас есть необходимость часто изменять значения символов для определенной группы ресурсов, вы, вероятно, найдете его более удобным и безопасным, чтобы разорвать эти символы в отдельный файл заголовков только для чтения, как описано в приведенном выше разделе " Включение дополнительных файлов заголовков".

Как Visual C++ управляет включением наборов информации

Как описано выше, команда "Набор" меню "Файл" позволяет вам задать три типа сведений:

  • Файл заголовка символов

  • Директивы символов Read-Only

  • Директивы Compile-Time

В следующей .RC таблице описывается, как Visual C++ поддерживает эти сведения в файле. Эти сведения не требуются для использования Visual C++, но это может улучшить понимание, чтобы вы могли более уверенно использовать функцию "Набор включает".

Каждый из указанных выше трёх типов наборов включает сведения, которые хранятся в .RC файле в двух формах: (1) как #include или другие директивы, которые интерпретируются компилятором ресурсов, и (2) как специальные TEXTINCLUDE ресурсы, интерпретируемые только Visual C++.

Цель ресурса TEXTINCLUDE заключается в безопасном хранении информации о "Set Includes" в форме, которая легко отображается в диалоговом окне "Set Includes" Visual C++. TEXTINCLUDEэто тип ресурса , определенный Visual C++. Visual C++ распознает три конкретных TEXTINCLUDE ресурса, имеющих идентификационные номера ресурсов 1, 2 и 3:

TEXTINCLUDE Идентификатор ресурса Тип набора включает сведения
1 Файл заголовка символов
2 Директивы символов Read-Only
3 Директивы Compile-Time

Каждый из трех типов сведений о наборе проиллюстрирован файлами MYAPP.RC и RESOURCE.H, созданными по умолчанию AppWizard, как описано ниже. Дополнительные маркеры \0 и "" между блоками BEGIN и END требуются синтаксисом RC, чтобы указать строки с нулевым завершением и символ двойной кавычки соответственно.

Файл заголовка символов

Форма сведений о файле заголовка символов, интерпретируемая компилятором #include ресурсов, — это просто инструкция:

#include "resource.h"

Соответствующий TEXTINCLUDE ресурс:

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

Директивы символов Read-Only

Директивы символа Read-Only включаются в начало MYAPP.RC в следующей форме, интерпретируемой компилятором ресурсов:

#include "afxres.h"

Соответствующий TEXTINCLUDE ресурс:

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

Директивы Compile-Time

директивы Compile-Time включаются в конце 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++ пропускать директивы Compile-Time.

Соответствующий 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

См. также

Технические примечания по номеру
Технические заметки по категориям