• Создание приложения средствами MFC AppWizard
  • Приложение Dialog
  • Имена, используемые MFC
  • Ресурсы приложения
  • Исходные тексты приложения
  • Средства ClassWizard
  • Создание нового класса
  • Включение в класс новых методов
  • Включение в класс новых элементов данных
  • Просмотр характеристик класса
  • 4. Приложение с главной диалоговой панелью

    В состав компиляторов Microsoft Visual C++ встроены средства, позволяющие программисту облегчить разработку приложений. В первую очередь к ним относятся MFC AppWizard и ClassWizard .

    Как известно, в любом деле самое трудное – начало. Это высказывание в полной мере справедливо по отношению к разработке приложений Windows. Мы рассказывали в предыдущих книгах серии “Библиотека системного программиста” и вы могли убедиться в этом сами, что исходные тексты даже простых приложений Windows имеют большие размеры.

    На создание работающего каркаса или шаблона приложения у программиста уходит слишком много времени. Обычно, чтобы не набирать исходный текст такого шаблона каждый раз, новые приложения создают на основе уже отлаженных примеров, изменяя их по своему усмотрению.

    Благодаря MFC AppWizard среда разработчика Microsoft Visual C++ позволяет быстро создавать шаблоны новых приложений. При этом программисту не приходится писать ни одной строки кода. Достаточно ответить на ряд вопросов, которые задает MFC AppWizard, выбрав какое приложение вы желаете создать, и исходные тексты шаблона приложения вместе с файлами ресурсов готовы. Эти тексты можно сразу оттранслировать и получить готовый загрузочный модуль приложения.

    Конечно, сегодня никакие средства автоматизированной разработки не смогут создать программу полностью без вашего участия – иначе зачем были бы нужны программисты? Прикладную часть приложения вы должны будете написать сами.

    Однако MFC AppWizard окажет вам очень сильную помощь. Так, чтобы создать многооконный текстовый редактор обладающий справочной системой, в который к тому же можно включать OLE объекты и, вам не придется написать ни единой строчки кода программы. Исходные тексты такого приложения можно автоматически разработать с помощью AppWizard буквально за две минуты.

    Но даже когда шаблон приложения полностью готов, Microsoft Visual C++ не оставляет вас один на один с его текстом. Встроенный в среду Visual C++ редактор ресурсов позволяет быстро создавать новые меню, диалоговые панели, добавлять кнопки к панели управления (панели toolbar).

    Средства ClassView и ClassWizard позволят подключить к созданным и отредактированным ресурсам управляющий ими код. Большую часть работы по описанию и определению функций, обрабатывающих сообщения от меню, органов управления диалоговых панелей и т. д. также берут на себя ClassView и ClassWizard.

    Создание приложения средствами MFC AppWizard

    Во второй главе книги мы рассматривали приложение MFDialog, которое не имеет главного окна. Вместо окна это приложение использует обыкновенную диалоговую панель. Сейчас мы расскажем вам как создать приложение, подобное MFDialog, не набрав ни одной строки текста программы. Для этого мы будем использовать средства MFC AppWizard и ClassWizard.

    Выберите из меню File строку New. На экране появится диалоговая панель New, содержащая меню. Выберите из него тип объекта, который надо создать. Для создания нового проекта выберите из этого меню строку Project Workspace. Теперь на экране откроется диалоговая панель New Project Workspace, показанная нами на рисунке 4.1.

    Рис. 4.1. Диалоговая панель New Project Workspace


    Из списка Type выберите тип приложения, которое вы желаете создать. В следующей таблице перечислены типы приложений, которые вы можете выбрать.

    Тип приложения Описание
    MFC AppWizard (exe) Приложение, создаваемое с использованием библиотеки классов MFC. С помощью AppWizard вы можете автоматически создать основные классы необходимые для приложения
    MFC AppWizard (dll) Библиотека динамической компоновки – DLL, создаваемая с помощью библиотеки классов MFC. AppWizard позволяет автоматически создать все основные файлы, необходимые для DLL
    OLE ControlWizard Органы управления OLE, созданные с использованием библиотеки классов MFC. Компилятор автоматически создает базовый набор файлов для проекта этого типа
    Application Приложение, созданное на основе библиотеки классов MFC или с использованием только вызовов функций программного интерфейса Windows
    Dynamic-Link Library Библиотека динамической компоновки, созданная с использованием только вызовов функций программного интерфейса Windows
    Console Application Приложение, разработанное с использованием функций консольного ввода/вывода. Этот тип приложений можно использовать для создания небольших программ, работающих в пакетном режиме
    Static Library Библиотека функций
    Makefile Предоставляет дополнительные возможности для использования MAKE-файла
    Custom AppWizard Позволяет создать собственный “волшебник” Custom AppWizard, который можно будет использовать для разработки шаблонов приложений с заданными вами свойствами

    Список типов приложений, которые может создавать Microsoft Visual C++ версии 4.1, расширен. В него включен “волшебник” ISAPI Extension Wizard, который облегчает создание приложений для Microsoft Internet Information Server.

    В этой книге мы расскажем о создании собственных приложений с использованием средств AppWizard. Поэтому выберите из списка Type строку MFC AppWizard (exe).

    Теперь определите расположение базового каталога, в котором будут размещены проекты. Путь каталога можно ввести непосредственно в поле Location или выбрать, из списка, нажав на кнопку Browse. Затем введите в поле Name имя создаваемого проекта. В базовом каталоге создается одноименный подкаталог и в него записываются все файлы проекта. Имена файлов, составляющих проект, и названия классов приложения также присваиваются AppWizard на основе имени проекта.

    В группе переключателей Platforms надо выбрать, для какой платформы создается приложение. Если вы работаете в среде операционных систем Windows NT или Windows 95, установите переключатель Win32.

    После того как вы заполнили все поля диалоговой панели, нажмите кнопку Create. На экране появится первая диалоговая панель MFC AppWizard. Внешний вид этой панели зависит от того, какой тип приложения вами создается. Если вы создаете выполнимое приложение, то на экране появится диалоговая панель, показанная на рисунке 4.2.

    Рис. 4.2. Первый шаг MFC AppWizard


    На первом шаге вам предлагается определить, какой тип пользовательского интерфейса должно иметь приложение. Вы можете выбирать между многооконным интерфейсом (Multiple documents), однооконным интерфейсом (Single document) и интерфейсом основанном на диалоговой панели без главного окна (Dialog based).

    После того как вы определите тип пользовательского интерфейса приложения, в заголовке диалоговой панели MFC AppWizard будет указано, сколько еще шагов (диалоговых панелей AppWizard) надо будет заполнить, чтобы определить все свойства приложения. Для приложений, имеющих интерфейс на основе главной диалоговой панели, процесс создания приложения будет состоять из 4 шагов, а для приложений, имеющих однооконный и многооконный интерфейс – 6 шагов.

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

    Заполнив первую диалоговую панель MFC AppWizard, нажмите кнопку Next >. На экране появится следующая диалоговая панель MFC AppWizard. В зависимости от того, какой тип интерфейса пользователя вы выбрали для приложения, вид этой диалоговой панели может несколько отличаться.

    Если вы выбрали интерфейс приложения, основанный на диалоговой панели, тогда диалоговая панель на втором шаге будет иметь вид, показанный на рисунке 4.3. В этой панели можно указать, будет ли у создаваемого приложения информационная диалоговая панель, справочная подсистема, трехмерные органы управления, возможности использования технологии OLE и коммуникации с помощью протокола TCP/IP. Вы также сможете определить заголовок главной диалоговой панели приложения.

    Рис. 4.3. Второй шаг MFC AppWizard


    Если включить переключатель About box, то приложение будет иметь небольшую информационную панель About. В ней обычно содержится краткая информация о приложении – его название, номер версии, авторские права, небольшая пиктограмма. Чтобы вызвать эту панель, пользователь должен будет выбрать из системного меню главной диалоговой панели приложения строку About App…

    Операционная система Windows имеет хорошо развитую справочную систему. Обычно каждое приложение имеет собственный справочный файл данных, содержащий разнообразную информацию о приложении. MFC AppWizard позволяет легко создать заготовку такого файла и подключить ее к приложению. Для этого следует включить переключатель Context sensitive Help. Теперь главная диалоговая панель приложения будет иметь кнопку Help, с помощью которой можно запустить справочную систему приложения.

    Современный дизайн интерфейса приложений предполагает, что все органы управления, например кнопки и переключатели, должны выглядеть объемными. Чтобы получить эффект трехмерных органов управления, включите переключатель 3D controls.

    Средства автоматизированного создания приложений легко позволяют создавать приложения, использующие OLE технологию. Для приложений, интерфейс пользователя которых основан на диалоговой панели, вы можете использовать технологию OLE automation. Эта технология позволяет приложению работать с объектами, созданными в других приложениях.

    Чтобы облегчить программистам создание приложений Windows, разработаны органы управления OLE. Если вы будете их использовать, включите переключатель OLE controls.

    Библиотека классов MFC версии 4.0 позволяет создавать приложения, взаимодействующие друг с другом через сетевой протокол TCP/IP. Чтобы включить поддержку этого протокола, включите переключатель Windows Sockets.

    По умолчанию название главной диалоговой панели приложения совпадает с именем проекта. Вы можете изменить это название в поле Please enter a title for your dialog.

    После того, как вы заполнили диалоговую панель, нажмите кнопку Next >. На экране появится следующая диалоговая панель, предназначенная для определения основных свойств приложения. Мы представили ее на рисунке 4.4.

    Рис. 4.4. Третий шаг MFC AppWizard


    В этой диалоговой панели вы можете попросить MFC AppWizard немного приподнять завесу тайны над волшебством автоматического создания приложения. Если вы переместите переключатель Would you like to generate source file comments в положение Yes, please, то исходный текст приложения будет снабжен комментариями.

    Приложение может использовать библиотеку классов MFC двумя способами – вызывая библиотеки DLL или включая код классов непосредственно в приложение.

    В первом случае приложение будет иметь меньший размер, но вместе с ним вы должны будете распространять dll-библиотеки MFC. Описание dll-библиотек MFC вы можете найти в разделе “Первое приложение MFC” главы “Введение в MFC”.

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

    Способ подключения библиотеки MFC определяется положением переключателя How would you like to use the MFC library. Если он находится в положении As a shared DLL, то используется dll-библиотека MFC, а если в положении As a statically linked library, то код классов MFC включается непосредственно в выполнимый файл приложения.

    Теперь вы можете перейти к последнему этапу определения свойств приложения. Нажмите кнопку Next >. На экране появится диалоговая панель для выбора названий классов приложения. Внешний вид этой панели представлен на рисунке 4.5.

    Рис. 4.5. Четвертый шаг MFC AppWizard


    В списке AppWizard creates the following classes for you перечислены названия всех классов, которые создает MFC AppWizard для вашего приложения. Названия этих классов являются производными от названия проекта. Ниже этого списка расположены четыре поля Class name, Base class, Header file, Implementation file. Когда вы выбираете из списка AppWizard creates the following classes for you название класса приложения в этих полях отображаются следующая информация:

    Имя поля Описание
    Class name Имя класса приложения, выбранное вами из списка. Вы можете изменить его по вашему усмотрению или оставить как есть
    Base class Имя базового класса MFC, из которого наследуется класс выбранный из списка Class name. Для ряда классов базовый класс можно изменить. Более подробно об этом мы расскажем позже
    Header file, Implementation file Эти два поля определяют названия включаемого файла, в котором описан класс, и файла, содержащего исходный код методов класса. Вы можете изменить их по своему усмотрению

    Теперь все готово к созданию исходных текстов приложения. Для этого достаточно нажать кнопку Finish. На экране появится панель, содержащая информацию о свойствах приложения: тип интерфейса пользователя, названия классов приложения, а также другие особенности, определенные вами с помощью диалоговых панелей MFC AppWizard. Если все правильно, нажмите кнопку OK. MFC AppWizard сразу приступит к построению проекта, полностью создаст все файлы проекта и загрузит их в среду Microsoft Visual C++.

    MFC AppWizard создаст проект, который сразу можно оттранслировать и получить приложение, полностью готовое к запуску. Запустите полученное приложение. На экране появится главная диалоговая панель приложения (рис. 4.6).

    Рис. 4.6. Приложение Dialog


    Полученное приложение имеет только две кнопки OK и Cancel. Нажав на любую из них, вы можете завершить приложение. Взяв за основу полученный проект, измените его в соответствии с вашими потребностями. Вы можете добавить в диалоговую панель новые органы управления, подключить к ним программный код, создать другие ресурсы, и т. д. Все эти задачи легко решаются в среде Microsoft Visual C++ версии 2.0 и 4.0.

    Приложение Dialog

    Названия файлов, входящих в проект Dialog, вы можете просмотреть на странице FileView в окне Project Workspace. В состав нашего проекта входят следующие основные файлы:

    Имя файла Описание
    Dialog.h Основной включаемый файл приложения. В нем описан главный класс приложения CDialogApp, а также подключены другие включаемые файлы, необходимые для библиотеки MFC
    Dialog.cpp Основной файл приложения. В нем определены методы главного класса приложения и глобальные объекты
    Dialog.rc Файл ресурсов. В этом файле описаны все ресурсы приложения. Сами ресурсы могут быть записаны в каталоге RES, расположенном в главном каталоге проекта
    Resource.h Файл содержит определения идентификаторов ресурсов приложения, например идентификаторы строк меню
    res\Dialog.ico Пиктограмма приложения
    res\Dialog.rc2 В этом файле определены ресурсы, которые нельзя редактировать с помощью редактора ресурсов среды Visual C++
    DialogDlg.h Файл, в котором определен класс главной диалоговой панели приложения
    DialogDlg.cpp В этом файле определены методы класса главной диалоговой панели
    ReadMe.txt Текстовый файл, содержащий описание проекта. В нем кратко рассмотрен каждый файл, входящий в проект, перечислены классы приложения, а также представлена некоторая другая дополнительная информация
    Dialog.clw Файл содержит информацию, необходимую для правильной работы ClassWizard
    StdAfx.h, StdAfx.cpp Использование этих файлов позволяет ускорить процесс повторного построения проекта. Более подробное описание файлов представлено ниже

    Имена, используемые MFC

    Библиотека классов содержит огромное количество классов, структур, констант и т. д. Чтобы сделать исходный текст приложений MFC более легким для понимания, принято использовать ряд соглашений для используемых имен и комментариев.

    Названия всех классов и шаблонов классов библиотеки MFC начинаются с заглавной буквы C. Например, CWnd, CMenu, CArray – это классы. Когда вы наследуете собственные классы от классов MFC, вы можете давать им любые имена. Рекомендуется называть их как и классы MFC с заглавной буквы C. Это сделает исходный текст приложения более ясным для понимания.

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

    Библиотека MFC включает помимо классов, набор служебных функций. Названия этих функций начинаются с символов Afx, например AfxGetApp, AfxGetAppName, AfxGetMainWnd. Символы AFX являются сокращением от словосочетания Application FrameworkX, означающего основу приложения, его внутреннее устройство.

    Символы AFX встречаются не только в названии функций MFC. Многие константы, макрокоманды и другие символы начинаются с этих символов. В общем случае Afx является признаком, по которому вы можете определить принадлежность того или иного объекта (функции, переменной, ключевого слова или символа) к библиотеке MFC.

    В процессе создания приложения MFC AppWizard и ClassWizard могут определять идентификаторы ресурсов, идентификаторы для справочной системы и т. д. При этом, для идентификаторов различного типа используются разные префиксы:

    Префикс Представляет идентификаторы
    HID_ Контекстной подсказки для команд
    HIDD_ Контекстной подсказки для диалоговых панелей
    ID_ Строк меню и кнопок панелей управления
    IDB_ Растровых изображений bitmap
    IDC_ Курсоров
    IDC_ Органов управления диалоговых панелей
    IDD_ Шаблонов диалоговых панелей
    IDI_ Пиктограмм
    IDP_ Строковых ресурсов, используемые в диалоговых панелях message box для отображения приглашения
    IDR_ Приложение может иметь несколько ресурсов различного типа с одинаковыми идентификаторами. Для таких идентификаторов используют префикс IDR_
    IDS_ Строковых ресурсов
    IDOK, IDCANCEL Стандартные идентификаторы для кнопок OK и Cancel диалоговых панелей

    Когда приложение разрабатывается средствами MFC AppWizard и ClassWizard, они размещают в исходном тексте приложения комментарии следующего вида:

    //{{AFX_

     …

    //}}AFX_

    Такие комментарии образуют блок кода программы, который управляется только средствами MFC AppWizard и ClassWizard. Пользователь не должен вручную вносить изменения в этом блоке. Для этого необходимо использовать средства ClassWizard.

    Чтобы подчеркнуть особое положение программного кода, заключенного в комментарии //{{AFX_, он отображается серым цветом. Это еще раз напоминает пользователю, о том, что он не должен вручную вносить изменения в этот код. В следующей таблице представлено краткое описание некоторых блоков //{{AFX_.

    Блок Включает
    //{{AFX_DATA //}}AFX_DATA Объявление элементов данных класса. Используется в описании классов диалоговых панелей
    //{{AFX_DATA_INIT //}}AFX_DATA_INIT Инициализация элементов данных класса. Используется в файле реализации классов диалоговых панелей
    //{{AFX_DATA_MAP //}}AFX_DATA_MAP Макрокоманды DDX, предназначенные для связывания элементов данных класса и органов управления диалоговых панелей. Используется в файле реализации классов диалоговых панелей
    //{{AFX_MSG //}}AFX_MSG Описание методов, которые предназначены для обработки сообщений. Этот блок используется при описании класса
    //{{AFX_MSG_MAP //}}AFX_MSG_MAP Макрокоманды таблицы сообщений класса. Используются совместно с AFX_MSG
    //{{AFX_VIRTUAL //}}AFX_VIRTUAL Описание переопределенных виртуальных методов класса. Блок AFX_VIRTUAL используется при описании класса

    Мы перечислили далеко не все блоки //{{AFX_. Существует еще целый ряд блоков, относящихся к реализации технологии OLE и использованию баз данных.

    Когда вы будете изучать описание классов приложения, созданных средствами MFC AppWizard и ClassWizard, вы заметите ряд комментариев, разделяющих элементы класса на несколько категорий. Описание этих комментариев мы привели в следующей таблице.

    Комментарий После комментария размещаются
    // Constructors Конструкторы класса и методы, используемые для инициализации объектов класса. Как правило, элементы класса размещенные в этой секции определены с ключевым словом public
    // Attributes Элементы данных класса, и методы для доступа к ним (свойства класса). Как правило, элементы класса размещенные в этой секции определены с ключевым словом public
    // Operations Виртуальные и невиртуальные методы, используемые для выполнения операций над объектами класса. Как правило элементы класса размещенные в этой секции определены с ключевым словом public
    // Overridables Здесь расположены виртуальные методы, которые вы можете переопределить в порожденных классах. Как правило, элементы класса размещенные в этой секции определены с ключевым словом protected. В большинстве случаев, названия виртуальных методов класса начинается с символов On
    // Implementation Методы и элементы данных, относящиеся к внутреннему устройству класса – реализации класса. Как правило, элементы класса размещенные в этой секции определены с ключевым словом protected или private
    // Dialog Data Элементы данных, класса диалоговой панели, связанные с органами управления

    Для некоторых классов, используются и другие комментарии, например, // Advanced Overridables и т. д.

    MFC AppWizard и ClassWizard помогают вам разрабатывать приложение. Они создают все классы и методы, необходимые для его работы. Вам остается дописать к ним свой код. В тех местах, где вы можете вставить этот код, MFC AppWizard и ClassWizard, как правило, помещают комментарий // TODO:.

    Ресурсы приложения

    Большую часть пользовательского интерфейса любого приложения составляют ресурсы – меню, диалоговые панели, пиктограммы, курсоры. Создавая приложение, MFC AppWizard подготавливает для него базовый набор ресурсов. Вы можете редактировать подготовленные для вас ресурсы по своему усмотрению, а также добавлять в проект новые ресурсы.

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

    Просмотреть ресурсы приложения можно в окне Project Workspace на странице ResourceView. Ресурсы приложения представлены в виде дерева и разделяются по типам. Чтобы просмотреть ресурсы определенного типа, надо установить курсор на символ и нажать левую кнопку мыши. Символ изменится на и вам откроется список ресурсов данного типа, включенных в проект. Около имени каждого ресурса размещается небольшая пиктограмма. Чтобы загрузить выбранный ресурс в редактор, сделайте двойной щелчок левой кнопкой мыши по имени ресурса или по его пиктограмме. Вот список ресурсов, доступных для использования в приложении:

    Ресурс Описание

     Accelerators Акселераторы

     Bitmaps Растровые изображения в формате BMP

     Cursors Курсоры

     Dialogs Диалоговые панели

     Icons Пиктограммы

     Menus Меню

     String tables Таблицы текстовых строк

     Toolbars Панели управления

     Version information Сведения о версии приложения

     Имя определяется программистом Ресурс, определяемый самим пользователем

    MFC AppWizard автоматически создает несколько различных ресурсов для приложения Dialog. Вы можете просмотреть эти ресурсы в окне Project Workspace, выбрав страницу ResourceView. Как видите ресурсы приложения включают две диалоговые панели, пиктограмму, таблицу строк и информацию о версии приложения. Рассмотрим эти ресурсы подробнее.

    Диалоговые панели приложения Dialog

    Диалоговые панели имеют идентификаторы IDD_DIALOG_DIALOG и IDD_ABOUTBOX. Диалоговая панель IDD_DIALOG_DIALOG – это и есть главная диалоговая панель приложения. Она будет отображаться на экране монитора сразу после запуска приложения.

    Просмотрите внешний вид диалоговой панели IDD_DIALOG_DIALOG в редакторе ресурсов. Для этого сделайте двойной щелчок по ее названию в окне Project Workspace. Изначально эта панель содержит только две кнопки OK и Cancel, а также короткую текстовую строку. Впоследствии вы можете изменять эту панель, добавляя к ней новые органы управления.

    Вторая диалоговая панель IDD_ABOUTBOX содержит информацию о приложении – его название, авторские права, год разработки и пиктограмму. Эта панель будет отображаться на экране, когда пользователь выберет строку About из системного меню главной диалоговой панели приложения.

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

    Ниже мы привели фрагменты из файла ресурсов приложения Dialog, в которых определяются шаблоны диалоговых панелей IDD_ABOUTBOX и IDD_DIALOG_DIALOG.

    //////////////////////////////////////////////////////////////

    // Шаблоны диалоговых панелей приложения


    IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 217, 55

    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

    CAPTION "About Dialog"

    FONT 8, "MS Sans Serif"

    BEGIN

     ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20

     LTEXT "Dialog Version 1.0", 
    IDC_STATIC,40,10,119,8,SS_NOPREFIX

     LTEXT "Copyright © 1996", IDC_STATIC, 40, 25, 119, 8

     DEFPUSHBUTTON "OK",IDOK,178,7,32,14,WS_GROUP

    END


    IDD_DIALOG_DIALOG DIALOGEX 0, 0, 185, 92

    STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU

    EXSTYLE WS_EX_APPWINDOW

    CAPTION "Dialog"

    FONT 8, "MS Sans Serif"

    BEGIN

     PUSHBUTTON "Cancel",IDCANCEL,128,23,50,14

     DEFPUSHBUTTON "OK",IDOK,128,7,50,14

     LTEXT "TODO: Place dialog controls here.",
    IDC_STATIC,5,34,113,8

    END

    Пиктограмма

    В файле ресурсов приложения указана единственная пиктограмма, имеющая идентификатор IDR_MAINFRAME. Эта пиктограмма содержится в файле Dialog.ico, в каталоге res.

    //////////////////////////////////////////////////////////////

    // Пиктограмма


    IDR_MAINFRAME ICON DISCARDABLE "res\\Dialog.ico"

    Пиктограмма IDR_MAINFRAME содержит два цветных изображения с разрешением 32×32 и 16×16 пикселов (рис. 4.7). Вы можете изменить эти пиктограммы по своему усмотрению.

    Рис. 4.7. Пиктограммы приложения Dialog


    Таблица текстовых строк

    В таблице текстовых строк проекта Dialog определена только одна текстовая строка &About Dialog…, имеющая идентификатор IDS_ABOUTBOX. Эта строка содержит текст нового элемента, который будет добавлен к системному меню главной диалоговой панели приложения. Если пользователь выберет эту строку меню, приложение выведет на экран небольшую диалоговую панель, с краткой информацией о приложении.

    //////////////////////////////////////////////////////////////

    // Таблица строк


    STRINGTABLE DISCARDABLE

    BEGIN

     IDS_ABOUTBOX "&About Dialog…"

    END

    Версия

    Во всех приложениях, созданных с использованием MFC AppWizard, определен специальный ресурс, содержащий различные сведения о версии приложения (4.8). Приложение Dialog также содержит такой ресурс, который имеет идентификатор VS_VERSION_INFO.

    Рис. 4.8. Информация о версии приложения


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

    Исходные тексты приложения

    Рассмотрим исходные тексты приложения более подробно. Из главы “Введение в MFC” вы уже знаете, что приложения, созданные на основе библиотеки MFC, как правило, не имеют главной функции приложения WinMain.

    Функция WinMain скрыта от программиста внутри методов класса CWinApp. Каждое приложение должно иметь один объект класса, наследованного от базового класса CWinApp. Поэтому свой рассказ мы начнем с главного класса приложения.

    Главный класс приложения dialog

    Главный класс приложения CDialogApp, наследованный от базового класса CWinApp, определен во включаемом файле Dialog.h. Исходный текст этого файла содержится в листинге 4.1.

    Первые строки файла содержат директиву #ifndef, которая проверяет, определен ли символ __AFXWIN_H__. Символ __AFXWIN_H__ определен в файле afxwin.h. Если на этапе обработки файла Dialog.h символ не определен, то при построении проекта выдается сообщение об ошибке. Это гарантирует, что включаемый файл afxwin.h будет обработан до Dialog.h.

    Следующая директива #include включает файл resource.h. Этот файл создается MFC AppWizard и содержит определение идентификаторов, задействованных для ресурсов приложения.

    Листинг 4.1. Файл Dialog.h

    // Dialog.h : Главный включаемый файл для приложения Dialog

    //


    #ifndef __AFXWIN_H__

    #error include 'stdafx.h' before including this file for PCH

    #endif


    #include "resource.h" // включаемый файл содержащий

    // идентификаторы ресурсов приложения


    //////////////////////////////////////////////////////////////

    // Класс CDialogApp:

    // Методы класса CDialogApp определены в файле Dialog.cpp

    //

    class CDialogApp : public CWinApp {

    public:

     CDialogApp();


     // Overrides

     // В следующем блоке ClassWizard помещает описания

     // переопределенных виртуальных методов класса

     //{{AFX_VIRTUAL(CDialogApp)

    public:

     virtual BOOL InitInstance();

     //}}AFX_VIRTUAL


     // Implementation


     //{{AFX_MSG(CDialogApp)

     // В этом блоке ClassWizard размещает описания методов

     // класса. Не редактируйте содержимое этого блока вручную

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Для класса CDialogApp описан конструктор CDialogApp, не имеющий параметров. Этот конструктор будет использоваться в момент запуска приложения для создания объекта класса CDialogApp.

    Кроме конструктора, в классе CDialogApp, переопределяется виртуальный метод InitInstance базового класса CWinApp. Как видите, метод InitInstance находится, после комментария // Overrides, который обозначает секцию переопределения виртуальных методов.

    В принципе вы можете удалить комментарий // Overrides, это ни как не повлияет на работу приложения. Все комментарии типа // Overrides и // Implementation вставляются MFC AppWizard для программиста, чтобы ему было легче определить назначение метода или элемента данных класса.

    MFC AppWizard поместил объявление метода InitInstance внутри блока комментариев AFX_VIRTUAL. Первая и последняя строка, обозначающая этот блок, не влияют на работу программы, так как они являются комментариями (расположены после символов комментария //). Блок AFX_VIRTUAL нужен ClassWizard, чтобы выделить методы класса, которые им управляются. Вы не должны вручную вносить изменения в этот блок и другие блоки AFX_.

    Более подробно о блоках AFX_ и других комментариях, вставляемых MFC AppWizard и ClassWizard, мы рассказывали в разделе “Имена, используемые MFC” данной главы книги.

    Основной файл приложения имеет имя, совпадающее с именем проекта – Dialog.cpp. Текст этого файла приведен нами в листинге 4.2. Файл содержит реализацию методов главного класса приложения CDialogApp.

    Листинг 4.2. Файл Dialog.cpp

    // Dialog.cpp : Определяет главный класс приложения

    //


    // Включаемые файлы

    #include "stdafx.h"

    #include "Dialog.h"

    #include "DialogDlg.h"


    // Для отладочной версии приложения включается дополнительные

    // определения

    #ifdef _DEBUG

    #define new DEBUG_NEW

    #undef THIS_FILE

    static char THIS_FILE[] = __FILE__;

    #endif


    //////////////////////////////////////////////////////////////

    // CDialogApp

    BEGIN_MESSAGE_MAP(CDialogApp, CWinApp)

     //{{AFX_MSG_MAP(CDialogApp)

     // ClassWizard размещает в данном блоке макрокоманды для

     // обработки сообщений. Не изменяйте содержимое этого блока

     // вручную

     //}}AFX_MSG

     ON_COMMAND(ID_HELP, CWinApp::OnHelp)

    END_MESSAGE_MAP()


    //////////////////////////////////////////////////////////////

    // Конструктор класса CDialogApp


    CDialogApp::CDialogApp() {

     // TODO: здесь вы можете добавить собственный код

    }


    //////////////////////////////////////////////////////////////

    // Создаем один объект класса CDialogApp. Это будет главный

    // объект приложения


    CDialogApp theApp;


    //////////////////////////////////////////////////////////////

    // Инициализация приложения


    BOOL CDialogApp::InitInstance() {

     // Стандартная инициализация приложения. Вы можете сократить

     // размер выполняемого модуля приложения, если удалите

     // инициализацию, которая вам не нужна

    #ifdef _AFXDLL

     Enable3dControls();

    #else

     Enable3dControlsStatic();

    #endif


     CDialogDlg dlg;

     m_pMainWnd = &dlg;

     int nResponse = dlg.DoModal();

     if (nResponse == IDOK) {

      // TODO: Здесь вы можете разместить код приложения,

      // который вызывается, если пользователь нажмет кнопку OK

      // в диалоговой панели приложения

     } else if (nResponse == IDCANCEL) {

      // TODO: Здесь вы можете разместить код приложения,

      // который вызывается, если пользователь нажмет кнопку

      // Cancel в диалоговой панели приложения

     }


     // Так как диалоговая панель закрыта, возвращаем значение

     // FALSE чтобы завершить приложение

     return FALSE;

    }

    В начале файла Dialog.cpp подключены три файла stdafx.h, Dialog.h и DialogDlg.h. Файл stdafx.h будет описан нами ниже. Сейчас отметим, что он содержит определения, необходимые для библиотеки классов MFC.

    Файл Dialog.h содержит описание главного класса приложения CDialogApp. Файл DialogDlg.h включает описание класса диалоговой панели приложения. Именно эта панель будет представлять пользовательский интерфейс нашего приложения.

    Далее директива #ifdef проверяет, был ли определен символ _DEBUG. Вы не найдете определение _DEBUG ни в одном исходном файле проекта. Этот символ определяется самой средой VIsual C++, если вы создаете отладочную версию приложения.

    #ifdef _DEBUG

    #define new DEBUG_NEW

    #undef THIS_FILE

    static char THIS_FILE[] = __FILE__;

    #endif

    Для отладочной версии приложения определяется символ DEBUG_NEW и переопределяется статическая переменная THIS_FILE. Если такой символ уже был определен, он предварительно отменяется директивой #undef, а затем определяется снова.

    THIS_FILE определяется как символьная строка, в которую записывается имя исходного файла данного модуля, определенное специальным символом __FILE__ (то, есть Dialog.cpp).

    Исходные тексты приложений, подготовленных с использованием средств автоматизированного проектирования MFC AppWizard и ClassWizard, активно используют символы, определенные в среде VIsual C++. Чтобы просмотреть их список, выберите из меню Build строку Settings. На экране появится диалоговая панель Project Settings, содержащая несколько страниц. Выберите страницу C/C ++ (рис. 4.9).

    В поле Settings For приложение Dialog представлено двумя строками. Одна выбирает параметры проекта для отладочной версии приложения, а вторая для законченной, не отладочной, версии.

    В поле Preprocessor definitions отображается список символов, определенных для данного проекта. Вы можете добавить в этот список новые символы, или убрать символы, которые уже определены.

    Рис. 4.9. Настройка проекта


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

    Таблица сообщений класса CDialogApp

    Таблица сообщений класса CDialogApp состоит из макрокоманд BEGIN_MESSAGE_MAP и END_MESSAGE_MAP. Между ними расположены макрокоманды, определяющие сообщения, обрабатываемые данным классом. В таблице определено только одно командное сообщение, имеющее идентификатор ID_HELP. Для его обработки вызывается метод OnHelp базового класса CWinApp.

    Необработанные сообщения передаются базовому классу CWinApp, так как он указан во втором параметре макрокоманды BEGIN_MESSAGE_MAP.

    //////////////////////////////////////////////////////////////

    // Таблица сообщений класса CDialogApp

    BEGIN_MESSAGE_MAP(CDialogApp, CWinApp)

     //{{AFX_MSG_MAP(CDialogApp)

     // ClassWizard размещает в данном блоке макрокоманды для

     // обработки сообщений. Не изменяйте содержимое этого блока

     //}}AFX_MSG

     ON_COMMAND(ID_HELP, CWinApp::OnHelp)

    END_MESSAGE_MAP()

    Обратите внимание, что внутри таблицы сообщений расположены две макрокоманды AFX_MSG, помещенные за знаками комментария. Сразу после создания приложения между ними нет ни одной макрокоманды. Когда вы будете создавать обработчики сообщений при помощи ClassWizard, он будет располагать новые обработчики между этими комментариями. Не рекомендуется вручную вносить изменения в код, расположенный в блоке AFX_MSG . Используйте для этого средства ClassWizard.

    Если вам требуется добавить новый обработчик в таблицу сообщений, без использования ClassWizard, расположите его после блока AFX_MSG и до макрокоманды END_MESSAGE_MAP.

    Приложение Dialog содержит еще одну таблицу сообщений, принадлежащую классу диалоговой панели приложения. Мы рассмотрим эту таблицу позже.

    Непосредственно после таблицы сообщений главного класса приложения расположено определение конструктора CDialogApp. Этот конструктор вызывается в момент создания объекта приложения. Конструктор, созданный MFC AppWizard, пустой и не выполняет никаких дополнительных действий. Для инициализации приложения используются методы InitInstance и InitApplication.

    Главный объект приложения

    В файле Dialog.cpp объявляется глобальный объект главного класса приложения. Именно с создания этого объекта и начинается работа приложения.

    CDialogApp theApp;

    Объект класса CWinApp обязательно входит во все приложения, созданные с использованием MFC AppWizard, вне зависимости от пользовательского интерфейса этого приложения. Приложения с однооконным, многооконным интерфейсом и с интерфейсом, основанном на диалоговой панели, имеют единственный объект класса CWinApp.

    Метод InitInstance

    Каждый раз, когда запускается очередная копия приложения, вызывается метод InitInstance главного класса приложения. Это единственный метод главного класса приложения, который должен быть переопределен в любом приложении.

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

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

    BOOL CDialogApp::InitInstance() {

     // …

    }

    Если вы указали, что ваше приложение должно иметь трехмерный графический интерфейс, то метод InitInstance вызывает метод Enable3dControls или Enable3dControlsStatic , определенные в классе CWinApp. Эти методы разрешают использование трехмерных органов управления. Какой из этих методов будет использоваться определяется на этапе работы препроцессора в зависимости от того, определен или нет символ _AFXDLL.

    // Использовать для приложения трехмерный интерфейс

    #ifdef _AFXDLL

    Enable3dControls();

    #else

    Enable3dControlsStatic();

    #endif

    Символ _AFXDLL определяется средой Visual C++, если вы используете библиотеку классов MFC как библиотеку DLL. Если же код MFC подключается к приложению как статическая библиотека, этот символ не определен.

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

    Затем метод InitInstance создает диалоговую панель, которая и будет выполнять роль пользовательского интерфейса приложения. Для этого сначала создается объект dlg класса CDialogDlg, который управляет диалоговой панелью. Затем адрес этого объекта присваивается элементу данных m_pMainWnd главного класса приложения.

    CDialogDlg dlg;

    m_pMainWnd = &dlg;

    Только после этого вызывается метод DoModal для объекта dlg класса CDialogDlg. Он создает модальное диалоговое окно и отображает его на экране. Диалоговая панель, которую создает MFC AppWizard, показана нами на рисунке 2.2. Она имеет всего две кнопки OK и Cancel. Когда пользователь нажимает на одну из этих кнопок, метод DoModal возвращает идентификатор этой кнопки. По умолчанию кнопка OK имеет идентификатор IDOK, а кнопка Cancel – IDCANCEL.

    int nResponse = dlg.DoModal();

    В исходный текст метода InitInstance включается два оператора if и else if, которые определяют, какая кнопка была нажата. Вы можете поместить после этих операторов ваш собственный код. Он будет вызываться при нажатии на соответствующую кнопку в диалоговой панели.

    if (nResponse == IDOK) {

     // Поместите здесь код, который будет выполняться

     // когда пользователь нажмет кнопку OK

    } else if(nResponse == IDCANCEL) {

     // Поместите здесь код, который будет выполняться

     // когда пользователь нажмет кнопку Cancel

    }

    Все! Теперь диалоговое окно закрыто и вам надо завершить приложение. Для этого достаточно, чтобы метод InitInstance вернул значение FALSE.

    return FALSE;

    Класс главной диалоговой панели приложения

    Большой интерес представляет файл DialogDlg.h, показанный в листинге 4.3. Этот класс содержит объявление класса главной диалоговой панели приложения CDialogDlg.

    Класс CDialogDlg наследуется от базового класса CDialog , определенного в библиотеке классов MFC. Конструктор класса имеет один необязательный параметр pParent, используемый для передачи индекса главного окна приложения. Приложение Dialog не имеет главного окна. Роль главного окна выполняет сама диалоговая панель, поэтому параметр pParent не используется.

    Непосредственно после объявления конструктора класса следует объявление элементов данных класса, которые добавлены средствами MFC AppWizard или ClassWizard. Они расположены между двумя комментариями AFX_DATA. Не рекомендуется вручную изменять код приложения, расположенный между этими комментариями.

    После блока AFX_DATA следует блок AFX_VIRTUAL. В этом блоке MFC AppWizard и ClassWizard добавляют объявления переопределенных виртуальных методов базового класса.

    Сначала в этом блоке объявлен только один метод DoDataExchange, переопределенный в нашем проекте. Этот метод применяется для связывания с органами управления диалоговой панели элементов управляющего ей класса.

    Практически со всеми приложениями связана пиктограмма, которая будет отображаться при минимизации приложения. Обычно эта пиктограмма определяется на этапе регистрации класса главного окна приложения. Приложение Dialog не имеет настоящего главного окна. Вместо него используется диалоговая панель. Поэтому отображение пиктограммы приложения не происходит автоматически и мы должны управлять этим сами. Идентификатор пиктограммы m_hIcon определен в классе CDialogDlg после блока AFX_VIRTUAL.

    Диалоговая панель CDialogDlg будет обрабатывать ряд сообщений. Объявления обработчиков сообщений созданных средствами MFC AppWizard или ClassWizard располагаются между двумя комментариями AFX_MSG, образующими блок AFX_MSG.

    После создания проекта в классе CDialogDlg объявлены 4 обработчика сообщений OnInitDialog, OnSysCommand, OnPaint и OnQueryDragIcon. Эти методы определены в файле DialogDlg.cpp, описанном ниже.

    Листинг 4.3. Файл DialogDlg.h

    //////////////////////////////////////////////////////////////

    // Класс CDialogDlg главной диалоговой панели приложения

    class CDialogDlg : public CDialog {

     // Construction

    public:

     // Стандартный конструктор

     CDialogDlg(CWnd* pParent = NULL);


     // Dialog Data

     //{{AFX_DATA(CDialogDlg)

     enum { IDD = IDD_DIALOG_DIALOG };

     // В этом блоке ClassWizard размещает новые элементы данных

     // класса

     //}}AFX_DATA


     // В следующем блоке ClassWizard выполняет переопределение

     // виртуальных методов

     //{{AFX_VIRTUAL(CDialogDlg)

    protected:

     // Поддержка DDX/DDV

     virtual void DoDataExchange(CDataExchange* pDX);

     //}}AFX_VIRTUAL


     // Implementation

    protected:

     HICON m_hIcon;


     // В следующем блоке перечислены методы обработчики

     // сообщений класса CDialogDlg

     //{{AFX_MSG(CDialogDlg)

     virtual BOOL OnInitDialog();

     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

     afx_msg void OnPaint();

     afx_msg HCURSOR OnQueryDragIcon();

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Методы класса диалогового окна определены в файле DialogDlg.cpp. Исходный текст этого файла представлен в листинге 4.4. В нем содержатся определение конструктора и методов класса CDialogDlg.

    Листинг 4.4. Файл DialogDlg.cpp

    #include "stdafx.h"

    #include "Dialog.h"

    #include "DialogDlg.h"


    #ifdef _DEBUG

    #define new DEBUG_NEW

    #undef THIS_FILE

    static char THIS_FILE[] = __FILE__;

    #endif


    //////////////////////////////////////////////////////////////

    // Описание класса CAboutDlg, который используется для

    // управления диалоговой панелью About. Методы этого класса

    // определены ниже

    class CAboutDlg : public CDialog {

    public:

     CAboutDlg();


     // Dialog Data

     //{{AFX_DATA(CAboutDlg)

     enum { IDD = IDD_ABOUTBOX };

     //}}AFX_DATA


     // В следующем блоке ClassWizard размещает переопределение

     // виртуальных методов

     //{{AFX_VIRTUAL(CAboutDlg)

    protected:

     // Поддержка DDX/DDV

     virtual void DoDataExchange(CDataExchange* pDX);

     //}}AFX_VIRTUAL


     // Implementation

    protected:

     //{{AFX_MSG(CAboutDlg)

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };


    // Конструктор класса CAboutDlg

    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) {

     //{{AFX_DATA_INIT(CAboutDlg)

     //}}AFX_DATA_INIT

    }


    // Метод DoDataExchange класса CAboutDlg

    void CAboutDlg::DoDataExchange(CDataExchange* pDX) {

     CDialog::DoDataExchange(pDX);

     //{{AFX_DATA_MAP(CAboutDlg)

     //}}AFX_DATA_MAP

    }


    // Таблица сообщений класса CAboutDlg

    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

     //{{AFX_MSG_MAP(CAboutDlg)

     // Класс CAboutDlg не обрабатывает никаких сообщений

     //}}AFX_MSG_MAP

    END_MESSAGE_MAP()


    //////////////////////////////////////////////////////////////

    // Ниже определены различные методы класса CDialogDlg


    // Конструктор класса CDialogDlg

    CDialogDlg::CDialogDlg(CWnd* pParent /*=NULL*/) : CDialog(CDialogDlg::IDD, pParent) {

     //{{AFX_DATA_INIT(CDialogDlg)

     // В этом блоке ClassWizard размещает инициализацию

     // элементов данных класса

     //}}AFX_DATA_INIT


     // Вызов LoadIcon не требует последующего вызова

     // DestroyIcon, если вы используете программный интерфейс

     // Win32

     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    }


    // Метод DoDataExchange класса CDialogDlg

    void CDialogDlg::DoDataExchange(CDataExchange* pDX) {

     CDialog::DoDataExchange(pDX);

     //{{AFX_DATA_MAP(CDialogDlg)

     // Здесь ClassWizard размещает вызовы методов DDX и DDV

     //}}AFX_DATA_MAP

    }


    // Таблица сообщений класса CDialogDlg

    BEGIN_MESSAGE_MAP(CDialogDlg, CDialog)

     //{{AFX_MSG_MAP(CDialogDlg)

     ON_WM_SYSCOMMAND()

     ON_WM_PAINT()

     ON_WM_QUERYDRAGICON()

     //}}AFX_MSG_MAP

    END_MESSAGE_MAP()


    // Метод OnInitDialog класса CDialogDlg

    BOOL CDialogDlg::OnInitDialog() {

     CDialog::OnInitDialog();


     // Добавление строки "About…" к системному меню приложения


     // Проверяем, что идентификатор IDM_ABOUTBOX относится к

     // системным командам

     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

     ASSERT(IDM_ABOUTBOX < 0xF000);


     CMenu* pSysMenu = GetSystemMenu(FALSE);

     CString strAboutMenu;

     strAboutMenu.LoadString(IDS_ABOUTBOX);

     if (!strAboutMenu.IsEmpty()) {

      pSysMenu->AppendMenu(MF_SEPARATOR);

      pSysMenu->AppendMenu(MF_STRING,  IDM_ABOUTBOX, strAboutMenu);

     }


     // Выбираем пиктограмму для диалоговой панели. Если главное

     // окно приложения не является диалоговой панелью, этот код

     // не нужен

     SetIcon(m_hIcon,TRUE); // выбираем пиктограмму большого

                            // размера


     SetIcon(m_hIcon,FALSE); // выбираем пиктограмму маленького

                             // размера


     // TODO: Здесь вы можете выполнить дополнительную

     // инициализацию


     return TRUE;

    }


    // Метод OnSysCommand класса CDialogDlg

    void CDialogDlg::OnSysCommand(UINT nID, LPARAM lParam) {

     if ((nID & 0xFFF0) == IDM_ABOUTBOX) {

      CAboutDlg dlgAbout;

      dlgAbout.DoModal();

     } else {

      CDialog::OnSysCommand(nID, lParam);

     }

    }


    // Если вы добавили кнопку минимизации к диалоговой панели,

    // следующий код нужен, чтобы отобразить пиктограмму


    // Метод OnPaint класса CDialogDlg

    void CDialogDlg::OnPaint() {

     if (IsIconic()) {

      CPaintDC dc(this); // контекст устройства


      SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);


      // Выравниваем по центру пиктограмму

      int cxIcon = GetSystemMetrics(SM_CXICON);

      int cyIcon = GetSystemMetrics(SM_CYICON);


      CRect rect;

      GetClientRect(&rect);

      int x = (rect.Width() – cxIcon + 1) / 2;

      int y = (rect.Height() – cyIcon + 1) / 2;


      // Отображаем пиктограмму

      dc.DrawIcon(x, y, m_hIcon);

     } else {

      CDialog::OnPaint();

     }

    }


    // Данный метод вызывается для определения формы курсора,

    // отображаемого, когда пользователь переносит

    // минимизированное окно


    // Метод OnQueryDragIcon класса CDialogDlg

    HCURSOR CDialogDlg::OnQueryDragIcon() {

     return (HCURSOR) m_hIcon;

    }

    Таблица сообщений класса CDialogDlg

    Файл DialogDlg.cpp содержит таблицу сообщений класса CDialogDlg. Таблица включает три макрокоманды. Как видите, они расположены в блоке AFX_MSG_MAP, поэтому для управления ими используется ClassWizard.

    BEGIN_MESSAGE_MAP(CDialogDlg, CDialog)

     //{{AFX_MSG_MAP(CDialogDlg)

     ON_WM_SYSCOMMAND()

     ON_WM_PAINT()

     ON_WM_QUERYDRAGICON()

     //}}AFX_MSG_MAP

    END_MESSAGE_MAP()

    При помощи ClassWizard вы можете обнаружить, что макрокоманды выполняют обработку сообщений WM_SYSCOMMAND, WM_PAINT, WM_QUERYDRAGICON, вызывая для этого методы OnSysCommand, OnPaint и OnQueryDragIcon.

    Конструктор класса CDialogDlg

    Конструктор класса CDialogDlg вызывает конструктор базового класса CDialog. При этом ему передается идентификатор диалоговой панели IDD и идентификатор главного окна приложения pParent. При создании объекта класса CDialogDlg не указываются никакие параметры. Поэтому pParent по умолчанию принимается равным NULL.

    //////////////////////////////////////////////////////////////

    // Конструктор класса CDialogDlg

    CDialogDlg::CDialogDlg(CWnd* pParent /*=NULL*/) : CDialog(CDialogDlg::IDD, pParent) {

     //{{AFX_DATA_INIT(CDialogDlg)

     // В этом блоке ClassWizard размещает инициализацию

     // элементов данных класса

     //}}AFX_DATA_INIT


     // Вызов LoadIcon не требует последующего вызова

     // DestroyIcon, если вы используете программный интерфейс

     // Win32

     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    }

    В теле конструктора расположен блок AFX_DATA_INIT . В него ClassWizard будет добавлять код инициализации элементов данных класса CDialogDlg. Конструктор также инициализирует m_hIcon, записывая в него идентификатор пиктограммы IDR_MAINFRAME.

    Функция AfxGetApp возвращает указатель на объект главного класса приложения. Такой объект для данного приложения всегда один. В нашем случае AfxGetApp определяет указатель на объект theApp. Вот прототип этой функции:

    CWinApp* AfxGetApp();

    Метод DoDataExchange

    Диалоговая панель приложения содержит только две кнопки и не имеет связанных с ними переменных. Однако метод DoDataExchange переопределен. Фактически он не выполняет ни какой работы. Единственное что он делает, это вызывает метод DoDataExchange базового класса CDialog.

    Если вы добавите к диалоговой панели новые органы управления и свяжете их средствами ClassWizard с элементами данных класса CDialogDlg, то в блоке AFX_DATA_MAP будут размещены вызовы методов DDE и DDV , необходимые для выполнения обмена данными.

    void CDialogDlg::DoDataExchange(CDataExchange* pDX) {

     CDialog::DoDataExchange(pDX);

     //{{AFX_DATA_MAP(CDialogDlg)

     // Здесь ClassWizard размещает вызовы методов DDX и DDV

     //}}AFX_DATA_MAP

    }

    Метод OnInitDialog

    Когда вы отображаете диалоговую панель на экране, вызывая методы DoModal, Create или CreateIndirect, функции диалоговой панели передается сообщение WM_INITDIALOG. Вы не имеете доступа непосредственно в функции диалога. Ее реализация содержится в базовом классе CDialog.

    В ответ на сообщение WM_INITDIALOG вызывается метод OnInitDialog, объявленный как виртуальный метод класса CDialog. Метод OnInitDialog вызывается непосредственно перед выводом панели на экран.

    Таблица сообщений класса CDialogDlg не содержит макрокоманд для обработки сообщения WM_INITDIALOG. Метод OnInitDialog вызывается непосредственно MFC.

    Чтобы реализовать собственную обработку сообщения WM_INITDIALOG, нужно просто переопределить метод OnInitDialog. Переопределенный метод должен сразу вызвать метод OnInitDialog базового класса CDialog.

    Для приложения Dialog MFC AppWizard уже переопределил метод OnInitDialog. В реализации метода добавляется новая строка к системному меню диалоговой панели для вызова краткой справки о приложении. Затем вызывая метод SetIcon, определенный в базовом классе CWnd, мы выбираем пиктограммы для приложения.

    Метод OnInitDialog возвращает значение TRUE. Это означает, что фокус ввода будет установлен на первый орган управления диалоговой панели. Первый орган диалоговой панели можно выбрать в редакторе диалоговой панели, выбрав из меню Layout строку Tab Order.

    Если во время инициализации диалоговой панели метод OnInitDialog устанавливает фокус ввода другому органу управления, метод должен вернуть значение FALSE.

    BOOL CDialogDlg::OnInitDialog() {

     CDialog::OnInitDialog();


     // Добавление строки "About…" к системному меню приложения


     // Проверяем, что идентификатор IDM_ABOUTBOX относится к

     // системным командам

     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

     ASSERT(IDM_ABOUTBOX < 0xF000);


     CMenu* pSysMenu = GetSystemMenu(FALSE);

     CString strAboutMenu;

     strAboutMenu.LoadString(IDS_ABOUTBOX);

     if (!strAboutMenu.IsEmpty()) {

      pSysMenu->AppendMenu(MF_SEPARATOR);

      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

     }


     // Выбираем пиктограмму для диалоговой панели. Если главное

     // окно приложения не является диалоговой панелью этот код

     // не нужен

     SetIcon(m_hIcon,TRUE); // Выбираем пиктограмму большого

                            // размера

     SetIcon(m_hIcon,FALSE); // Выбираем пиктограмму маленького

                             // размера


     // TODO: Здесь вы можете выполнить дополнительную

     // инициализацию

     return TRUE;

    }

    Метод OnSysCommand (системное меню)

    Разрабатывая приложение с помощью MFC AppWizard, мы указали, что оно должно иметь возможность отображения краткой справочной информации. Для этого в системное меню приложения была добавлена строка About.

    Когда пользователь выбирает строки системного меню любого окна, в том числе и диалоговой панели, или нажимает кнопки максимизации и минимизации, в функцию данного окна поступает сообщение WM_SYSCOMMAND. Для обработки этого сообщения вызывается виртуальный метод OnSysCommand, определенный в классе CWnd.

    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

    Параметр nID содержит идентификатор строки системного меню, вызвавшего сообщение. Младшие четыре бита параметра nID используются операционной системой и могут принимать любые значения. Параметр nID (без учета четырех младших бит) может принимать одно из следующих значений.

    Параметр nID Описание
    SC_CLOSE Закрывает объект CWnd
    SC_HOTKEY Активизирует объект CWnd, связанный с комбинацией клавиш, определенной приложением. Младшее слово параметра lParam содержит идентификатор активизируемого окна
    SC_HSCROLL Свертка по горизонтали
    SC_KEYMENU Выбор из меню при помощи комбинации клавиш
    SC_MAXIMIZE, SC_ZOOM Максимизировать объект CWnd
    SC_MINIMIZE, SC_ICON Минимизировать объект CWnd
    SC_MOUSEMENU Выбор из меню при помощи мыши
    SC_MOVE Перемещение окна CWnd
    SC_NEXTWINDOW Переключение на следующее окно
    SC_PREVWINDOW Переключение на предыдущее окно
    SC_RESTORE Восстановление нормального расположения и размера окна
    SC_SCREENSAVE Запустить приложение, предохраняющее экран монитора, указанное в секции [boot] файла SYSTEM.INI
    SC_SIZE Изменить размер окна CWnd
    SC_TASKLIST Запустить или активизировать приложение Task Manager
    SC_VSCROLL Свертка по вертикали

    Если строка системного меню выбрана с использованием мыши, параметр lParam содержит координаты курсора. Младшее слово определяет х-координату, а старшее y-координату.

    Виртуальный метод OnSysCommand определен в классе CDialog и выполняет обработку сообщений WM_SYSCOMMAND в соответствии с их идентификаторами. Естественно, он не может правильно обработать сообщения от строк меню добавленных вами.

    Чтобы обработать сообщения от новых строк системного меню (для нашего приложения это строка About), необходимо переопределить виртуальный метод OnSysCommand.

    Сообщения, имеющие стандартные идентификаторы nID, необходимо передавать для обработки по умолчанию методу OnSysCommand базового класса CDialog.

    void CDialogDlg::OnSysCommand(UINT nID, LPARAM lParam) {

     // Пользователь выбрал строку About системного меню

     if ((nID & 0xFFF0) == IDM_ABOUTBOX) {

      CAboutDlg dlgAbout;

      dlgAbout.DoModal();

     }

     // Все другие сообщение передаем для обработки методу

     // OnSysCommand базового класса CDialog

     else {

      CDialog::OnSysCommand(nID, lParam);

     }

    }

    Реализация метода OnSysCommand, созданная MFC AppWizard для класса CDialogDlg, определяет причину вызова. Если метод OnSysCommand вызван потому что пользователь выбрал из системного меню строку About, создается объект класса CAboutDlg. Класс CAboutDlg представляет собой класс для управления диалоговой панелью About. Затем вызывается метод DoModal, который и отображает диалоговую панель About на экране.

    Если метод OnSysCommand вызван по любой другой причине, тогда вызывается метод OnSysCommand базового класса CDialog, который выполняет обработку этого сообщения по умолчанию.

    Описание класса CAboutDlg, а также определение его методов, содержится в файле DialogDlg.cpp (листинг 4.4). Мы не будем подробно описывать класс CAboutDlg, так как он фактически представляет собой упрощенный вариант класса CDialogDlg.

    Метод OnPaint (отображение пиктограммы приложения)

    Диалоговая панель может иметь кнопку минимизации. Нажав эту кнопку или выбрав строку Minimaze из системного меню, пользователь может свернуть диалоговую панель (приложение) до размера пиктограммы.

    К сожалению диалоговая панель, в отличие от обычного окна, не содержит встроенных средств отображения пиктограммы приложения. Поэтому приложение должно само заботиться об отображении пиктограммы. MFC AppWizard облегчает эту задачу. Если вы выберите приложение с интерфейсом на основе диалоговой панели, то в исходный текст добавляется определение метода OnPaint. Рассмотрим метод OnPaint подробнее.

    void CDialogDlg::OnPaint() {

     // Определяем размер диалоговой панели

     if (IsIconic()) {

      // Если диалоговая панель минимизирована, отображаем

      // пиктограмму

      CPaintDC dc(this); // получаем контекст устройства


      SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);


      int cxIcon = GetSystemMetrics(SM_CXICON);

      int cyIcon = GetSystemMetrics(SM_CYICON);


      // Определяем размеры внутренней области окна

      CRect rect;

      GetClientRect(&rect);


      // Выравниваем пиктограмму по центру

      int x = (rect.Width() – cxIcon + 1) / 2;

      int y = (rect.Height() – cyIcon + 1) / 2;


      // Отображаем пиктограмму

      dc.DrawIcon(x, y, m_hIcon);

     } else {

      // Выполняем обработку по умолчанию

      CDialog::OnPaint();

     }

    }

    После вызова метода OnPaint он проверяет состояние диалоговой панели. Для этого вызывается метод IsIconic, определенный в классе CWnd. Если окно, или в нашем случае диалоговая панель, связанная с объектом, для которого вызывается метод IsIconic, минимизировано, возвращается ненулевое значение, в противном случае – нуль.

    BOOL IsIconic() const;

    В случае если диалоговая панель имеет нормальный размер, управление передается методу OnPaint базового класса CDialog для выполнения обработки по умолчанию.

    Если вызов OnPaint произошел в следствии минимизации диалоговой панели, тогда определяются размеры внутренней области минимизированного окна и размеры пиктограммы. Затем пиктограмма отображается в центре минимизированного окна.

    Метод OnQueryDragIcon

    Пользователь может перетащить пиктограмму минимизированного приложения с места на место. При этом, как правило, форма курсора меняется. Если пользователь перетаскивает пиктограмму окна для класса которого не определена пиктограмма, вызывается метод OnQueryDragIcon. Этот метод должен вернуть идентификатор курсора, который будет отображаться в момент перетаскивания пиктограммы окна.

    MFC AppWizard определяет метод OnQueryDragIcon для класса CDialogDlg, просто возвращая идентификатор пиктограммы приложения.

    HCURSOR CDialogDlg::OnQueryDragIcon() {

     // Возвращаем идентификатор пиктограммы

     return (HCURSOR) m_hIcon;

    }

    Файлы StdAfx.cpp и StdAfx.h

    Самый маленький файл проекта StdAfx.cpp . Исходный текст файла StdAfx.cpp представлен в листинге 4.5.

    Листинг 4.5. Файл StdAfx.cpp

    #include "stdafx.h"

    Фактически файл StdAfx.cpp содержит только директиву #include, предназначенную для подключения файла StdAfx.h. Включаемый файл StdAfx.h, представлен нами в листинге 4.6.

    Включаемый файл StdAfx.h предназначен для включения стандартных системных включаемых файлов afxwin.h, afxext.h и afxcmn.h. Если в вашем проекте определены редко изменяемые включаемые файлы, которые используются во многих модулях приложения, вы можете также подключить их в этом файле.

    Листинг 4.6. Файл StdAfx.h

    // Исключить редко используемые директивы из файлов windows.h

    // и afxv_w32.h

    #define VC_EXTRALEAN


    // Файл afxwin.h необходим при использовании MFC

    #include <afxwin.h>


    // Файл afxwin.h определяет некоторые расширения MFC

    #include <afxext.h>

    #ifndef _AFX_NO_AFXCMN_SUPPORT

    // Файл afxcmn.h используется для органов управления

    // операционной системы Windows 95

    #include <afxcmn.h>

    #endif // _AFX_NO_AFXCMN_SUPPORT

    Средства ClassWizard

    Разработка приложения не заканчивается, когда MFC AppWizard создаст для вас исходные файлы проекта. Теперь вы должны добавить к приложению собственный программный код, выполняющий основные функции приложения. Среда Microsoft Visual C++ версии 4.0 позволяет максимально облегчить дальнейшую разработку приложения. Для этого предназначены такие средства как ClassView и ClassWizard. Они позволяют с минимальными усилиями добавлять в классы новые методы и данные, быстро высвечивать в окне редактирования интересующие вас объявления и определения классов, методов, данных.

    Мы уже изучили возможности ClassView, предназначенные для работы с классами в разделе “Средства ClassView ” главы “Введение в mfc”. По сравнению с ClassView, “волшебник” ClassWizard предоставляет более полные услуги. Он позволяет не только добавлять к классу новые методы и данные. Вы можете использовать ClassWizard, чтобы добавить к классу новый метод, служащий для обработки сообщений, переменную, предназначенную для обмена информацией с полями диалоговой панели.

    Запустить ClassWizard очень просто, для этого можно нажать кнопку  из стандартной панели управления (окно Standard) или выбрать из меню View строку ClassWizard. На экране появится главная диалоговая панель ClassWizard. Мы привели внешний вид этой панели на рисунке 4.10.

    Рис. 4.10. Главная панель ClassWizard


    Главная панель ClassWizard содержит пять страниц – Message Maps, Member Variables, OLE Automation, OLE Events и Class Info. Страница Message Maps позволяет просмотреть сообщения, вырабатываемые объектами, и создать методы для их обработки. Вторая страница Member Variables позволяет управлять данными, записанными в классе. Следующие две страницы OLE Automation и OLE Events отвечают за поддержку вашим приложением технологии OLE. Эти страницы будут рассмотрены позже. Последняя страница Class Info позволяет получить различную информацию о классе.

    Когда вы просматриваете исходный текст приложения, в верхней части окна редактора может отображаться панель WizardBar (рис. 4.11). Органы управления этой панели позволяют получить быстрый доступ к некоторым возможностям ClassWizard. WizardBar позволяет управлять методами, обрабатывающими сообщения от органов управления.

    Рис. 4.11. Панель WizardBar

    Создание нового класса

    Из любой страницы ClassWizard можно добавить в приложение новый класс, созданный на основе базовых классов. В качестве базового класса можно использовать классы, наследованные от класса CCmdTarget или класса CRecordset . Если требуется создать класс, не наследуемый от базовых классов CCmdTarget или CRecordset, использовать средства ClassWizard нельзя. Такие классы надо создавать вручную, непосредственно в текстовом редакторе.

    Объекты порожденные от класса CCmdTarget могут обрабатывать сообщения Windows и команды, поступающие от меню, кнопок, акселераторов. Класс CCmdTarget и другие наследованные от него классы имеют таблицу сообщений (Message map) – набор макрокоманд, позволяющий сопоставить сообщениям Windows и командам методы класса.

    Чтобы создать класс, нажмите кнопку Add Class из любой страницы главной диалоговой панели ClassWizard. Откроется временное меню, содержащее три строки: New, From a file, From an OLE TypeLib. Для создания нового класса выберите из этого меню строку New. Если вы уже имеете исходные тексты класса и их просто требуется подключить к проекту, выберите из меню строку From a file. Последняя строка меню From an OLE TypeLib используется для подключения классов из библиотеки OLE.

    Когда вы создаете новый класс, на экране появляется диалоговая панель Create New Class. В поле Name введите имя создаваемого класса. Рекомендуется начинать названия классов с символа “C”. Для создаваемого класса организуются два файла реализации класса, имеющие расширения CPP и H. В них будут помещаться объявления класса, а также определения его методов и данных. Имя файлов реализации отображается в левой части группы File. По умолчанию файлы реализации имеют имена, соответствующие имени класса. Однако их можно изменить, воспользовавшись кнопкой Change из группы File.

    Теперь выберите из списка Base Class имя базового класса. Список Base Class достаточно велик. В нем содержатся не только основополагающие классы типа CCmdTarget, CDialog, CDocument, CFrameWnd, CView, CWinThread, CWnd. Список базовых классов включает классы большинства органов управления, например CAnimateCtrl, CButton, CColorDialog, CComboBox, CDragListBox, CEdit, CEditView, CFileDialog, CFontDialog, CHeaderCtrl, CHotKeyCtrl, CListBox, CListCtrl, CListView, CProgressCtrl, CStatic и многие многие другие. Доступны также базовые классы, предназначенные для работы с базами данных: CDaoRecordSet, CDaoRecordView, CRecordset, CRecordView, классы обеспечивающие технологию OLE: COleDocument, COleLinkingDoc, COleServerDoc.

    Так, например, вы можете создать новый класс CNewClass, наследованный от базового класса окна просмотра CEditView. Определение класса помещается во включаемый файл NewClass.h (листинг 4.7).

    Листинг 4.7. Файл NewClass.h

    // Класс окна просмотра CNewClass

    class CNewClass : public CEditView {

    protected:

     CNewClass();

     DECLARE_DYNCREATE(CNewClass)


     // Attributes

    public:


     // Operations

    public:


     // Overrides

     //{{AFX_VIRTUAL(CNewClass)

    protected:

     virtual void OnDraw(CDC* pDC);

     //}}AFX_VIRTUAL


     // Implementation

    protected:

     virtual ~CNewClass();

    #ifdef _DEBUG

     virtual void AssertValid() const;

     virtual void Dump(CDumpContext& dc) const;

    #endif


     // Методы, предназначенные для обработки сообщений

    protected:

     //{{AFX_MSG(CNewClass)

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    Определение методов класса размещается в другом файле, имеющем расширение CPP (листинг 4.8).

    Листинг 4.8. Файл NewClass.cpp

    #include "stdafx.h"

    #include "Single.h"

    #include "NewClass.h"


    #ifdef _DEBUG

    #define new DEBUG_NEW

    #undef THIS_FILE

    static char THIS_FILE[] = __FILE__;

    #endif


    //////////////////////////////////////////////////////////////

    // Реализация класса CNewClass


    IMPLEMENT_DYNCREATE(CNewClass, CEditView)


    CNewClass::CNewClass() {}


    CNewClass::~CNewClass() {}


    BEGIN_MESSAGE_MAP(CNewClass, CEditView)

     //{{AFX_MSG_MAP(CNewClass)


     //}}AFX_MSG_MAP

    END_MESSAGE_MAP()


    //////////////////////////////////////////////////////////////

    // Метод OnDraw класса CNewClass

    void CNewClass::OnDraw(CDC* pDC) {

     CDocument* pDoc = GetDocument();

     // TODO: здесь можно расположить код, выполняющий вывод в

     // окно

    }


    //////////////////////////////////////////////////////////////

    // Диагностические методы класса CNewClass

    #ifdef _DEBUG

    void CNewClass::AssertValid() const {

     CEditView::AssertValid();

    }


    void CNewClass::Dump(CDumpContext& dc) const {

     CEditView::Dump(dc);

    }

    #endif //_DEBUG

    Полученная заготовка класса полностью работоспособна. Ее можно дополнить по своему усмотрению новыми методами и данными. Эту работу можно выполнить вручную, но гораздо лучше и проще воспользоваться услугами предоставляемыми ClassWizard. За счет использования ClassWizard процедура создания собственного класса значительно ускоряется и уменьшается вероятность совершить ошибку во время объявления методов.

    Включение в класс новых методов

    Очень удобно использовать ClassWizard для включения в состав класса новых методов. Вы можете добавлять к классу методы, служащие для обработки сообщений Windows и команд от объектов, а также методы, переопределяющие виртуальные методы базовых классов.

    Выберите из списка Class name имя класса, к которому надо добавить новый метод. Теперь из списка Object IDs выберите идентификатор объекта, для которого надо создать метод. Если вам надо переопределить виртуальный метод базового класса, выберите из этого списка имя самого класса.

    Обратите внимание на список Messages. Если вы выбрали в списке Object IDs идентификатор объекта, то в списке Messages отображаются сообщения, которые этот объект может вырабатывать. Например, если в качестве объекта фигурирует строка меню, то в списке сообщений отображаются два сообщения – COMMAND и UPDATE_COMMAND_UI. Сообщение COMMAND передается, когда данная строка выбирается из меню, а сообщение UPDATE_COMMAND_UI – когда открывается меню, содержащее эту строку.

    Выберите из списка Messages то сообщение, для которого надо создать обрабатывающий его метод и нажмите кнопку Add Function. Откроется диалоговая панель Add Member Function. В ней надо определить название нового метода. По умолчанию вам будет предложено название, построенное на основе имени объекта и имени самого сообщения. Нажмите кнопку OK. ClassWizard добавит описание нового метода в класс, а также сформирует шаблон для этого метода, учитывающий все особенности объекта и сообщения.

    Название сообщения, для которого создан метод, или имя переопределенного метода из списка Messages выделяется жирным шрифтом. Название нового метода появится в списке методов класса – Member Function, расположенном в нижней части диалоговой панели ClassWizard. Перед названием методов размещаются символы или . Символ располагается перед виртуальными методами, а символ перед методами, обрабатывающими сообщения Windows.

    Чтобы перейти к редактированию метода класса, установите на его имя указатель мыши и сделайте двойной щелчок левой кнопкой мыши или нажмите кнопку Edit Code. Откроется окно редактора и курсор встанет непосредственно в начало определения метода.

    ClassWizard не только позволяет добавить в класс новые методы, но и удалить их. ClassWizard самостоятельно удалит объявление метода из класса. Чтобы удалить метод, выберите его название из списка Member Function и нажмите кнопку Delete Function.

    Включение в класс новых элементов данных

    ClassWizard позволяет включать в класс не только новые методы, но также и элементы данных, связанные с полями диалоговых панелей, форм просмотра и форм для просмотра записей баз данных и полей наборов записей. ClassWizard, использует специальные процедуры, чтобы привязать созданные им элементы данных класса к полям диалоговых панелей. Эти процедуры носят название обмен данными диалоговой панели и проверка данных диалоговой панели (Dialog Data Exchange and Dialog Data Validation – DDX/DDV). Чтобы привязать поля из наборов записей к переменным, используются процедуры обмена данными с полями записей – (Record Field Exchange – RFX).

    Процедуры DDX /DDV и RFX значительно упрощают программисту работу с диалоговыми панелями. Они позволяют связать поля диалоговых панелей и переменные. Когда пользователь редактирует поля диалоговых панелей, процедуры DDV проверяют введенные значение и блокируют ввод запрещенных значений. Затем процедуры DDX автоматически копируют содержимое полей диалоговых панелей в привязанные к ним элементы данных класса. И наоборот, когда приложение изменяет элементы данных класса, привязанные к полям диалоговой панели, процедуры DDX могут сразу отобразить новые значения полей на экране компьютера.

    Базовые сведения о процедурах обмена данных и проверке введенных значений мы привели в разделе “Диалоговая панель” главы “Введение в MFC”. А теперь мы рассмотрим средства, предоставляемые ClassWizard.

    Откройте ClassWizard и выберите из списка Class name имя класса, к которому надо добавить новый элемент данных. Теперь из списка Control IDs выберите идентификатор органа управления диалоговой панели, к которому надо привязать элемент данных класса. Если из списка Class name выбрать имя класса, не соответствующего диалоговой панели, форме просмотра, форме просмотра записей или набору записей, то список Control IDs остается пустым.

    В столбце Type отображается тип элемента данных, а в столбце Member имя этого элемента данных. Если к органу управления не подключен элемент данных класса, то соответствующие позиции в столбцах Type и Member остаются незаполненными.

    Чтобы добавить новый элемент данных, связанный с органом управления, выберите его из списка и нажмите кнопку Add Variable. На экране появится диалоговая панель Add Member Variable (рис. 4.12).

    Рис. 4.12. Диалоговая панель Add Member Variable


    В поле Member variable name введите имя нового элемента данных. Рекомендуется начинать имена данных класса с символов m_.

    Список Category определяет, будет ли новый элемент данных значением – Value или органом управления – Control. Первая категория обычно охватывает органы управления, которые могут принимать различные значения. К ним, например, относятся поля редактирования, переключатели, списки. Вторая категория охватывает органы управления, принимающие дискретные значения, например кнопки.

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

    Обычно программист должен заполнить в диалоговой панели Add Member Variable только поле названия элемента данных Member variable name. Значения для списков Category и Variable type выбираются автоматически, и как правило не требуют изменения, играя скорее информационную роль.

    Добавленные элементы данных можно легко удалить. Для этого надо выбрать из списка идентификатор соответствующего органа управления и нажать кнопку Delete Variable.

    Мы предлагаем вам самостоятельно попробовать ClassWizard для связывания переменных с органами управления диалоговых панелей. За основу вы можете взять приложение Dialog, описанное нами в предыдущих разделах.

    Просмотр характеристик класса

    Последняя страница Class Info диалоговой панели ClassWizard позволяет просмотреть основные характеристики класса, изменить фильтр сообщений Windows, изменить внешний класс и внешние переменные.

    Выберите из списка Class name имя интересующего вас класса. В группе File details отображается справочная информация о выбранном классе. Поле Header содержит название включаемого файла, в котором определен класс, поле Source – имя файла реализации класса (в нем размещаются определения методов класса и некоторых данных класса). В поле Base class отображается название базового класса, а в поле Resource – идентификатор ресурса (если он есть), обслуживаемого классом. Например, если вы исследуете класс, наследованный от класса CDialog, который обслуживает диалоговую панель, то в поле Base class выводится CDialog, а в поле Resource идентификатор диалоговой панели.

    Основные характеристики классов, отображаемые в полях группы File details, нельзя изменить в автоматическом режиме. Вы можете редактировать только характеристики класса, расположенные в группе Advanced options.

    В зависимости от того, какой тип объекта Windows – диалоговую панель, окно, дочернее окно и т. д., обслуживает класс, он может получать различные множества сообщений.

    Список сообщений, для которых класс может содержать методы-обработчики, отображается в списке Messages на странице Message Map главной диалоговой панели ClassWizard. Так как операционная система Windows имеет очень много различных сообщений, то ClassWizard помещает в этот список только часть этих сообщений.

    Список сообщений формируется в соответствии с типом объекта Windows, обслуживаемом данным классом. Отбор сообщений происходит по фильтру, который отображается в поле Message filter страницы Class Info диалоговой панели ClassWizard. Вы можете поменять этот фильтр. Вам доступны следующие фильтры сообщений:

    Список Message filter Объект, сообщения от которого должны обрабатываться
    Child Window Дочернее окно
    Dialog Диалоговое окно
    MDI Child Frame Дочернее окно MDI
    Not a Window Не окно
    Topmost Frame Окно frame window – главное окно приложения
    Window Окно

    ClassWizard позволяет отобразить (привязать) органы управления на диалоговой панели или форме к внешним (foreign) объектам классов CRecordset or CDaoRecordset. Для этого можно использовать список Foreign class и поле Foreign variable. Более подробно об этой возможности мы расскажем в одной из следующих книг серии.







     

    Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх