|
Можно ли сдавать один и тот же тест несколько раз? |
Библиотека классов MFC среды проектирования Visual Studio .NET. Диалоги
Приложения-диалоги
Базовым классом любого Windows-приложения, основанного на оконном интерфейсе, является класс cWinApp.
При создании приложения-диалога мастер построения MFC-приложения добавляет в проект два класса:
- класс приложения, производный от cWinApp ;
- класс диалога, производный от CDialog.
Класс приложения имеет следующее объявление и реализацию:
// Заголовочный файл
class CD1App : public CWinApp
{public:
CD1App();
public:
virtual BOOL InitInstance(); // Первый
// выполняемый метод
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CD1App theApp; // Переменная - приложение
// Файл реализации D1.cpp
#include "stdafx.h"
#include "D1.h"
#include "D1Dlg.h"
// CD1App
BEGIN_MESSAGE_MAP(CD1App, CWinApp) // Обрабатываемые события
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
CD1App::CD1App(){ } // Конструктор
CD1App theApp;
BOOL CD1App::InitInstance()
{ CWinApp::InitInstance();
AfxEnableControlContainer();
SetRegistryKey(_T("Local AppWizard-Generated
Applications"));
CD1Dlg dlg; // Создание объекта диалога
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal(); // Отображение
// диалога
if (nResponse == IDOK) { }
else if (nResponse == IDCANCEL) { }
return FALSE; // Завершение приложения
}
Класс диалога имеет следующее объявление и реализацию:
// Заголовочный файл
class CD1Dlg : public CDialog
{public:
CD1Dlg(CWnd* pParent = NULL); // Конструктор
enum { IDD = IDD_D1_DIALOG }; // Ресурс диалога
protected:
// Поддержка DDX/DDV:
virtual void DoDataExchange(CDataExchange* pDX);
// Реализация
protected:
HICON m_hIcon;
// Функции таблицы обрабатываемых событий
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
};
// Файл реализации D1Dlg.cpp
#include "stdafx.h"
#include "D1.h"
#include "D1Dlg.h"
class CAboutDlg : public CDialog // Класс
// вспомогательного диалога
{public: CAboutDlg();
enum { IDD = IDD_ABOUTBOX }; // Ресурс диалога
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { }
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX);}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// Класс окна диалога приложения
CD1Dlg::CD1Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CD1Dlg::IDD, pParent)
{ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }
void CD1Dlg::DoDataExchange(CDataExchange* pDX)
{ CDialog::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CD1Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()
// Методы обработки событий
BOOL CD1Dlg::OnInitDialog()
{ CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE); // Указатель
// на системное меню
if (pSysMenu != NULL) // Добавление пунктов к
{ CString strAboutMenu; //системному меню
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{ pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,
IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Определение крупной
// пиктограммы
SetIcon(m_hIcon, FALSE); // Определение мелкой пиктограммы
return TRUE;
}
void CD1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{ if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{ CAboutDlg dlgAbout; dlgAbout.DoModal(); }
else { CDialog::OnSysCommand(nID, lParam); }
}
void CD1Dlg::OnPaint() { CDialog::OnPaint(); }
HCURSOR CD1Dlg::OnQueryDragIcon() // Запрос курсора
{ return static_cast<HCURSOR>(m_hIcon); }
Листинг
19.1.
Для отображения окна диалога следует:
- создать ресурс диалога, имеющий конкретный вид диалогового окна, и разместить в нем требуемые элементы управления (каждый элемент управления также определяется своим идентификатором ресурса);
- создать класс, наследуемый от класса CDialog (или производного от него), и связать создаваемый класс с ресурсом диалога.
Связывание командных кнопок с методами - обработчиками событий и идентификаторов ресурсов элементов управления с переменными выполняется в редакторе ресурсов.
Для назначения кнопке метода обработчика события можно выполнить на ней двойной щелчок мышью (для события BN_CLICKED ) или выделить элемент управления и выполнить команду контекстного меню Add Event Handler.
По умолчанию для командной кнопки, выполняющей завершение диалога, будет вставлен следующий метод - обработчик события:
void CD1Dlg::OnBnClickedOk() {
OnOK(); // OnOK - метод базового класса CDialog
}Имя метода - обработчика события формируется из префикса On, имени события и идентификатора элемента управления.
Обработчик события добавляется как новый член класса диалога.
При добавлении каждого нового метода обработчика события в таблицу сообщений также добавляется новый вход.
Таблица сообщений (иногда называемая также таблицей событий) указывается между макросами BEGIN_MESSAGE_MAP и END_MESSAGE_MAP. Макрос BEGIN_MESSAGE_MAP имеет два параметра - имя класса, обрабатывающего данные сообщения, и имя базового класса. Чтобы определить, что данный класс имеет таблицу сообщений, в заголовочном файле указывается макрос DECLARE_MESSAGE_MAP.
Например:
BEGIN_MESSAGE_MAP(CD1Dlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDOK, &CD1Dlg::OnBnClickedOk) END_MESSAGE_MAP()
Каждый вход таблицы сообщений содержит имя события (например, ON_BN_CLICKED ), идентификатор ресурса элемента управления (например, IDOK ) и имя метода - обработчика события (например, &CD1Dlg::OnBnClickedOk ).
Диалог может быть создан как:
- модальный диалог, завершение которого необходимо выполнить до продолжения работы с приложением (диалог отображается вызовом метода DoModal );
- немодальный диалог, позволяющий получать одновременный доступ к другим немодальным диалогам данного приложения (диалог создается вызовом метода Create и сразу отображается, если установлен стиль диалога WS_VISIBLE ).
Для того чтобы отобразить созданный диалог как модальный, следует создать объект диалога и выполнить для него метод DoModal().
Например:
CD1Dlg dlg; INT_PTR nResponse = dlg.DoModal();
Если предполагается определить диалог как главное окно приложения, то необходимо для объекта приложения установить значение свойства m_pMainWnd (CWnd* m_pMainWnd;).
Например:
CD1Dlg dlg;
m_pMainWnd = &dlg; // AfxGetApp()->m_pMainWnd
// AfxGetApp() возвращает для
// приложения указатель на
// объект типа CWinApp
INT_PTR nResponse = dlg.DoModal();Для модального диалога следует проверять код завершения диалога.
Например:
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK) { }
else if (nResponse == IDCANCEL) { }Для того чтобы отобразить диалог как немодальный, следует создать объект диалога и выполнить для него метод Create().
Например:
CMyDialog* pDialog; // Указатель на объект диалога
void CMyWnd::OnSomeAction()
{
// pDialog может быть инициализирован как NULL
// в конструкторе или классе CMyWnd
pDialog = new CMyDialog();
if(pDialog != NULL)
{
BOOL ret =
pDialog->Create(IDD_MYDIALOG,this); // Параметр
// указывает используемый ресурс диалога
if(!ret) AfxMessageBox("Ошибка при создании диалога");
pDialog->ShowWindow(SW_SHOW);
}
else AfxMessageBox("Ошибка с объектом диалога");
}