Все права на текст принадлежат автору: Александр Вячеславович Фролов, Григорий Вячеславович Фролов.
Это короткий фрагмент для ознакомления с книгой.
Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2Александр Вячеславович Фролов
Григорий Вячеславович Фролов

Фролов А.В., Фролов Г.В., 1996 г. Библиотека системного программиста  Том 28  Microsoft Visual C++ и MFC Часть 2  Программирование для Windows 95 и Windows NT

Введение

В 24 томе серии "Библиотека системного программиста" мы начали рассказывать о программировании приложений Windows с использованием библиотек классов MFC. Вы узнали об основных принципах построения приложений MFC и наиболее важных классах. В этом томе мы продолжим изучение библиотеки классов MFC и ее возможностей.

Много внимания будет уделено созданию приложений, имеющих многооконный пользовательский интерфейс, основанный на использовании технологии MDI, основы которой мы уже излагали в предыдущих книгах серии "Библиотека системного программиста". Но теперь мы будем использовать для создания таких приложений не возможности программного интерфейса Windows, а классы библиотеки MFC. Если вы разрабатывали раньше многооконные приложения, то сможете по достоинству оценить насколько библиотека MFC упрощает работу программиста.

Мы создадим многооконное приложение с использованием MFC AppWizard и объясним как оно работает. Одно из преимуществ многооконного приложения – это возможность отображать в различных окнах одного приложения различные представления документов одного и того же типа или даже документы разных типов. Мы приведем пример приложения, которое отображает в своих окнах документы различного типа.

Развитый программный интерфейс операционной Windows значительно помогает программисту в разработке приложений, имеющих сложный пользовательский интерфейс. Создавая приложения Windows, программист избавлен от необходимости вручную рисовать окна, меню, диалоговые панели и т. д. Трудно даже представить, насколько усложнится задача разработки приложения, если вы решите создать программу, имеющую аналогичные возможности в операционной системе MS-DOS.

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

Библиотека MFC не только служит для простого объединения функций Windows API в классы (например функции управляющие меню, объединяются в один класс, а функции управляющие панелью состояния, – в другой). Библиотека MFC обеспечивает взаимодействие составляющих ее классов, которые вместе нацелены на выполнение определенных задач. Недаром в документации и в дополнительной литературе встречается термин framework (каркас, основа, рабочая среда), употребляемый в отношении совокупности классов MFC и их внутреннему устройству.

Microsoft Visual C++ имеет еще одно средство, позволяющее упростить программисту работу и обеспечить повторное использование кода. Это так называемая галерея компонентов – Component Gallery. В нее входит набор отдельных модулей – компонент, которые программист может включать в свой проект для решения каких-либо задач.

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

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

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

Мы также расскажем о старых знакомых – стандартных диалоговых панелях, которые представлены в библиотеки MFC отдельными классами.

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

Новые версии Visual C++

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

Microsoft Visual C++ версия 4.2

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

Сеть Internet
В состав версии 4.2 включены абсолютно новые классы для работы с сетью Internet, основанные на программном интерфейсе Wininet . С их помощью вы легко сможете создавать клиентские приложения для работы с серверами WWW, FTP и Goufer.

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

Базы данных
Расширены возможности работы с базами данных. Внесены изменения и дополнения в классы, взаимодействующие с базами данных через ODBC, в том числе модифицированы классы CRecordset и CDatabase. Добавлены новые компоненты к Component Gallery, которые можно использовать для связи с базами данных.

Стандартная библиотека языка Си++
В Microsoft Visual C++ версии 4.2 реализована стандартная библиотека языка Си++. В нее включены всевозможные функции, которые вы теперь можете использовать в своих программах.

Win32s посвящается
Microsoft Visual C++ версии 2.0 и все старшие версии этого продукта не позволяют разрабатывать 16-разрядные приложения для операционных систем Windows 3.xx.

Начиная с версии 4.2, приложения, подготовленные в Microsoft Visual C++ и MFC 4.2, также не будут работать в среде Windows 3.хх с установленной поддержкой 32-разрядных приложений Win32s .

Если вам все же необходимо создать приложение, способное работать в среде Win32s, следует воспользоваться более ранними версиями MFC, например MFC 4.1. К сожалению, в этом случае, последние новшества, введенные в библиотеку MFC 4.2, уже не будут вам доступны.

Microsoft Visual C++ версия 4.2, Enterpise Edition
По сравнению с обычной версией Microsoft Visual C++ 4.2, версия Enterpise Edition, значительно расширяет возможности программиста при работе с базами данных.

Если вы используете в своих программах базы данных Microsoft SQL Server или Oracle, то в окне Project Workspace появится новая страница – DataView. В ней представлены различные объекты базы данных – таблицы, хранимые процедуры, триггеры и т. д.

В состав Microsoft Visual C++ 4.2 Enterpise Edition включен отладчик, позволяющий отлаживать хранимые процедуры на языке SQL. Это значительно упрощает этап отладки программы и поиска возможных ошибок.

Интересные новшества введены и в текстовый редактор Microsoft Visual C++. Теперь он имеет возможность более полно работать с текстами на языке SQL, выделяя цветом ключевые слова этого языка.

Visual C++ и Visual J++

Летом 1996 года Microsoft выпустила тестовую версию нового продукта, получившего название Visual J++. Его название перекликается с названием Visual C++, и можно подумать, что “Жи++” стал приемником Си++. Спешим вас успокоить, Жи++ не предназначен для замены Си++. Это совершенно другой язык программирования, основанный на языке Java, лицензию на который Microsoft приобрела у известной фирмы Sun Microsystems.

Предусмотрена интеграция Visual J++ в уже знакомую вам среду разработчика Microsoft Developer Studio. Более того, можно организовать взаимодействие Visual C++ и Visual J++.

Ресурсы Microsoft

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

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

Во время установки Microsoft Visual C++ не происходит копирования файла ресурсов Common.res на жесткий диск компьютера. Поэтому вы должны скопировать его отдельно или использовать непосредственно с компакт диска. На компакт дисках Microsoft Visual C++ этот файл расположен в каталоге Msdev\Samples\Mfc\General\Clipart\.

Чтобы включить некоторые ресурсы из файла Common.res в файл ресурсов вашего приложения, откройте в Microsoft Visual C++ файл Common.res и файл ресурсов приложения. Затем скопируйте интересующие вас ресурсы и сохраните изменения на диске.

Как связаться с авторами

Авторы имеют почтовый адрес в сети GlasNet. Все свои замечания и предложения по содержанию книг серий "Библиотека системного программиста", а также "Персональный компьютер – шаг за шагом" вы можете присылать нам по следующему адресу:

frolov@glas.apc.org

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

Глобальная сеть Наш адрес
CompuServe >internet:frolov@glas.apc.org
GlasNet frolov@glas.apc.org
Internet frolov@glas.apc.org
Relcom frolov@glas.apc.org
UUCP uunet!cdp!glas!frolov
Вы также можете присылать свои пожелания почтой по адресу:

Издательский отдел АО "ДИАЛОГ-МИФИ". Индекс 115409, город Москва, улица Москворечье, дом 31, корпус 2.

Приносим свои извинения за то, что не можем ответить на каждое письмо. Мы также не занимаемся рассылкой книг, дискет и исходных текстов к нашим книгам. По этому вопросу обращайтесь непосредственно в издательство “Диалог-МИФИ”.

Благодарности

Большую помощь нам оказал сотрудник Microsoft АО Юрий Тумашко, предоставивший дистрибутив Microsoft Visual C++ для работы над книгами, посвященными программированию в Windows.

Авторы выражают благодарность Фроловой Ольге Викторовне, Кустову Виктору. Мы также благодарим всех сотрудников издательского отдела АО "ДИАЛОГ-МИФИ": Голубева Олега Александровича, Дмитриеву Наталью, Виноградову Елену, Кузьминову Оксану.

Поддержку в работе над книгами нам оказали генеральный директор АО “ДиалогНаука” Антимонов Сергей Григорьевич и руководитель антивирусного отдела АО “ДиалогНаука” Лященко Юрий Павлович, предоставившие доступ к сети Internet через свой сервер.

1. Многооконный интерфейс

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

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

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

Далее мы усовершенствуем наше приложение так, что оно сможет работать с документами двух типов – графическими и текстовыми.

В ходе своих объяснений мы иногда будем ссылаться на однооконное приложение Single, также созданное с использованием средств MFC AppWizard. Приложение Single мы рассматривали в 24 томе “Библиотеки системного программиста”. Если у вас нет под рукой 24 тома, вы можете быстро создать приложение Single, воспользовавшись MFC AppWizard.

Приложение Multi

Создайте новое приложение с многооконным интерфейсом и назовите его Multi. При определении свойств приложения оставьте все предложения по умолчанию. Приложение Multi не будет использовать технологию OLE и сетевые технологии, не будет работать с базами данных. Процедура создания приложений с использованием MFC AppWizard описана в разделе “Приложение с оконным интерфейсом” 24 тома серии “Библиотека системного программиста”, поэтому мы будем считать, что вы уже создали проект.

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

Сразу после запуска приложения Multi, открывается дочернее окно, предназначенное для просмотра документа, которое получает название Multi1. Вы можете создать новые дочерние окна, выбрав из меню File строку New – открыть новый документ или строку Open – открыть файл (рис. 1.1). Для просмотра уже открытого документа можно открыть еще одно окно (рис. 1.11). В названии такого окна указывается дополнительный числовой индекс.

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

Рис. 1.1. Приложение Multi


Теперь рассмотрим внимательно сам проект Multi, подготовленный для нас MFC AppWizard. Найдите окно Project Workspace и откройте страницу FileView. Вы увидите список всех исходных файлов, входящих в проект (рис. 1.2). В отдельную папку Dependencies будут помещены названия вспомогательных файлов проекта. Эти файлы не входят в проект непосредственно, но используются либо для хранения ресурсов, либо как включаемые файлы, указанные директивой #include в одном или нескольких основных файлах проекта.

Рис. 1.2. Окно Project Workspace, файлы проекта


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

Имя файла Описание
ChildFrm.cpp Файл содержит определение методов класса CChildFrame
ChildFrm.h В файле находится определение класса дочернего окна MDI – CChildFrame
MainFrm.cpp Файл содержит определения методов класса CMainFrame
MainFrm.h Содержит описание класса главного окна приложения, который называется CMainFrame. Класс CMainFrame наследуется от базового класса CFrameWnd, определенного в библиотеке классов MFC
Multi.cpp Основной файл приложения. В нем определены методы основного класса приложения CMultiApp
Multi.h В этом файле перечислены другие включаемые файлы и описан главный класс приложения CMultiApp
Multi.pch Файл создается во время первой трансляции программы, если вы используете предварительную компиляцию включаемых файлов
Multi.rc Файл ресурсов. В этом файле описаны все ресурсы приложения. Сами ресурсы могут быть записаны в каталоге RES, расположенном в главном каталоге проекта
MultiDoc.cpp Включает определение методов класса CMultiDoc
MultiDoc.h Содержит определение класса документов приложения – CMultiDoc
MultiView.cpp Включает определение методов класса CMultiView
MultiView.h Содержит описание класса окна просмотра приложения – CMultiView
ReadMe.txt Текстовый файл, содержащий описание проекта. В нем кратко рассмотрен каждый файл, входящий в проект, перечислены классы приложения, а также представлена некоторая другая дополнительная информация
res\Multi.ico Пиктограмма приложения
res\Multi.rc2 В этом файле определены ресурсы, которые нельзя редактировать с помощью редактора ресурсов среды Visual C++
res\MultiDoc.ico Пиктограмма для документов приложения
res\Toolbar.bmp Файл содержит растровое изображение кнопок панели управления
Resource.h Файл содержит определения идентификаторов ресурсов приложения, например, идентификаторы строк меню
StdAfx.h, StdAfx.cpp Использование этих файлов позволяет ускорить процесс повторного построения проекта. Более подробное описание файлов представлено ниже

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

Рассмотрим ресурсы, которые MFC AppWizard создал для нашего приложения. Откройте страницу RecourceView в окне проекта Project Workspace. В нем отображается полный список всех ресурсов приложения (рис. 1.3).

Рис. 1.3. Окно Project Workspace, ресурсы приложения


Сравните эти ресурсы с ресурсами приложения с однооконным интерфейсом (том 24 серии “Библиотека системного программиста”). Вы заметите, что в состав приложения с многооконным интерфейсом входит больше ресурсов. Так, например, для многооконного приложения определены два меню, две пиктограммы, больше размер таблицы текстовых строк.

Национальные ресурсы
Обратите внимание, что все ресурсы, представленные на странице RecourceView в окне проекта Project Workspace, английские. К сожалению, MFC AppWizard из доступных нам версий Microsoft Visual C++ не позволяет выбрать для создаваемого приложения русские ресурсы (язык для ресурсов выбирается в первой панели MFC AppWizard – Step 1, во время определения свойств приложения). Поэтому для приложения Multi и всех других приложений, созданных с помощью MFC AppWizard, мы выбрали английский язык.

Если вы в Control Panel с помощью приложения Regional Settings выбрали русский язык, то в некоторых случаях ClassWizard может работать неправильно. Например, если вы добавите к английской диалоговой панели новые органы управления, то ClassWizard не позволит автоматически привязать к ним переменные. Возникнут также сложности при использовании русского текста в строковых ресурсах, помеченных как английские. Чтобы избежать этих проблем, измените язык, используемый для ресурсов. Для этого достаточно в окне Project Workspace щелкнуть по идентификатору ресурса правой кнопкой мыши и выбрать из открывшегося контекстного меню строку Properties. На экране появится диалоговая панель со свойствами выбранного ресурса. Измените в ней язык ресурса, выбрав из списка Language строку Russian.

Шаблон меню
Для многооконного приложения в ресурсах проекта определены два меню с идентификаторами IDR_MAINFRAME и IDR_MULTITYPE. Приложение использует одно из этих меню, в зависимости от того, открыт документ или нет.

Меню с идентификатором IDR_MAINFRAME используется, если в приложении не открыт ни один документ. Как видите, идентификатор меню совпадает с идентификатором меню приложения с однооконным интерфейсом, однако строки этих меню различаются:

//////////////////////////////////////////////////////////////// Меню IDR_MAINFRAME

IDR_MAINFRAME MENU PRELOAD DISCARDABLE

BEGIN

 POPUP "&File"

 BEGIN

  MENUITEM "&New\tCtrl+N",    ID_FILE_NEW

  MENUITEM "&Open...\tCtrl+O",ID_FILE_OPEN

  MENUITEM SEPARATOR

  MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP

  MENUITEM SEPARATOR

  MENUITEM "Recent File",     ID_FILE_MRU_FILE1, GRAYED

  MENUITEM SEPARATOR

 MENUITEM "E&xit",            ID_APP_EXIT

 END

 POPUP "&View"

 BEGIN

  MENUITEM "&Toolbar",        ID_VIEW_TOOLBAR

  MENUITEM "&Status Bar",     ID_VIEW_STATUS_BAR

 END

 POPUP "&Help"

 BEGIN

  MENUITEM "&About Multi...", ID_APP_ABOUT

 END

END

Меню, имеющее идентификатор IDR_MULTITYPE, отображается, когда пользователь создает новый документ или открывает документ, уже записанный в файле на диске.

Как видите, в этом меню определено временное меню Window, строки которого служат для управления MDI окнами приложения:

//////////////////////////////////////////////////////////////// Меню IDR_MAINFRAME

IDR_MAINFRAME MENU PRELOAD DISCARDABLE

BEGIN

 POPUP "&File"

 BEGIN

  MENUITEM "&New\tCtrl+N",     ID_FILE_NEW

  MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN

  MENUITEM SEPARATOR

  MENUITEM "P&rint Setup...",  ID_FILE_PRINT_SETUP

  MENUITEM SEPARATOR

  MENUITEM "Recent File",      ID_FILE_MRU_FILE1, GRAYED

  MENUITEM SEPARATOR

  MENUITEM "E&xit",            ID_APP_EXIT

 END

 POPUP "&View"

 BEGIN

  MENUITEM "&Toolbar",         ID_VIEW_TOOLBAR

  MENUITEM "&Status Bar",      ID_VIEW_STATUS_BAR

 END

 POPUP "&Help"

 BEGIN

  MENUITEM "&About Multi...",  ID_APP_ABOUT

 END

END

Большинство строк меню приложения Multi имеет стандартные идентификаторы. Соответствующие им стандартные командные сообщения обрабатываются различными классами библиотеки MFC. Так, например, стандартное командное сообщение с идентификатором ID_FILENEW от строки New меню File, по умолчанию обрабатывается методом OnFileNew класса CWinApp. Мы уже рассказывали о стандартных командных сообщениях в 24 томе из серии “Библиотека системного программиста”. Более подробное описание стандартных командных сообщений вы можете найти в документации Microsoft Visual C++.

В этой книге мы посвятили меню приложений отдельную главу, которая называется “Меню, панели управления и панели состояния”. Дополнительную информацию об использовании меню вы можете получить в 13 томе серии “Библиотека системного программиста”.

Пиктограмма
В файле ресурсов приложения Multi определены две пиктограммы IDR_MULTITYPE и IDR_MAINFRAME. Каждая из этих пиктограмм содержит по два изображения размером 32×32 и 16×16 пикселов. Внешний вид пиктограмм соответствует пиктограммам, используемым приложением с однооконным интерфейсом. Для однооконного приложения пиктограмма, представляющая документ, называлась IDR_SINGLETYPE, а не IDR_MULTITYPE. Такая разница в названиях возникла исключительно из-за разницы в названиях проектов приложений:

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

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

IDR_MAINFRAME ICON DISCARDABLE "res\\Multi.ico"

IDR_MULTITYPE ICON DISCARDABLE "res\\MultiDoc.ico"

Пиктограмма IDR_MAINFRAME представляет приложение, когда оно минимизировано (рис. 1.4). Эта же пиктограмма отображается в левом верхнем углу главного окна приложения.

Рис. 1.4. Пиктограмма IDR_MAINFRAME


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

Рис. 1.5. Пиктограмма IDR_MULTITYPE


Панель управления toolbar
Несмотря на то, что приложение имеет два меню, для него определена только одна панель управления IDR_MAINFRAME. Идентификаторы первых трех и последних двух кнопок этой панели соответствуют идентификаторам строк и меню IDR_MAINFRAME и меню IDR_MULTITYPE. А вот вторые три идентификатора имеют соответствие только в меню IDR_MULTITYPE. Пока ни один документ не открыт и отображается меню IDR_MAINFRAME, эти кнопки недоступны и отображаются серым цветом:

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

// Панель управления Toolbar

IDR_MAINFRAME TOOLBAR DISCARDABLE  16, 15

BEGIN

 BUTTON ID_FILE_NEW

 BUTTON ID_FILE_OPEN

 BUTTON ID_FILE_SAVE

 SEPARATOR

 BUTTON ID_EDIT_CUT

 BUTTON ID_EDIT_COPY

 BUTTON ID_EDIT_PASTE

 SEPARATOR

 BUTTON ID_FILE_PRINT

 BUTTON ID_APP_ABOUT

END

Образ кнопок панели управления расположен в файле Toolbar.bmp, записанном в подкаталоге res каталога проекта (рис. 1.6):

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

// Изображение Bitmap, определяющее кнопки приложения

IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Toolbar.bmp"

Панелям управления мы уделили в этой книге отдельную главу, которая имеет название “Меню, панели управления и панели состояния”. В ней описаны принципы устройства и работы панелей управления, приведены простые примеры создания дополнительных панелей управления, в том числе панелей управления на основе шаблонов диалоговых панелей.

Рис. 1.6. Панель управления


Таблица акселераторов
Таблица акселераторов IDR_MAINFRAME приложения полностью соответствует таблице акселераторов, добавленной MFC AppWizard к ресурсам приложения с однооконным интерфейсом:

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

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

IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE

BEGIN

 "N",       ID_FILE_NEW,   VIRTKEY,CONTROL

 "O",       ID_FILE_OPEN,  VIRTKEY,CONTROL

 "S",       ID_FILE_SAVE,  VIRTKEY,CONTROL

 "P",       ID_FILE_PRINT, VIRTKEY,CONTROL

 "Z",       ID_EDIT_UNDO,  VIRTKEY,CONTROL

 "X",       ID_EDIT_CUT,   VIRTKEY,CONTROL

 "C",       ID_EDIT_COPY,  VIRTKEY,CONTROL

 "V",       ID_EDIT_PASTE, VIRTKEY,CONTROL

 VK_BACK,   ID_EDIT_UNDO,  VIRTKEY,ALT

 VK_DELETE, ID_EDIT_CUT,   VIRTKEY,SHIFT

 VK_INSERT, ID_EDIT_COPY,  VIRTKEY,CONTROL

 VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFT

 VK_F6,     ID_NEXT_PANE,  VIRTKEY

 VK_F6,     ID_PREV_PANE,  VIRTKEY,SHIFT

END

Мы расскажем вам подробнее о таблице акселераторов в разделе “Таблица акселераторов”. Дополнительную информацию вы сможете получить в 13 томе серии “Библиотека системного программиста”.

Диалоговая панель
В ресурсах приложения определена диалоговая панель с идентификатором IDD_ABOUTBOX. Она содержит краткую информацию о приложении и отображается на экране, когда пользователь выбирает из меню Help строку About Multi:

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

// Версия

VS_VERSION_INFO     VERSIONINFO

 FILEVERSION    1,0,0,1

 PRODUCTVERSION 1,0,0,1

 ILEFLAGSMASK 0x3fL

#ifdef _DEBUG

  FILEFLAGS 0x1L

#else

  FILEFLAGS 0x0L

#endif

 FILEOS 0x4L

 FILETYPE 0x1L

 FILESUBTYPE 0x0L

BEGIN

 BLOCK "StringFileInfo"

 BEGIN

  BLOCK "040904B0"

   BEGIN

   VALUE "CompanyName", "Solaris\0"

   VALUE "FileDescription", "MULTI MFC Application\0"

   VALUE "FileVersion", "1, 0, 0, 1\0"

   VALUE "InternalName", "MULTI\0"

   VALUE "LegalCopyright", "Copyright © 1996 Frolov G.V.\0"

   VALUE "OriginalFilename", "MULTI.EXE\0"

   VALUE "ProductName", "MULTI Application\0"

   VALUE "ProductVersion", "1, 0, 0, 1\0"

  END

 END

 BLOCK "VarFileInfo"

 BEGIN

  VALUE "Translation", 0x409, 1200

 END

END

Таблица текстовых строк
Ресурсы приложения содержат несколько блоков, описывающих таблицы текстовых строк. Эти таблицы практически совпадают с таблицами текстовых строк, включенных MFC AppWizard в ресурсы приложения с однооконным интерфейсом.

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

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

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

STRINGTABLE PRELOAD DISCARDABLE

BEGIN

 IDR_MAINFRAME "Multi"

 IDR_MULTITYPE "\nMulti\nMulti\n\n\nMulti.Document\nMulti Document"

END

STRINGTABLE PRELOAD DISCARDABLE

BEGIN

 AFX_IDS_APP_TITLE   "Multi"

 AFX_IDS_IDLEMESSAGE "Ready"

END

Блок текстовых строк, которые используются в панели состояния ststus bar, полностью совпадает с аналогичным блоком в ресурсах однооконного приложения:

STRINGTABLE DISCARDABLE

BEGIN

 ID_INDICATOR_EXT  "EXT"

 ID_INDICATOR_CAPS "CAP"

 ID_INDICATOR_NUM  "NUM"

 ID_INDICATOR_SCRL "SCRL"

 ID_INDICATOR_OVR  "OVR"

 ID_INDICATOR_REC  "REC"

END

В блоке текстовых строк, описывающих элементы меню, добавлен ряд текстовых строк, которые относятся к меню Window. Для однооконного приложения эти строки не определены, так как меню Window есть только у многооконных приложений:

STRINGTABLE DISCARDABLE

BEGIN

 ID_FILE_NEW         "Create a new document\nNew"

 ID_FILE_OPEN        "Open an existing document\nOpen"

 ...

 ID_PREV_PANE        "Switch back to the previous window pane\nPrevious Pane"

 ID_WINDOW_NEW       "Open another window for the active document\nNew Window"

 ID_WINDOW_ARRANGE   "Arrange icons at the bottom of the window\nArrange Icons"

 ID_WINDOW_CASCADE   "Arrange windows so they overlap\nCascade Windows"

 ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"

 ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"

 ID_WINDOW_SPLIT     "Split the active window into panes\nSplit"

 ...

 ID_EDIT_CLEAR       "Erase the selection\nErase"

 ID_VIEW_TOOLBAR     "Show or hide the toolbar\nToggle ToolBar"

 ID_VIEW_STATUS_BAR  "Show or hide the status bar\nToggle StatusBar"

END

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

STRINGTABLE DISCARDABLE

BEGIN

 AFX_IDS_SCSIZE        "Change the window size"

 AFX_IDS_SCMOVE        "Change the window position"

 AFX_IDS_SCMINIMIZE    "Reduce the window to an icon"

 AFX_IDS_SCMAXIMIZE    "Enlarge the window to full size"

 AFX_IDS_SCNEXTWINDOW  "Switch to the next document window"

 AFX_IDS_SCPREVWINDOW  "Switch to the previous document window"

 AFX_IDS_SCCLOSE       "Close the active window and prompts to save the documents"

 AFX_IDS_SCRESTORE     "Restore the window to normal size"

 AFX_IDS_SCTASKLIST    "Activate Task List"

 AFX_IDS_MDICHILD      "Activate this window"

 AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"

END

Классы приложения Multi

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

Список названий классов, а также входящие в них методы и элементы данных можно просмотреть на странице ClassView окна Project Workspace (рис. 1.7). В отдельной папке Globals представлены глобальные объекты и переменные приложения. Приложение Multi имеет только один глобальный объект theApp. Это объект главного класса приложения.

Рис. 1.7. Окно Project Workspace, классы приложения


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

Класс приложения Базовый класс Описание
CMultiApp CWinApp Главный класс приложения
CMainFrame CMDIFrameWnd Класс главного окна приложения
CChildFrame CMDIChildWnd Класс дочернего окна MDI
CMultiDoc CDocument Класс документа приложения
CMultiView CView Класс окна просмотра документа
Кроме пяти основных классов создается также класс CAboutDlg, наследованный от базового класса CDialog. Он отвечает за диалоговую панель About. Если во время определения характеристик приложения вы включите возможность работы с базами данных, работу с сетевыми протоколами или использование технологии OLE, список классов приложения может стать значительно шире.

Главный класс приложения
Главный класс приложения CMultiApp управляет работой всего приложения. Методы этого класса выполняют инициализацию приложения, обработку цикла сообщений и вызываются при завершении приложения. Через окно Project Workspace можно просмотреть названия методов класса и загрузить их в текстовый редактор (рис. 1.8).

Рис. 1.8. Окно Project Workspace, класс CMultiApp


Класс CMultiApp определен в файле Multi.h следующим образом:

//////////////////////////////////////////////////////////////// Класс CMultiApp

class CMultiApp : public CWinApp {

public:

 CMultiApp();


// Overrides

 //{{AFX_VIRTUAL(CMultiApp)

public:

 virtual BOOL InitInstance();

 //}}AFX_VIRTUAL


// Implementation

 //{{AFX_MSG(CMultiApp)

 afx_msg void OnAppAbout();

 //}}AFX_MSG


 // Класс CMultiApp может получать сообщения

 DECLARE_MESSAGE_MAP()

};

В приложении определен только один объект базового класса приложения theApp. Этот объект должен быть один вне зависимости от того, какой интерфейс имеет приложение – однооконный, многооконный или основанный на диалоговой панели:

CMultiApp theApp;

Конструктор класса CMultiApp
Конструктор класса, созданный MFC AppWizard, не выполняет никаких действий. В нем вы можете разместить код для инициализации объекта CMultiApp:

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

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

CMultiApp::CMultiApp() {

 // TODO:

}

Метод InitInstance класса CMultiApp
Основную работу по инициализации приложения выполняет метод InitInstance главного класса приложения, определенный в файле Multi.cpp. Как видите, он отличается от метода InitInstance, который используется для однооконных приложений:

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

// Метод InitInstance

BOOL CMultiApp::InitInstance() {


#ifdef _AFXDLL

 Enable3dControls();  

#else

 Enable3dControlsStatic();

#endif


 // Загружаем файл конфигурации

 LoadStdProfileSettings();


 // Создаем шаблон документа

 CMultiDocTemplate* pDocTemplate;

 pDocTemplate = new CMultiDocTemplate(IDR_MULTITYPE, RUNTIME_CLASS(CMultiDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMultiView));


 // Регистрируем шаблон документа

 AddDocTemplate(pDocTemplate);


 // Создаем главное окно приложения (MDI Frame window)

 CMainFrame* pMainFrame = new CMainFrame;

 if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE;

 m_pMainWnd = pMainFrame;


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

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

 CCommandLineInfo cmdInfo;

 ParseCommandLine(cmdInfo);


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

 if (!ProcessShellCommand(cmdInfo)) return FALSE;


 // Отображаем окно

 pMainFrame->ShowWindow(m_nCmdShow);

 pMainFrame->UpdateWindow();


 return TRUE;

}

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

Затем создается указатель pDocTemplate на объекты класса шаблона документов. Для однооконных приложений это класс CSingleDocTemplate, а для многооконных – CMultiDocTemplate. Создается новый объект класса и указатель на него записывается в переменную pDocTemplate. Для создания шаблона документа используется оператор new.

Конструктору класса CMultiDocTemplate передаются четыре параметра:

CMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);

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

Остальные три параметра pDocClass, pFrameClass и pViewClass содержат указатели на объекты класса CRuntimeClass, полученные с помощью макрокоманд RUNTIME_CLASS из классов документа CMultiDoc, дочернего окна MDI CChildFrame и окна просмотра CMultiView. Таким образом, шаблон документа объединяет всю информацию, относящуюся к данному типу документов.

Созданный шаблон документов заносится в список шаблонов, с которыми работает приложение. Для этого указатель на созданный шаблон документа передается методу AddDocTemplate из класса CWinApp. Указатель на шаблон документов передается через параметр pTemplate:

void AddDocTemplate(CDocTemplate* pTemplate);

Указатель pTemplate должен указывать на объект класса CDocTemplate, однако мы передаем через него указатель на объект класса CMultiDocTemplate. Это допустимо, так как класс CDocTemplate является базовым классом для CMultiDocTemplate.

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

После создания шаблона документа создается главное окно MDI (главное окно приложения).

Для создания главного окна приложения мы формируем объект класса CMainFrame и записываем указатель на него в pMainFrame. Класс CMainFrame определен в нашем приложении. Мы расскажем о нем немного позже:

// Создаем главное окно MDI (главное окно приложения)

CMainFrame* pMainFrame = new CMainFrame;

Затем для только что созданного объекта вызывается метод LoadFrame класса CFrameWnd. Он создает окно, загружает ресурсы, указанные первым параметром, и связывает их с объектом класса CMainFrame. Параметр метода LoadFrame определяет меню, пиктограмму, таблицу акселераторов и таблицу строк главного окна приложения:

if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE;

Указатель на главное окно приложения, которым является главное окно MDI, записывается в элемент данных m_pMainWnd главного класса приложения. Элемент данных m_pMainWnd, определенн в классе CWinThread. Когда окно, представленное указателем m_pMainWnd закрывается, приложение автоматически будет завершено (в случае если приложение включает в себя несколько задач, завершается только соответствующая задача):

m_pMainWnd = pMainFrame;

Метод LoadFrame не отображает главное окно приложения на экране. Для этого надо вызвать методы ShowWindow и UpdateWindow:

// Отображаем главное окно приложения

pMainFrame->ShowWindow(m_nCmdShow);

// Обновляем содержимое окна

pMainFrame->UpdateWindow();

В заключение метода InitInstance обрабатывается командная строка приложения. Для этого создается объект cmdInfo класса CCommandLineInfo и для него вызываются методы ParseCommandLine и ProcessShellCommand:

// Просматриваем командную строку приложения в поиске

// стандартных команд и обрабатываем их

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);


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

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

if (!ProcessShellCommand(cmdInfo)) return FALSE;

Таблица сообщений
Класс CMultiApp может получать сообщения и имеет таблицу сообщений. Таблицу сообщений класса CMultiApp расположена в файле Multi.cpp. Она содержит четыре макрокоманды для обработки командных сообщений от меню приложения:

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

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

BEGIN_MESSAGE_MAP(CMultiApp, CWinApp)

 //{{AFX_MSG_MAP(CMultiApp)

 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

 //}}AFX_MSG_MAP

 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

 ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)

END_MESSAGE_MAP()

Только для одного командного сообщения, имеющего идентификатор ID_APP_ABOUT, вызывается метод обработчик OnAppAbout, определенный в классе CMultiApp. Остальные три командных сообщения ID_FILE_NEW, ID_FILE_OPEN и ID_FILE_PRINT_SETUP передаются для обработки методам класса CWinApp, который является базовым классом для CMultiApp.

Метод-обработчик OnAppAbout вызывается объектом главного класса приложения, когда пользователь выбирает из меню Help строку About. OnAppAbout создает объект класса CAboutDlg, представляющий модальную диалоговую панель About и вызывает для него метод DoModal, отображающий панель на экране (рис. 1.9):

void CMultiApp::OnAppAbout() {

 CAboutDlg aboutDlg;

 aboutDlg.DoModal();

}

Рис. 1.9. Окно Project Workspace, класс CMainFrame


Класс главного окна приложения
Внутри главного окна приложения отображаются панели управления и состояния, дочерние MDI окна, используемые для просмотра документов. Для управления главным окном приложения используется класс CMainFrame, определенный в файле MainFrm.h.

Вы можете изучить класс CMDIFrameWnd, просмотрев его структуру в окне Project Workspace, на странице ClassView (рис. 1.10). Выполните двойной щелчок левой кнопкой мыши по названию класса или по названию интересующего вас метода, и соответствующий программный код загрузится в окно редактора Microsoft Visual C++.


Рис. 1.10. Окно Project Workspace, класс CMainFrame


Ниже мы привели определение класса CMainFrame:

class CMainFrame : public CMDIFrameWnd {

 DECLARE_DYNAMIC(CMainFrame)

public:

 CMainFrame();


// Attributes

public:


// Operations

public:


// Overrides

 //{{AFX_VIRTUAL(CMainFrame)

 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

 //}}AFX_VIRTUAL


// Implementation

public:

 virtual ~CMainFrame();

#ifdef _DEBUG

 virtual void AssertValid() const;

 virtual void Dump(CDumpContext& dc) const;

#endif


protected:

 CStatusBar m_wndStatusBar;

 CToolBar   m_wndToolBar;


protected:

 //{{AFX_MSG(CMainFrame)

 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

};

Класс главного окна многооконного приложения CMainFrame практически полностью соответствует классу главного окна однооконного приложения. Даже названия этих классов одинаковы. Однако обратите внимание, что класс CMainFrame наследуется от базового класса CMDIFrameWnd, а не от CFrameWnd, как это было для однооконного приложения.

Конструктор и деструктор класса CMainFrame
Ниже представлены конструктор и деструктор класса CMainFrame. Изначально они не содержат программного кода и представляют собой простые заготовки. Вы можете использовать их для дополнительной инициализации объекта класса:

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

CMainFrame::CMainFrame() {

 // TODO:

}

// Деструктор класса CMainFrame

CMainFrame::~CMainFrame() {}

Таблица сообщений класса CMainFrame
Таблица сообщений класса CMainFrame содержит только одну макрокоманду ON_WM_CREATE, которая устанавливает для обработки сообщения WM_CREATE метод OnCreate. Сообщения WM_CREATE приходит во время создания главного окна приложения.

Непосредственно перед таблицей сообщений класса CMainFrame располагается макрокоманда IMPLEMENT_DYNAMIC. Она указывает, что объекты класса CMainFrame могут создаваться динамически во время работы приложения:

// Объекты класса CMainFrame могут создаваться автоматически

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)


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

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)

 //{{AFX_MSG_MAP(CMainFrame)

 ON_WM_CREATE()

 //}}AFX_MSG_MAP

END_MESSAGE_MAP()

Метод OnCreate класса CMainFrame
Метод OnCreate класса CMainFrame создает и отображает на экране панели управления и состояния:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

 if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;


 if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) {

  // Ошибка создания панели управления

  TRACE0("Failed to create toolbar\n");

  return -1;   

 }


 if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))    {

  // Ошибка создания панели состояния

  TRACE0("Failed to create status bar\n");

  return -1;     

 }


 m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);


 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

 EnableDocking(CBRS_ALIGN_ANY);

 DockControlBar(&m_wndToolBar);


 return 0;

}

Структура indicators, описывающая индикаторы панели состояния, определена в файле MainFrm.h следующим образом:

static UINT indicators[] = {

 ID_SEPARATOR,

 ID_INDICATOR_CAPS,

 ID_INDICATOR_NUM,

 ID_INDICATOR_SCRL,

};

Сейчас мы не станем подробно останавливаться на процедуре создания панелей состояния и управления. Во первых, в 24 томе мы уже рассматривали метод OnCreate однооконного приложения Single. Он фактически полностью повторяет метод OnCreate приложения Multi. Во вторых мы посвятили проблеме использования меню, панелей состояния и панелей управления отдельный раздел “Меню, панели управления и панели состояния”. Прочитав его, вы полностью поймете как устроен метод OnCreate класса CMainFrame.

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

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {

// TODO:


 return CMDIFrameWnd::PreCreateWindow(cs);

}

Методы AssertValid и Dump класса CMainFrame
В отладочной версии приложения класс CMainFrame содержит переопределения виртуальных методов AssertValid и Dump. Эти методы определены в базовом классе CObject и используются при отладке приложения:

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

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

#ifdef DEBUG

void CMainFrame::AssertValid() const { ...



Все права на текст принадлежат автору: Александр Вячеславович Фролов, Григорий Вячеславович Фролов.
Это короткий фрагмент для ознакомления с книгой.
Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2Александр Вячеславович Фролов
Григорий Вячеславович Фролов