Microsoft visual C++ и MFC.© Александр Фролов, Григорий ФроловТом 24, М.: Диалог-МИФИ, 1993. Первое приложение MFCПервое приложение MFHello, которое мы создадим с использованием библиотеки классов MFC будет очень простое. Единственное, что оно будет делать - это отображать на экране маленькую диалоговую панель, содержащую строку “Hello, MFC!”. Исходный текст приложения, представленный в листинге 2.1, состоит всего из двенадцати строк, не считая строк комментариев. В нашем первом приложении мы использовали единственный класс библиотеки MFC, наследованный от базового класса CWinApp XE "CWinApp" . Чтобы создать новый проект, выберите из меню File строку New. На экране появится диалоговая панель New, содержащая одноименный список New и две кнопки. Выберите из списка New строку Project Workspace. Откроется диалоговая панель New project workspace (рис. 4.1 из главы “Приложение с главной диалоговой панелью”). В ней вы должны указать тип приложения, который будет разрабатываться, имя проекта и расположение каталога для записи в него файлов проекта. Самые простые приложения с использованием библиотеки классов MFC мы будем создавать без использования автоматизированных средств разработки приложений MFC AppWizard. Поэтому в качестве типа приложения выберите из списка Type строку Application. В поле Name введите имя нового проекта. Наш первый проект мы назвали именем MFHello. Расположение каталога для размещения файлов проекта отображается в поле Location. По умолчанию каталог проекта называется точно также как сам проект и будет размещен в каталоге Projects среды разработки Visual C++. Вы можете выбрать для проекта любой другой каталог, если нажмете на кнопку Browse. Теперь нажмите кнопку Create. Будут созданы служебные файлы проекта. Они получат названия MFHello.mak, MFHello.ncb и MFHello.mdp. Файл MFHello.mdp является основным файлом проекта. В этих файлах определяется, какие исходные файлы содержит проект, указываются характеристики создаваемого приложения, конфигурация самой среды разработки Visual C++. Окно Project WorkspaceMicrosoft Visual C++ версии 4.0 имеет удобные средства для просмотра исходных текстов файлов проекта, кодов классов приложения, ресурсов, а также для получения справочной информации. Откройте окно Project Workspace. Обычно оно расположено в левой части экрана, но вы можете переместить его в другое место и даже закрыть. Если окно закрыто, откройте его. Для этого выберите из меню View строку Project Workspace. Окно Project Workspace состоит из нескольких страниц. Вы можете открыть их, нажимая на соответствующие закладки. Количество страниц зависит от того, установлена ли справочная система и открыт ли проект.
Откройте окно Project Workspace и выберите страницу FileView. Так как сначала в проекте нет ни одного файла, вы увидите пустую папку проекта. Теперь надо создать новый текстовый файл и набрать в нем исходный текст нашего первого приложения. Чтобы создать новый файл, вы можете нажать кнопку New Source File ( Листинг 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 XE "ClassView" в окне Project Workspace. В ней отображаются все классы, определенные в приложении и все глобальные переменные. Для каждого класса приложения можно видеть входящие в него элементы (рис. 2.11). На странице ClassView отображается древовидная структура классов вашего приложения. Когда вы в первый раз открываете ClassView, структура классов отображается в виде закрытой папки В нашем проекте определен только один класс 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 XE "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 XE "afxwin.h" : // Включаемый файл для MFC #include <afxwin.h> В этом файле определены классы, методы, константы и другие структуры для библиотеки классов MFC. Кроме того включаемый файл afxwin.h автоматически подключает другой включаемый файл windows.h уже известный вам по предыдущим томам серии библиотеки системного программиста. Поэтому даже если из приложения будут вызываться функции стандартного программного интерфейса Windows файл windows.h XE "windows.h" включать не надо. В предыдущих томах серии “Библиотека системного программиста”, посвященных программированию в среде операционных систем Windows и Windows 95, мы рассказывали о функции WinMain XE "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 XE "CWinApp" . В каждом приложении определяется главный класс приложения, наследуемый от базового класса CWinApp. Обычно этот класс называют CProjectApp, где в качестве Project указывают имя проекта. Приложение должно иметь только один объект главного класса приложения, наследованного от класса CWinApp. Класс CWinApp выполняет все действия, которые обычно выполняла функция WinMain - инициализирует приложение, обрабатывает сообщения и завершает приложение. Для этого класс CWinApp включает виртуальные методы InitApplication XE "CWinApp:InitApplication" , InitInstance XE "CWinApp:InitInstance" , Run XE "CWinApp:Run" и ExitInstance XE "CWinApp: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 XE "CWinApp: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 XE "AfxMessageBox" определена в библиотеке классов MFC. Вместо функции AfxMessageBox вы можете воспользоваться хорошо известной вам функцией MessageBox программного интерфейса Windows. Когда вы вызываете из приложения, созданного с использованием классов MFC, функции программного интерфейса Windows, необходимо указывать перед именем функции символы ::. Так, вызов функции MessageBox мог бы выглядеть следующим образом: ::MessageBox(NULL,"Hello, world!", "Message", MB_OK); В конце метода InitInstance мы вызываем оператор return и возвращаем значение FALSE. Приложение сразу завершается. Если метод InitInstance вернет значение TRUE, приложение продолжит работу и приступит к обработке очереди сообщений. Более подробно о методе InitInstance и свойствах базового класса CWinApp вы узнаете позже, когда мы будем рассматривать средства автоматизированной разработки приложений. |