CodeNet / Платформы / Windows / MFC / Основы программирования с помощью библиотеки Microsoft Foundation Classes
Основы MFC
Иерархия классов MFC
Библиотека MFC содержит большую иерархию классов, написанных на С++. Структура иерархии приведена на рис. 1. В ее вершине находится класс СObject, который содержит различные функции, используемые во время выполнения программы и предназначенные, в частности, для предоставления информации о текущем типе во время выполнения, для диагностики, и для сериализации.
Информация о типе времени выполнения
Если указатель или ссылка ссылается на объект, производный от класса CObject, то в этом случае предусмотрен механизм определения реального типа объекта с помощью макроса RUNTIME_CLASS(). Хотя в С++ имеется механизм RTTI, механизм, реализованный в MFC, намного более эффективен по производительности.
Диагностика
Каждый класс, производный от CObject, может по запросу проверить свое внутреннее состояние и выдать диагностическую информацию. Это интенсивно используется в MFC при отладке.
Сериализация
Сериализация - это механизм, позволяющий преобразовать текущее состояние объекта в последовательный поток байт, который обычно затем записывается на диск, и восстановить состояние объекта из последовательного потока, обычно при чтении с диска. Это позволяет сохранять текущее состояние приложения на диске, и восстанавливать его при последующем запуске.
Основные классы
Некоторые классы порождаются непосредственно от CObject. Наиболее широко используемыми среди них являются CCmdTarget, CFile, CDC, CGDIObject и CMenu. Класс ССmdTarget предназначен для обработки сообщений. Класс СFile предназначен для работы с файлами. Класс CDC обеспечивает поддержку контекстов устройств. Об контекстах устройств мы будем говорить несколько позднее. В этот класс включены практически все функции графики GDI. CGDIObject является базовым классом для различных DGI-объектов, таких как перья, кисти, шрифты и другие. Класс СMenu предназначен для манипуляций с меню. От класса CCmdTarget порождается очень важный класс CWnd. Он является базовым для создания всех типов окон, включая масштабируемые ("обычные") и диалоговые, а также различные элементы управления. Наиболее широко используемым производным классом является CFrameWnd. Как Вы увидите в дальнейшем, в большинстве программ главное окно создается с помощью именно этого класса.
От класса CCmdTarget, через класс CWinThread, порождается, наверное, единственный из наиболее важных классов, обращение к которому в MFC-программах происходит напрямую: CWinApp. Это один из фундаментальных классов, поскольку предназначен для создания самого приложения. В каждой программе имеется один и только один объект этого класса. Как только он будет создан, приложение начнет выполняться.
Функции-члены в MFC
Большинство функций, вызываемых в MFC-программе, являются членами одного из классов, определенных в библиотеке. Большинство функций API доступны через функции-члены MFC. Тем не менее, всегда можно обращаться к функциям API напрямую. Иногда это бывает необходимым, но все же в большинстве случаев удобнее использовать функции-члены MFC.
Глобальные функции в MFC
В библиотеке есть ряд глобальных функций. Все они начинаются с префикса Afx. (Когда MFC только разрабатывалась, то проект назывался AFX, Application Framework. После ряда существенных изменений AFX была переработана в MFC, но прежнее название сохранилось во многих идентификаторах библиотеки и в названиях файлов.) Например, очень часто используется функция AfxMessageBox(), отображающая заранее определенное окно сообщения. Но есть и член-функция MessageBox(). Таким образом, часто глобальные функции перекрываются функциями-членами.
Файл AFXWIN.H
Все MFC-программы включают заголовочный файл AFXWIN.H. В нем, а также в различных вспомогательных файлах, содержатся описания классов, структур, переменных и других объектов MFC. Он автоматически подключает большинство заголовочных файлов, относящихся к MFC, в том числе и WINDOWS.H, в котором определены все функции Windows API и другие объекты, которые используются при традиционном программировании на С и "чистом" API.
Каркас MFC-программы
Теперь мы создадим с помощью MFC небольшое приложение. Оно только отображает стандартное окно Windows, и больше ничего не делает. При закрытии окна приложение завершается. Это приложение послужит основой для всех других приложений, которые мы будем рассматривать.
В простейшем случае программа, написанная с помощью MFC, содержит два класса, порождаемые от классов иерархии библиотеки: класс, предназначенный для создания приложения, и класс, предназначенный для создания окна. Другими словами, для создания минимальной программы необходимо породить один класс от CWinApp, а другой - от CFrameWnd. Эти два класса обязательны для любой программы.
Кроме создания вышеупомянутых классов, в программе также должна быть организована обработка всех сообщений, поступающих от Windows. В данном примере программа еще ничего полезного не делает, поэтому отвечать на каждое сообщение не нужно. MFC обработает все сообщения, которые нас не интересуют. Тем не менее в этом примере присутствует карта откликов на сообщения, или просто карта сообщений. Позже мы рассмотрим ее подробнее.
Ниже приведен исходный код программы. Мы всегда будем помещать декларации классов и их реализацию в отдельные файлы. Это соответствует принятой практике программирования на С++.
Исходные тексты примера
simpwin.hpp
#include <afxwin.h>
// Класс основного окна приложения
class CMainWin: public CFrameWnd {
public:
CMainWin();
// Декларирование карты сообщений
DECLARE_MESSAGE_MAP()
};
// Класс приложения. Должен существовать только
// один экземпляр этого класса.
// Член-функция InitInstance() вызывается при запуске
// приложения.
class CApp: public CWinApp {
public:
BOOL InitInstance();
};
simpwin.cpp
#include <afxwin.h>
#include <string.h>
#include "SIMPWIN.HPP"
// Создание одного и только одного экземпляра
// приложения
CApp App;
// Реализация
BOOL CApp::InitInstance()
{
// Создание главного окна приложения и его
// отображение.
// Член CApp::m_pMainWnd - это указатель на объект
// главного окна.
m_pMainWnd = new CMainWin;
m_pMainWnd->ShowWindow(SW_RESTORE);
m_pMainWnd->UpdateWindow();
// Сигнализируем MFC об успешной инициализации
// приложения.
return TRUE;
}
CMainWin::CMainWin()
{
// Создание окна с заголовком. Используется
// встроенный в MFC
// класс окна, поэтому первый параметр 0.
this->Create(0, "Простейшее приложение на MFC");
}
// Реализация карты сообщений
BEGIN_MESSAGE_MAP(CMainWin /*класс окна*/, CFrameWnd
/*класс-предок*/)
END_MESSAGE_MAP()

Рис. 2. Окно, созданное простейшим приложением на MFC
Для создания стандартного окна в приложении должен наследоваться класс от CFrameWnd. В данном примере он называется CMainWin. Он содержит конструктор и макрос DECLARE_MESSAGE_MAP(). Макрос на самом деле разворачивается в декларацию карты сообщений, которая определяет, какая член-функция класса должна вызываться в ответ на сообщение Windows. Этот макрос применяется для любого окна, в котором обрабатываются сообщения. Он должен быть последним в декларации класса.
Само окно создается в конструкторе с помощью вызова функции Create(). Эта функция используется почти во всех приложениях. Она выполняет действия по созданию окна. В этом примере приведен самый простой случай ее использования. Пока нам нужно знать, что второй параметр определяет заголовок окна, а первый чаще всего равен NULL.
Класс CApp
приложения порождается от CWinApp. Этот класс отвечает за работу программы. В примере используется член-функция со следующим прототипом:virtual BOOL CWinApp::InitInstance();Это виртуальная функция, которая вызывается каждый раз при запуске программы. В ней должны производиться все действия, связанные с инициализацией приложения. Функция должна возвращать TRUE при успешном завершении и FALSE в противном случае. В нашем случае, в функции сначала создается объект класса CMainWin, и указатель на него запоминается в переменной m_pMainWnd. Эта переменная является членом класса CWinThread. Она имеет тип CWnd* и используется почти во всех MFC-программах, потому что содержит указатель на главное окно. В последующих двух строчках через нее вызываются функции-члены окна. Когда окно создано, вызывается функция c прототипом:
BOOL CWnd::ShowWindow(int How);Параметр определяет, каким образом окно будет показано на экране. Наиболее распространенные значения следующие:
| Константа | Действие |
| SW_HIDE | Окно становится невидимым |
| SW_MAXIMIZE | Окно максимизируется |
| SW_MINIMIZE | Окно минимизируетс |
| SW_SHOW | Окно отображается, если было невидимо |
| SW_RESTORE | Окно приводится к нормальному размеру |
При первом вызове в качестве первого параметра функции можно подставить член m_nCmdShow, в котором хранится значение кода отображения окна, переданное в программу при запуске (например, в ярлыке Windows 95 пользователь может определить, как показывать окно при запуске приложения).
Функция UpdateWindow() посылает окну сообщение о том, что его содержимое нужно перерисовать. В дальнейшем мы рассмотрим этот процесс подробнее.
В конце программы помещена реализация карты сообщений:
BEGIN_MESSAGE_MAP(CMainWin /*класс окна*/, CFrameWnd /*класс-предок*/) END_MESSAGE_MAP()Первый макрос всегда имеет два параметра, первый - класс окна, второй - класс, от которого порожден класс окна. В данном примере карта сообщений пустая, то есть все сообщения обрабатывает MFC.
Подробнее о создании масштабируемых окон
В примере была использована функция Create(), которая на самом деле имеет много параметров. Ее прототип таков:
BOOL CFrameWnd::Create(
LPCSTR ClassName, // Имя Windows-класса окна
LPCSTR Title, // Заголовок
DWORD Style = WS_OVERLAPPEDWINDOW, // Стиль
const RECT &XYSize = rectDefault, // Область
CWnd *Parent = 0, //Окно-предок
LPCSTR MenuName = 0, //Имя ресурса меню
DWORD ExStyle = 0, //Расширенные стили
CCreateContext *Context = 0 // Доп. данные
);
Первый параметр, ClassName, определяет имя класса окна для
оконной подсистемы Windows.
Обычно его не нужно явно задавать, так как MFC выполняет всю необходимую
черновую работу. В данных методических указаниях
мы не будем использовать своих классов окон.
Параметр Style задает
стиль окна. По умолчанию создается стандартное
перекрываемое окно. Можно задать свой стиль,
объединив с помощью операции "или" несколько
констант из приведенных ниже:
| Константа | Элемент окна |
| WS_OVERLAPPED | Стандартное окно с рамкой |
| WS_MAXIMIZEBOX | Кнопка максимизации |
| WS_MINIMIZEBOX | Кнопка минимизации |
| WS_SYSMENU | Системное меню |
| WS_HSCROLL | Горизонтальная полоса прокрутки |
| WS_VSCROLL | Вертикальная полоса прокрутки |
В дальнейшем мы не будем так подробно расписывать здесь все возможные значения констант, потому что всегда можно обратиться к справке Visual C++ и получить подробную информацию.
Начальное положение и размер окна определяются параметром XYSize. Это структура, которая определяет экранные координаты левого верхнего и правого нижнего угла прямоугольника, в котором будет отображено окно.
Все остальные параметры, которые мы будем использовать, будут рассмотрены в соответствующих разделах.
Оставить комментарий
Комментарии




Хотя бы так :) :
int main()
{
}




А ты возми скопируй эту ошибку - error LNK2001
в окошко поиска MSDN, найди ёё и сразу тебе станет понятно что не так у тебя настроенно или чего не хватает...






PS Иди на сайт www.firststeps.ru - там все понятней расписано, чем здесь
;)


libcmt.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Release/russciy.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
?????????????????????????????????????????????
