Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VC_Lect.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
15 Мб
Скачать
☆

9.1.Приложение, основанное на диалоговом окне

MFC AppWizard (exe) → Dialog Based.

Приложение, имеющее одно диалоговое окно (рис.1.). В этом окне можно, естественно, располагать другие управляющие элементы: поля ввода, кнопки, списки и т.д. В качестве примера такого приложения можно привести проект Fire, который входит в состав примеров (samples), поставляемых вместе с Microsoft Visual Studio 6.0. Проект Fire можно также использовать как иллюстрацию использования вкладок (класс CTabCtrl) и других управляющих элементов. В такое приложение можно также добавлять обработчики событий, контекстное меню. В целом проект Fire весьма поучителен.

Рис.1. Приложение, основанное на диалоговом окне

Дадим краткий обзор приложения Fire как основанного на диалоговом окне. В проект входят такие основные файлы (и классы): Fire.cpp, FireDlg.cpp и FireWnd.cpp.

В файле Fire.cpp описывается и определяется объект theApp класса CFireApp, который –объект – и представляет собой собственно программу. Класс CFireApp является наследником класса CWinApp, который имеется в любом приложении, построенном на базе библиотеки MFC.

Когда приложение запускается на выполнение, то в первую очередь вызывается функция WinMain(), которая имеется в любом приложении Windows, но, как и в данном приложении, она скрыта в каркасе приложения. Вы можете увидеть ее вызов, если запустите приложение в режиме трассировки с заходом в функции (команда отладки F11). Еще раньше, до вызова функции WinMain(), в соответствии с семантикой языка С++ конструируется объект theApp, так как он описан в глобальной области, и, следовательно, вызывается его конструктор. Таким образом, первым после запуска программы на выполнение выполняется код конструктора класса CFireApp. Вы можете в этом убедиться сами, если добавите точку прерывания в этот конструктор или, еще лучше, выведете сообщение с использованием макроса TRACE.

В данном приложении Fire класс CFireApp объявлен в файле Fire.h, содержимое которого следующее (комментарии и несущественные макросы в листинг не включены):

// fire.h : главный заголовочный файл для приложения FIRE

#include <afxcmn.h>

#include "resource.h"

class CFireApp : public CWinApp

{

public:

CFireApp();

//{{AFX_VIRTUAL(CFireApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

DECLARE_MESSAGE_MAP()

};

Как видно из листинга файла Fire.h, в классе CFireApp имеется только конструктор и важная виртуальная функция InitInstance(), которая вызывается функцией WinMain(). Отметим, что до сих пор никакого окна программы еще не создано.

Посмотрим на реализацию класса CFireApp, которая приведена в файле Fire.cpp (комментарии и несущественные макросы в листинг не включены):

// fire.cpp : определяет поведение приложения

#include "stdafx.h"

#include "fire.h"

#include "firedlg.h"

BEGIN_MESSAGE_MAP(CFireApp, CWinApp)

//{{AFX_MSG_MAP(CFireApp)

//}}AFX_MSG

ON_COMMAND(ID_HELP, CWinApp::OnHelp)

END_MESSAGE_MAP()

CFireApp::CFireApp()

{

// Добавьте сюда код конструирования объекта

// Всю важную инициализацию включите в функцию InitInstance

}

CFireApp theApp;

BOOL CFireApp::InitInstance()

{

DWORD dwVersion = ::GetVersion();

BOOL bWin31 = (dwVersion > 0x80000000 && (BYTE)dwVersion < 4);

if (bWin31)

{

AfxMessageBox(IDP_WIN32S);

return FALSE;

}

Enable3dControls();

LoadStdProfileSettings();

CFireDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// Добавьте сюда код, который должен выполняться при закрытии // диалогового окна с помощью клавиши ОК

}

else if (nResponse == IDCANCEL)

{

// Добавьте сюда код, который должен выполняться при закрытии // диалогового окна с помощью клавиши CANCEL

}

return FALSE;

}

Обратите внимание на то, что в функции InitInstance() определяется объект dlg класса CFireDlg диалогового окна и показывается окно путем вызова функции dlg.DoModal(). Если бы наше приложение базировалось не на диалоговом окне, то код функции InitInstance() был бы другим. До сих пор весь тот код, который мы рассмотрели (код в файлах Fire.h и Fire.cpp), был сгенерирован мастером и у нас не было необходимости в его модификации. Однако в каком-либо другом приложении у нас может появиться необходимость в модификации этого кода.

Теперь обратим свое внимание на файл firedlg.h, в котором объявляется класс диалогового окна нашей программы – самый важный класс:

// firedlg.h : заголовочный файл для класса окна диалога

#include "FireWnd.h"

class CFireDlg : public CDialog

{

public:

CFireDlg(CWnd* pParent = NULL); // стандартный конструктор

//{{AFX_DATA(CFireDlg)

enum { IDD = IDD_FIRE_DIALOG };

CSpinButtonCtrl m_SettingCtrl;

CEdit m_Setting;

CButton m_Apply;

CTreeCtrl m_Property;

CSliderCtrl m_Height;

CTabCtrl m_Color;

CProgressCtrl m_Burn;

CFireWnd m_FireWnd;

int m_nSetting;

//}}AFX_DATA

int m_nSettingMin;

int m_nSettingMax;

//{{AFX_VIRTUAL(CFireDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

protected:

HICON m_hIcon;

UINT m_uTimerID;

// Generated message map functions

//{{AFX_MSG(CFireDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnApply();

afx_msg void OnPropertySelchanged(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnColorSelchange(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnDestroy();

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnSettingChange();

afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);

afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

Прежде всего отметим, что «вручную» в файл были добавлены только две строки: описания член-данных m_nSettingMin и m_nSettingMax, а также директива #include "FireWnd.h". Весь остальной код в этом файле был сгенерирован мастером.

В секции тела класса, заключенной между строками //{{AFX_DATA(CFireDlg) и //}}AFX_DATA, описаны переменные, ассоциированные с управляющими элементами диалогового окна с помощью мастера ClassWizard.

В секции тела класса, заключенной между строками //{{AFX_MSG(CFireDlg) и //}}AFX_MSG, мастер разместил объявления функций таблицы сообщений, т.е. обработчиков сообщений Windows.

Реализация класса CFireDlg находится в файле Filedlg.cpp и, в контексте рассмотрения последовательности выполнения кода приложения, для нас важно то, что, после выполнения кода конструктора класса CFireDlg вызывается функция CFireDlg::OnInitDialog(). Если «забыть» о функции CFireDlg::OnPaint(), то можно сказать, что по завершении функции CFireDlg::OnInitDialog() на экране наконец-то появляется диалоговое окно и вот теперь уже можно говорить, что «программа выполняется».

Если Вы посмотрите на код функции CFireDlg::OnInitDialog(), то увидите, что в ней выполняется инициализация управляющих элементов диалогового окна: создаются вкладки, присваиваются начальные значения элементам и т.п. Дальнейшая логика работы приложения зависит от действий пользователя.

В данном приложении имеется еще один интересный класс CFireWnd, который ассоциирован с управляющим элементом Picture (идентификатор IDC_FIRE) и предназначен для изображения пламени – «изюминки» данного приложения. Конструктор этого класса вызывается каркасом приложения при конструировании диалогового окна, так же как и конструкторы всех других управляющих элементов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]