Шаг 1 - Минимальный проект

Создание проекта

Создадим проект. Здесь все просто - выберем Win32 Application, а AppWizard пока отложим. Если Вы раньше программировали на OWL(я так и делал) или вообще не программировали под Windows(так я тоже делал), результаты работы этого шамана приведут в уныние даже настоящего мужчину. Все работает, но как ? Выбираем File New и переключаемся на вкладку Project. Введя имя проекта нажимаем OK.

1_1.gif (9820 b)

Появится окошко мастера проектов. В нем мы выберем пустой проект - An Empty Project. И нажмем кнопочку Finish для подтверждения своего выбора. IDE VC++ начнет генерацию серии файлов необходимых для работы с проектом и его сборки.

1_2.gif (4681 b)

Добавим в наш проект файл, в котором будет исходный код. Мы же с вами выбрали пустой проект и нам нужен cpp файл в этом проекте. Вам нужно перейти на вкладку FileView и щелкнуть правой кнопкой мыши на step1 files. Выбрать пункт меню Add File to Project.

1_3.gif (2606 b)

Появится диалоговое окно добавления файла в проект Insert Files Into Project. У нас файла нет. Поэтому надо просто написать его имя и нажать OK.

1_4.gif (4387 b)

Теперь нужно настроить проект так, чтобы он использовал MFC. Это очень важно. MFC находится в DLL файлах. И если наш проект будет использовать MFC, мы должны это указать для того, чтобы компилятор мог подключить необходимые LIB файлы со ссылками на функции в DLL. Если этого не сделать, то проект не соберется. В окне Build будут такие ошибки.

Linking...
nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
Release/step1.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

Нам нужно пойти в меню Project, а потом Setting.

1_5.gif (2534 b)

Вот здесь и вот так. Не забудем проверить поддержку MFC для всех типов (Setting For).

1_6.gif (6252 b)

Создаем код

В нашем файле запишем код.


//	Step1.cpp
//	Сайт Первые шаги (http://www.firststeps.ru/)
//	Каев Артем (1999-2001)
//	создано 1999 г.
//	обновление 24.06.2001

#include "afxwin.h" // MFC Основные и стандартные компоненты

class CMainWnd : public CFrameWnd
{
public:
	CMainWnd();	// Конструктор по умолчанию
};

CMainWnd::CMainWnd()
{
	Create(NULL,"Step1",WS_OVERLAPPEDWINDOW,rectDefault,
		NULL,NULL);	// Создать окно программы
}

class CMyApp : public CWinApp
{
public:
	CMyApp();			//конструктор по умолчанию
	virtual BOOL InitInstance();//стандартная инициализация
};

CMyApp::CMyApp() // конструктор главного класса приложения
{}

BOOL CMyApp::InitInstance() // стандартная инициализация
{
	m_pMainWnd=new CMainWnd();	// создать класс окна
	ASSERT(m_pMainWnd);	// проверить его правильность
	m_pMainWnd->ShowWindow(SW_SHOW);// Показать окно
	m_pMainWnd->UpdateWindow();	// Обновить окно
	return TRUE;		// Вернуть что все нормально
};

CMyApp theApp;	// запуск приложения

Теперь попробуем во всем этом разобраться:

Первая строка включает необходимый файл заголовка с описанием классов, функций и переменных, он ссылается ещё на кучу других, а они на другие и так до windows.h. Вот почему windows.h нам и не понадобился. В каждой программе на С++ есть главная функция программы, в Dos это main(), в Windows - WinMain(). Эта функция обеспечивает запуск программы. Она проверяет операционную среду, выполняет некоторые настройки и, если все нормально, непосредственно передает управление вашему коду. Но у нас-то её нет ! В MFC есть класс CWinApp, который и включает главную функцию программы. Естественно, что в приложении она может быть только одна.

Мы с вами создали CMyApp, как производный от CWinApp и унаследовали все его свойства, методы и т.д. В своем классе мы объявили конструктор по умолчанию (без параметров). Он необходим, иначе вы не скомпилируете программу. Здесь все логично мы в коде объявляем статический класс производный от нашего CMyApp в строке CMyApp theApp;. Как видите он тоже без параметров.

CWinApp имеет виртуальный метод InitInstance(). Виртуальный он потому, что это только заглушка. Мы с вами написали свой метод в виде функции. Этот метод должен возвращать ненулевое значение, если инициализация прошла нормально, а иначе 0. Он предназначен, чтобы вы могли описать класс окна программы и отобразить окно на экране.

Дальше мы должны знать, что в CWinApp есть указатель на класс окна - m_pMainWnd. Этот указатель общедоступный и вы могли догадаться, так как он нигде не объявлен. Ситуация с ним такая - Если по окончанию InitInstance() он будет равен нулю, то приложение завершится. И естественно, когда приложение завершается он обнуляется. Строкой m_pMainWnd=new CMainWnd(); мы присваиваем этому указателю адрес класса CMainWnd, который порожден от CFrameWnd. Последний из них отвечает за работу окна программы в стиле одного документа (SDI - single document interface). Он создает окно, управляет сообщениями и т.д. В конструкторе этого класса мы вызвали функцию создания окна, в которой указали кучу параметров.

Первый параметр указывает на класс Windows, он нам не нужен, пока не нужен и поэтому NULL, дальше указали имя окна программы, WS_OVERLAPPEDWINDOW указывает, что окно имеет заголовок и рамку, rectDefault говорит о том, что размер окна присвоит Windows, и еще некоторые параметры, ими всеми мы займемся позже. Далее следует ASSERT(m_pMainWnd);. Очень хорошая и простая функция. Если создание объекта произойдет, то m_pMainWnd будет отличаться от нуля и всё будет нормально, а иначе вы получите сообщение о том, что в таком файле на такой-то строке ошибка. Вообще это намного лучше, чем смотреть дизассемблированный код или оказаться в исходном коде библиотеки MFC, если не повесим Windows конечно.

Так как m_pMaiWnd это сейчас тоже что и CMainWnd, то мы используем это переменную, чтобы вывести на экран окно:

m_pMainWnd->ShowWindow(SW_SHOW);

И показать окно.

m_pMainWnd->UpdateWindow();

Вот и все ! При запуске приложения вот такое окно мы получим.

1_7.gif (1032 b)

Шпаргалка

  1. Включить описание классов MFC:
    #include <afxwin.h>
  2. Объявить класс производный от CWinApp:
    class CMyApp : public CWinApp
    .......
  3. Объявить переменную этого класса:
    CMyApp theApp;
  4. Объявить класс производный от CFrameWnd:
    class CMainWnd : public CFrameWnd
    .......
  5. В конструкторе класса производного от CFrameWnd вызвать функцию Create() и выбрать параметры в ней на свой вкус:
    Create(NULL,"Step1",WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL);
  6. Переопределить функцию InitInstance() класса производного от CWinApp.
  7. В функции InitInstance() создать объект производный от CFrameWnd и присвоить указателю m_pMainWnd адрес этого объекта.
    m_pMainWnd=new CMainWnd();
  8. Проверить указатель на корректность:
    ASSERT(m_pMainWnd);
  9. Вызвать функции класса производного от CFrameWnd для прорисовки на экране:
    m_pMainWnd->ShowWindow(SW_SHOW);// Показать окно
    m_pMainWnd->UpdateWindow();	// Обновить окно
    	
  10. Закончить выполнение функции, убедив MFC, что все нормально:
    return TRUE;
  11. Откомпилировать, собрать и запустить программу, насладившись пустым окном и именем Step1.

Загрузить проект | Следующий Шаг | Оглавление
Автор Каев Артем - 29.08.99 (обновлено 24.06.2001)