Microsoft Visual C++ и MFC. Программирование для Win95 и WinNT

         

Окно Project Workspace


Microsoft Visual C++ версии 4.0 имеет удобные средства для просмотра исходных текстов файлов проекта, кодов классов приложения, ресурсов, а также для получения справочной информации.

Откройте окно Project Workspace. Обычно оно расположено в левой части экрана, но вы можете переместить его в другое место и даже закрыть. Если окно закрыто, откройте его. Для этого выберите из меню View строку Project Workspace. Окно Project Workspace состоит из нескольких страниц. Вы можете открыть их, нажимая на соответствующие закладки. Количество страниц зависит от того, установлена ли справочная система и открыт ли проект.

Закладка

Описание

ClassView. Средство для просмотра и редактирования классов приложения

ResourceView. Позволяет просматривать и редактировать ресурсы приложения

FileView. Выполняет просмотр файлов приложения

InfoView. Справочная система Microsoft Visual C++. В нее включена информация о языке Си, Си++, библиотеки классов MFC, функций програмного интерфейса Windows

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

Чтобы создать новый файл, вы можете нажать кнопку New Source File (

) в стандартной панели управления или выбрать из меню File строку New, а затем из списка в открывшейся панели New выбрать строку Text File. Откроется новое окно текстового редактора. В нем надо набрать исходный текст приложения, представленного листингом 2.1. Сохраните набранный текст в файле под именем MFHello.cpp в каталоге проекта. Для этого выберите из меню File строку Save As.

Листинг 2.1. Файл MFHello.cpp

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

#include <afxwin.h>

//=====================================================

// Класс CMFHelloApp

// Наследуем от базового класса CWinApp главный

// класс приложения CMFHelloApp

//=====================================================


class CMFHelloApp : public CWinApp

{

public:

      // Мы будем переопределять метод InitInstance,

      // предназначенный для инициализации приложения

      virtual BOOL InitInstance();

};

 

// Создаем объект приложение класса CMFHelloApp

CMFHelloApp MFHelloApp;

 

//=====================================================

// Метод InitInstance класса CMFHelloApp

// Переопределяем виртуальный метод InitInstance

// класса CWinApp. Он вызывается каждый раз при запуске

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

//=====================================================

BOOL CMFHelloApp::InitInstance()

{

      AfxMessageBox("Hello, MFC!");

      return FALSE;

}

Единственный файл с исходным текстом приложения создан и его надо включить в проект. Выберите из меню Insert строку Files into Project. На экране появится диалоговая панель Insert Files into Project. Выберите файл MFHello.cpp и нажмите кнопку Add. Диалоговая панель закроется. Просмотрите еще раз папку с файлами проекта. Теперь в ней расположен файл MFHello.cpp (рис. 2.10).



Рис. 2.10. Файлы проекта MFHello

Откройте страницу ClassView в окне Project Workspace. В ней отображаются все классы, определенные в приложении и все глобальные переменные. Для каждого класса приложения можно видеть входящие в него элементы (рис. 2.11).

На странице ClassView отображается древовидная структура классов вашего приложения. Когда вы в первый раз открываете ClassView, структура классов отображается в виде закрытой папки
. Чтобы ее открыть, щелкните два раза левой кнопкой мыши по изображению папки или один раз по символу
, расположенному левее папки. В открытой папке символом
 представлены классы приложения и еще одним символом папки глобальные объекты приложения. Папку с глобальными объектами можно открыть также как папку с классами. Вы можете открыть и сами классы. Так вы сможете просмотреть элементы класса - методы и данные. Методы обозначаются символом
, а данные символом
. Если методы или данные объявлены как protected, перед ними отображается символ
, а если как private - символ
.



В нашем проекте определен только один класс CMFHelloApp. В класс CMFHelloApp входит метод InitInstance. Кроме того, определена одна глобальная переменная MFHelloApp.



Рис. 2.11. Классы проекта MFHello

Если вы используете в приложении классы или функции библиотеки классов MFC, то проект надо настроить. Выберите из меню Build строку Settings или нажмите комбинацию клавиш <Alt+F7>. На экране появится диалоговая панель Project Settings. В этой панели расположены несколько страниц, позволяющих настроить различные характеристики проекта.

Откройте страницу General. Мы привели внешний вид этой страницы на рисунке 2.12. Обратите внимание на список Microsoft Foundation Classes. По умолчанию из этого списка выбрана строка No Using MFC. Она означает, что приложение не будет использовать библиотеку MFC. Так как в приложении MFHello и всех остальных приложениях, описанных в этой книге, задействованы классы MFC, выберите из списка Microsoft Foundation Classes строку Use MFC in a Shared Dll (mfc40(d).dll) или строку Use MFC in a Static Library.

Что же выбрать - Use MFC in a Shared Dll или Use MFC in a Static Library? Оказывается программные коды библиотеки классов MFC могут использоваться приложением двумя способами. Код библиотеки MFC либо непосредственно записывается в выполнимый файл приложения, либо вызывается по мере необходимости из отдельной dll-библиотеки.

Использование для приложения dll-библиотеки немного ускоряет процесс построения проекта и позволяет создавать выполнимые файлы значительно меньшего размера. Однако сам по себе такой выполнимый файл работать не будет. Для него необходима dll-библиотека. Поэтому если приложение устанавливается и на других компьютерах, его надо распространять вместе с dll-библиотекой.

Для MFC версии 4.0 dll-библиотека хранится в файлах Mfc40d.dll и Mfc40.dll. В файле Mfc40d.dll находится отладочная версия MFC, а в файле Mfc40.dll отладочная информация отсутствует. В ходе установки Visual C++ эти dll-библиотеки записываются в системный каталог операционной системы.



Если вы забудете указать, что приложение использует MFC, то во время построения проекта на этапе установления связи (Linking...) будут обнаружены ошибки:

error LNK2001: unresolved external symbol __endthreadex

error LNK2001: unresolved external symbol __beginthreadex

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



Рис. 2.12. Диалоговая панель Project Settings

Если вы все сделали, постройте проект. Для этого вы можете выбрать из меню Build строку Build MFHello.exe - создать выполнимый файл MFHello.exe или строку Rebuild All - заново оттранслировать все исходные файлы проекта. Если в ходе построения выполнимого файла приложения нашего проекта возникли ошибки, исправьте их и заново оттранслируйте проект. После успешного построения проекта запустите полученное приложение, выбрав из меню Build строку Execute MFHello.exe.

На экране появится маленькая диалоговая панель (рис. 2.13). Название этой диалоговой панели соответствует названию выполнимого файла приложения MFHELLO. В диалоговой панели отображается текстовое сообщение “Hello, MFC!”, пиктограмма с восклицательным знаком внутри треугольника и кнопка OK. Как только вы нажмете кнопку OK, диалоговая панель закрывается и приложение завершит свою работу.



Рис. 2.13. Приложение MFHello

Посмотрим, как работает приложение MFHello на уровне исходного текста. Первая строка, не считая строки комментария, содержит директиву препроцессора #include, которая включает файл afxwin.h:

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

#include <afxwin.h>

В этом файле определены классы, методы, константы и другие структуры для библиотеки классов MFC. Кроме того включаемый файл afxwin.h автоматически подключает другой включаемый файл windows.h уже известный вам по предыдущим томам серии библиотеки системного программиста. Поэтому даже если из приложения будут вызываться функции стандартного программного интерфейса Windows файл windows.h включать не надо.



В предыдущих томах серии “Библиотека системного программиста”, посвященных программированию в среде операционных систем Windows и Windows 95, мы рассказывали о функции WinMain, которая является главной функцией приложения. Эта функция вызывается, когда пользователь или операционная система запускает приложение. Все приложения, которые мы рассматривали до сих пор содержали функцию WinMain:

// Самое простое приложение Windows

#include <windows.h>

int WINAPI WinMain(

 

    HINSTANCE  hInstance,

    HINSTANCE  hPrevInstance,

    LPSTR  lpCmdLine,            

    int  nShowCmd     

   )

{

      // Отображаем на экране небольшую панель с сообщением

      MessageBox(NULL,"Hello, world", "Text Message", MB_OK);

     

      // Завершаем приложение

      return 0;

}

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

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

Класс CWinApp выполняет все действия, которые обычно выполняла функция WinMain - инициализирует приложение, обрабатывает сообщения и завершает приложение. Для этого класс CWinApp включает виртуальные методы InitApplication, InitInstance, Run и ExitInstance.

Чтобы выполнить инициализацию приложения, функция WinMain вызывает методы InitApplication и InitInstance для объекта главного класса приложения. Метод InitApplication выполняет инициализацию на уровне приложения. Вы можете переопределить этот метод в своем приложении. Метод InitInstance выполняет инициализацию каждой запущенной копии приложения. Обычно метод InitInstance создает главное окно приложения. Вы обязательно должны переопределить этот метод в своем приложении. Остальные методы, например Run, можно не переопределять.



Затем функция WinMain начинает обрабатывать цикл сообщений. Для этого вызывается метод Run. Вы можете переопределить этот метод, чтобы реализовать собственный цикл обработки сообщений.

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

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

//=====================================================

// Класс CMFHelloApp

// Наследуем от базового класса CWinApp главный

// класс приложения CMFHelloApp

//=====================================================

class CMFHelloApp : public CWinApp

{

public:

      // Мы будем переопределять метод InitInstance,

      // предназначенный для инициализации приложения

      virtual BOOL InitInstance();

};

Мы наследуем класс CMFHelloApp от базового класса CWinApp. При этом базовый класс указан как public. Это означает, что в программе доступны все элементы базового класса CWinApp, объявленные как public. Мы можем вызывать методы класса CWinApp для объектов класса CMFHelloApp и обращаться к элементам данных класса CWinApp.

В определении класса CMFHelloApp мы объявляем виртуальный метод InitInstance. Он будет нами переопределен. Изначально метод InitInstance определен в классе CWinApp. Метод InitInstance отвечает за инициализацию приложения. Он вызывается каждый раз, когда пользователь запускает приложение. Если пользователь запустит приложение несколько раз, то метод InitInstance будет вызываться каждый раз.

Метод InitInstance обязательно должен быть переопределен в вашем главном классе приложения. Остальные виртуальные методы можно оставить без изменения.

Сразу после объявления главного класса приложения мы создаем объект этого класса - MFHelloApp. Вы должны определить объект главного класса приложения как глобальный. В этом случае он будет создан сразу при запуске приложения и сможет управлять всей работой приложения. После создания глобальных объектов вызывается функция WinMain, определенная в классе CWinApp. Она выполняет свои обычные функции - регистрирует классы окон, создает окно, и т. д.



Нельзя создавать два и более объектов класса, наследованного от базового класса CWinApp. Каждое приложение должно иметь один и только один объект главного класса приложения:

// Создаем объект приложение класса CMFHelloApp

CMFStartApp MFHelloApp;

Метод InitInstance главного класса приложения CMFHelloApp служит для инициализации. Он вызывается автоматически каждый раз, когда запускается очередная копия приложения. Мы используем метод InitInstance чтобы вывести на экран компьютера диалоговую панель с сообщением “Hello, MFC!”. Для этого вызываем функцию AfxMessageBox:

//=====================================================

// Метод InitInstance класса CMFHelloApp

// Переопределяем виртуальный метод InitInstance

// класса CWinApp. Он вызывается каждый раз при запуске

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

//=====================================================

BOOL CMFHelloApp::InitInstance()

{

      AfxMessageBox("Hello, MFC!");

      return FALSE;

}

Функция AfxMessageBox определена в библиотеке классов MFC. Вместо функции AfxMessageBox вы можете воспользоваться хорошо известной вам функцией MessageBox программного интерфейса Windows.

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

::MessageBox(NULL,"Hello, world!", "Message", MB_OK);

В конце метода InitInstance мы вызываем оператор return и возвращаем значение FALSE. Приложение сразу завершается. Если метод InitInstance вернет значение TRUE, приложение продолжит работу и приступит к обработке очереди сообщений. Более подробно о методе InitInstance и свойствах базового класса CWinApp вы узнаете позже, когда мы будем рассматривать средства автоматизированной разработки приложений.


Содержание раздела