При работе с большинством приложений возникают ситуации, когда приложение запрашивает от пользователя некоторую информацию. В большинстве случаев для запроса открывается новое окно. Такие окна называются диалоговыми. Диалоговые окна обычно содержат несколько элементов управления и текст с пояснениями о запрашиваемой информации. В них нет такой обширной пустой рабочей области, как в редакторах.
В библиотеке MFC (как и в других подобных библиотеках) заготовлены некоторые виды типовых диалоговых окон для взаимодействия с пользователем:
Простые диалоговые окна сообщений реализуются двумя функциями
MessageBox() - является членом класса CWnd, поэтому доступна только для потомков этого класса. Это означает, что ее можно вызывать только из оконного класса или класса элемента управления. Имеет три параметра, которые можно передавать по порядку один, два или триAfxMessageBox() - применяется тогда, когда нужно открыть окно сообщения из класса, не являющегося потомком CWnd. Имеет два параметра. Ее можно вызывать и из класса-потомка CWndНазначение параметров по порядку:
AfxMessageBox() - отсутствует вообще)Сочетание кнопок и пиктограмм, определяемых третьим параметром (у функции AfxMessageBox() - вторым), предопределено, поэтому если необходимо что-то иное, придется создать свое диалоговое окно, похожее на стандартное. Ниже приведены все возможные значения третьего параметра
Идентификаторы комбинации кнопок в третьем параметре функции MessageBox() | |
|---|---|
| Идентификатор | Кнопки |
MB_ABORTRETRYIGNORE |
Три кнопки: Abort (Прервать), Retry (Повторить), Ignore (Пропустить) |
MB_OK |
Кнопка OK |
MB_OKCANCEL |
Две кнопки: OK, Cancel (Отмена) |
MB_RETRYCANCEL |
Две кнопки: Retry (Повторить), Cancel (Отмена) |
MB_YESNO |
Две кнопки: Yes (Да), No (Нет) |
MB_YESNOCANCEL |
Три кнопки: Yes (Да), No (Нет), Cancel (Отмена) |
MB_CANCELTRYCONTINUE |
Три кнопки: Cancel (Отмена), Try Again (Повторить попытку), Continue (Продолжить) |
Идентификаторы пиктограмм в третьем параметре функции MessageBox() | |
|---|---|
| Идентификатор | Пиктограммы |
MB_ICONINFORMATION |
Информационное сообщение |
MB_ICONQUESTION |
Вопросительный знак |
MB_ICONSTOP |
Знак остановки |
MB_ICONEXCLAMATION |
Восклицательный знак |
Если при вызове функции окна сообщений указывается сочетание кнопок, то нужно получить возвращаемое значение, чтобы определить, по какой кнопке щелкнул пользоватаель. Возвращаемые значения являются целочисленными и их идентификаторы приведены в таблице
Идентификаторы результатов, возвращаемый функцией MessageBox() | |
|---|---|
| Идентификатор | Кнопка, которую выбрал пользователь |
IDABORT |
Abort (Прервать) |
IDRETRY |
Retry (Повторить) |
IDIGNORE |
Ignore (Пропустить) |
IDYES |
Yes (Да) |
IDNO |
No (Нет) |
IDOK |
OK |
IDCANCEL |
Cancel (Отмена) |
IDTRYAGAIN |
Try Again (Повторить попытку) |
IDCONTINUE |
Continue (Продолжить) |
Создайте новый проект C++ на основе MFC и назовите его Dialogs
Ни в коем случае не называйте проекты русскими именами, поскольку оболочка использует имя проекта при автоматической генерации имен файлов проекта и классов. Компилятор из текстов на русском принимает только комментарии и строковые константы.
Укажите мастеру, что проект будет диалоговым приложением
Остальные настройки мастера оставьте по умолчанию
Установите для ресурсов русский язык
Измените заголовок формы на "свою фамилию" + " Lab7 - Диалоги"
Создайте макет диалогового окна, показанный на рисунке. Для этого воспользуйтесь таблицей свойств элементов управления, приведенной ниже
Для выравнивания элементов диалога включите и пользуйтесь панелью инструментов "Dialog Editor" оболочки
При выравнивании группы элементов отметьте, что первый из выделенных элементов группы является опорным: все остальные элементы подравниваются под него. Точное перемещение элементов выполняйте стрелками клавиатуры. Для быстрого просмотра результатов визуального проектирования пользуйтесь кнопкой Test Dialog панели инструментов Dialog Editor оболочки.
Определите порядок перехода по клавише табуляции между элементами управления
Обеспечьте выход по кнопке
Application Type Application Type Dialog Based Resource language:Project style:MFC standard Use of MFC:Use MFC in a shared DLL Advanced Features User Interface Features Main frame styles:System menu Dialog title:Dialogs Таблица свойств главной диалоговой формы Dialogs | ||
|---|---|---|
| Элемент управления | Свойство | Значение |
| Главная форма | Caption |
Студент Иванов. Lab7 - Диалоги |
Font(Size) |
MS Sans Serif(10) |
|
Maximize Box |
True |
|
|
True |
|
Button |
ID |
IDC_B_YESNOCANCEL |
Caption |
Да, Нет, Отмена | |
Button |
ID |
IDC_B_ABORTRETRYIGNORE |
Caption |
Прервать, Повторить, Пропустить | |
Button |
ID |
IDC_B_FILEOPEN |
Button |
Caption |
Диалог File Open |
ID |
IDC_B_CUSTOMDIALOG |
|
Caption |
Сконструированный диалог | |
Button |
ID |
IDC_B_WHICHOPTION |
Caption |
Какая опция? | |
Disabled |
True |
|
Static Text |
Caption |
Результаты диалога: |
Right Align Text |
True |
|
Edit Control |
ID |
IDC_E_RESULT |
Multiline |
True |
|
Auto VScroll |
True |
|
|
True |
|
Button |
ID |
IDC_B_EXIT |
Caption |
Выход | |
Нажмите на пиктограмму
Создайте и свяжите с полем редактирования и кнопкой "Какая опция?" две переменные| Переменные элементов управления | |||||
|---|---|---|---|---|---|
ID (Объект связывания) |
Name (Имя) |
Type ( Тип) |
Category ( Категория) |
Accass ( Доступ) |
Назначение |
IDC_E_RESULT |
m_strResult |
Value |
|
public |
Для хранения значений поля редактирования |
IDC_B_WHICHOPTION |
m_cWhichOption |
Control |
CButton |
Public |
Для управления блокированием кнопки |
Создайте обработчик для щелчка на первой кнопке "Да, Нет, Отмена"Обработчик для щелчка по первой кнопке "Да, Нет, Отмена"
void CDialogsDlg::OnBnClickedBYesnocancel()
{
int iResults; // Для возвращаемого значения MessageBox()
// Спросить пользователя
iResults = MessageBox(
"Щелкните по кнопке\nДа, Нет, Отмена"// В области клиента (символ новой строки)
,"Диалог \"Да, Нет, Отмена\"" // Заголовок окна (экраны)
,MB_YESNOCANCEL | MB_ICONINFORMATION // Комбинации кнопок и пиктограмм
);
// Определить, по какой кнопке щелкнул пользователь
switch(iResults){ // переключатель
case IDYES:
m_strResult = "Да! Да! Да!";
break;
case IDNO:
m_strResult = "Нет, нет, нет, нет, нет.";
break;
case IDCANCEL:
m_strResult = "Жаль, что \"Отмена\"";
// break здесь необязательно, все равно последний
}
// Выдать на экран
UpdateData(FALSE);
}
По аналогии создайте обработчик для щелчка по второй кнопке "Прервать, Повторить, Пропустить", используя идентификатор комбинации кнопок MB_ABORTRETRYIGNORE и идентификатор пиктограмм MB_ICONEXCLAMATIONВ библиотеки MFC предусмотрено несколько классов C++, предназначенных для поддержки общих (стандартных) диалогов
| Классы стандартных диалогов | |
|---|---|
| Класс | Тип диалога |
CFileDialog |
Выбор файла для чтения или записи |
CFontDialog |
Выбор шрифта |
CColorDialog |
Выбор цвета |
CPageSetupDialog |
Установка параметров страницы для печати |
CPrintDialog |
Печать |
CFindReplaceDialog |
Поиск и замена |
Все эти диалоговые окна используются одинаково, хотя отдельные свойства и функции класса отличаются в зависимости от назначения диалога.
Для использования конкретного диалога нужно выполнить следующее
new, своевременно освободив ее оператором delete после закрытия диалога и выборки из него необходимой информацииDoModal() класса. Класс CFindReplaceDialog создает немодальное окно, поэтому для него вместо метода DoModal() нужно вызывать метод Create()DoModal() значение, чтобы определить на какой кнопке щелкнул пользователь - на OK или CancelOK, то прочитать все необходимые для дальнейшей работы приложения свойства, которые могли быть установлены пользователем в окне диалога. Для этого имеются методы доступа к свойствам класса, которые имеет смыcл применять для чтения только после того, как завершиться выбор пользователя нажатием кнопки OKЛюбое диалоговое окно может отображаться в двух режимах:
modal ) - всякое иное взаимодействие пользователя с приложением приостанавливается до закрытия диалога. Модальные диалоговые окна применяются тогда, когда без завершения забора информации от пользователя продолжение работы приложения будет неопределенным. Пример - типовые окна сообщенийmodeless ) - пользователь может переключиться на основное окно приложения, не завершив диалог. Пример - окно "Find and Replace" (Найти и Заменить)Класс CFileDialog реализует содание двух типов диалогов, который зависит от того, с каким аргументом для конструктора класса создается экземпляр - окно диалога:
" CFileDialog openFile(TRUE); // создается окно Open File " " CFileDialog saveFile(FALSE); // создается окно Save File
Конструктору можно передать несколько аргументов, задав тем самым расширения отображаемых файлов (фильтры), маршрут, начальное имя файла и начальный путь по умолчанию. Все эти аргументы конструктора имеют значения по умолчанию, так что не обязательно указывать явно ни один из них.
| Основные методы доступа класса CFileDialog | |
|---|---|
| Функция | Описание |
GetPathName() |
Возвращает полный путь выбранного файла |
GetFileName() |
Возвращает имя выбранного файла |
GetFileExt() |
Вовращает расширение выбранного файла |
GetFileTitle() |
Возвращает имя выбранного фвйла без расширения (например, если был выбран файл "MyFile.txt", то вернется "MyFile" |
Примечание. Все перечисленные в таблице методы не могут вызываться до тех пор, пока не будет вызван метод DoModal() и пока он не вернет значение IDOK. Иначе в свойствах может храниться кодовый мусор.
Класс CFontDialog инкапсулирует встроенный в Windows стандартный диалог выбора шрифта. В таблице приводятся основные методы-члены класса CFontDialog.
| Основные методы доступа класса CFontDialog | |
|---|---|
| Функция | Описание |
GetFaceName() |
Возвращает имя выбранного шрифта. |
GetStyleName() |
Возвращает начертание выбранного шрифта (вид шрифта, тип шрифта). К одному типу шрифта может относиться несколько различных шрифтов. |
GetSize() |
Возвращает размер, указанный для выбранного шрифта. |
GetColor() |
Возвращает цвет, указанный для выбранного шрифта. |
GetWeight() |
Возвращает вес, указанный для выбранного шрифта. |
IsStrikeOut() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "зачеркнутый" ( strike out ) для выбранного шрифта. |
IsUnderline() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "подчеркнутый" ( underline ) для выбранного шрифта. |
IsBold() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "полужирный" ( bold ) для выбранного шрифта. |
IsItalic() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "курсив" ( italic ) для выбранного шрифта. |
Класс CColorDialog инкапсулирует стандартный диалог выбора цвета, используемый во многих Windows -приложениях для получения значений координат модели цвета RGB (RedGreenBlue) , которые затем можно передать любому методу интерфейса графических устройств , требующему код цвета. В таблице приводятся основные методы-члены класса CColorDialog
Основные методы доступа класса CColorDialog | |
|---|---|
| Функция | Описание |
GetColor() |
Возвращает выбранный цвет. |
GetSavedCustomColor() |
Возвращает массив созданных пользователем цветов. |
SetCurrentColor() |
Устанавливает текущий цвет. Вызывать данный метод следует перед вызовом метода DoModal(). |
Класс CPageSetupDialog инкапсулирует диалог Page Setup (параметры страницы), который используется для настройки вывода на печать.Этот диалог позволяет выбрать принтер, размер и поля печатаемой страницы. В таблице приводятся основные методы-члены класса CPageSetupDialog
Основные методы доступа класса CPageSetupDialog | |
|---|---|
| Функция | Описание |
CreatePrinterDC() |
Возвращает контекст устройства, используемого для печати |
GetDeviceName() |
Возвращает имя выбранного принтера |
GetDevMode() |
Возвращает структуру, содержащую информацию о выбранном принтере и его возможностях (цветной или черно-белый) |
GetMargins() |
Этому методу в качестве аргументов передаются два указателя - либо на класс CRect, либо на структуру RECT, - а он заносит в класс или структуру размеры полей и области печати |
GetPaperSize() |
Возвращает класс CSize, который определяет текущий размер бумаги |
GetDriveName() |
Возвращает имя драйвера выбранного принтера |
GetPortName() |
Возвращает имя выбранного порта вывода |
Класс CPrintDialog инкапсулирует стандартный диалог Print. Он содержит большинство методов класса CPageSetupDialog, за исключением методов GetMargins() и GetPaperSize(). Прочие важные функции класса CPrintDialog приведены в таблице
Прочие важные методы доступа класса CPrintDialog | |
|---|---|
| Функция | Описание |
GetCopies() |
Возвращает количество печатаемых копий |
GetFromPage() |
Возвращает номер начальной страницы (в случае, если был задан диапазон номеров печатаемых страниц) |
GetToPage() |
Возвращает номер конечной страницы (в случае, если был задан диапазон номеров печатаемых страниц) |
GetPrinterDC() |
Возвращает дескриптор контекста устройства для указанного принтера |
PrintAll() |
Возвращает логическое значение, позволяющее определить, нужно ли печатать все страницы текущего документа |
PrintCollate() |
Возвращает логическое значение, позволяющее определить, желает ли пользователь, чтобы страницы были разобраны по копиям |
PrintRange() |
Возвращает логическое значение, позволяющее определить, задан ли диапазон номеров печатаемых страниц |
PrintSelection() |
Возвращает логическое значение, позволяющее определить, нужно ли печатать только выбранные элементы или страницы целиком |
В отличие от методов класса CPageSetupDialog, метод CreatePrinterDC() можно вызывать без предварительного вызова метода DoModal(). Отображать этот диалог перед печатью необязательно, но класс CPrintDialog можно использовать для получения информации о принтере и контексте устройства.
Класс CFindReplaceDialog инкапсулирует стандартный диалог поиска и замены. В отличии от других стандартных диалогов, это окно немодальное, поэтому для отображения данного диалога нужно вызывать вместо метода DoModal() метод Create(). Метод Create() может принимать пять параметров, два первых из которых обязательны:
TRUE ) или для поиска и замены ( FALSE )FR_DOWN ). Направление "назад" устанавливается значением 0Принципы работы с классом CFindReplaceDialog более сложные, чем с другими классами стандартных диалогов. Мы их здесь рассматривать не будем. В таблице приводятся основные методы-члены класса CFindReplaceDialog
Основные методы доступа класса CFindReplaceDialog | |
|---|---|
| Функция | Описание |
|
Возвращает логическое значение, указывающее, нужно ли найти следующее вхождение искомой строки |
GetFindString() |
Возвращает введенную пользователем строку для поиска |
GetReplaceString() |
Возвращает введенную пользователем строку для замены |
IsTerminating() |
Возвращает логическое значение, позволяющее определить, решил ли пользователь закрыть этот диалог |
MatchCase() |
Возвращает логическое значение, которое указывает, нужно ли в поиске строки учитывать регистр |
MatchWholeWord() |
Возвращает логическое значение, которое указывает, нужно ли искать слово только целиком |
ReplaceAll() |
Возвращает логическое значение, которое указывает, нужно ли заменить все вхождения искомой строки |
ReplaceCurrent() |
Возвращает логическое значение, которое указывает, нужно ли заменить текущее найденное вхождение искомой строки |
SearchDown() |
Возвращает логическое значение, которое указывает, нужно ли выполнить поиск вперед от текущей позиции |
Создайте обработчик для кнопки "Диалог File Open"
Заполните его кодомОбработчик для щелчка по кнопке "Диалог File Open"
void CDialogsDlg::OnBnClickedBFileopen()
{
CFileDialog openFile(TRUE); // Создать диалог
if(openFile.DoModal() == IDOK){ // Отобразить и получить результат
m_strResult = openFile.GetFileName(); // Сохранить имя файла
UpdateData(FALSE); // Передать на экран
}
}
Добавим собственное диалоговое окно, которое будет предлагать пользователю поле редактирования, группу радиокнопок. Когда пользователь щелкнет на кнопке OK, введенный им текст отобразится в главном окне приложения. Для этого нужно будет выполнить следующие действия:
CDialog
Выберите вкладку
Выделите в нем пиктограмму
В панели Resource View выделите сгенерированный ресурс с дежурным именем IDD_DIALOG1 и через панель свойств присвойте ресурсу осмысленный идентификатор IDD_MESSAGEDLG. Не удаляйте кнопки OK и Cancel
Отредактируйте ресурс диалогового окна в соответствии с таблицей свойств| Таблица свойств диалогового ресурса IDD_MESSAGEDLG | ||
|---|---|---|
| Элемент управления | Свойство | Значение |
| Форма | Caption |
Диалог с сообщениями и опциями |
Font(Size) |
MS Sans Serif(10) |
|
Maximize Box |
False |
|
|
False |
|
Static Text |
Caption |
Введите сообщение: |
Right Align Text |
True |
|
Edit Control |
ID |
IDC_EMESSAGE |
Multiline |
True |
|
Auto VScroll |
True |
|
|
True |
|
Group Box |
Caption |
Выбор опции |
|
ID |
IDC_ROPTION1 |
Caption |
Опция 1 | |
Group |
True |
|
|
ID |
IDC_ROPTION2 |
Caption |
Опция 2 | |
Group |
False |
|
|
ID |
IDC_ROPTION3 |
Caption |
Опция 3 | |
Group |
False |
|
|
ID |
IDC_ROPTION4 |
Caption |
Опция 4 | |
Group |
False |
|
При редактировании диалогового ресурса периодически проверяйте дизайн кнопкой Test Dialog панели инструментов Dialog Editor. Размеры элементов управления контролируйте через панель состояния дизайнера. Для выравнивания элементов пользуйтесь инструментами на панели инструментов или опциями меню Format оболочки.
Окончательный вариант макета приведен на рисунке

Отметьте, что для согласованной работы радиокнопок мы для первого переключателя установили свойство Group в состояние True. В остальных же переключателях оставили его значение по умолчанию False. Это приведет к тому, что следующие по порядку их создания радиокнопки будут объединены в группу. Новая группа начнется с нового следующего по порядку создания радиопереключателя со свойством True (но у нас только одна группа). Порядок следования радиопереключателей можно посмотреть через опцию Edit/Resource Symbols (или через контекстное меню в панели Resource View, щелкнув на узле Dialogs.rc ) в окне Resource Symbols

Отредактировать порядок радиопереключателей можно в файле Resource.h, открыв его на редактирование через панель Solution Explorer (не рекомендуется!!!)

В этом файле оболочка формирует именованные константы
Именованные константы в файле Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Dialogs.rc
//
#define IDD_DIALOGS_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_MESSAGEDLG 131
#define IDC_B_YESNOCANCEL 1000
#define IDC_B_ABORTRETRYIGNORE 1001
#define IDC_B_CUSTOMDIALOG 1002
#define IDC_B_WHICHOPTION 1003
#define IDC_E_RESULT 1004
#define IDC_EMESSAGE 1005
#define IDC_B_FILEOPEN 1006
#define IDC_ROPTION1 1006
#define IDC_B_EXIT 1007
#define IDC_ROPTION2 1007
#define IDC_ROPTION3 1008
#define IDC_RADIO4 1009
#define IDC_ROPTION4 1009
............................................
Для управления диалоговым ресурсом создайте класс на основе базового класса CDialog. Для этого:
Выберите только что сконструированное окно приложения в режиме дизайна и через контекстное меню (или главное меню Project ) выполните опцию Add Class
Запустится мастер добавления класса, который нужно настроить в соответствии с рисунком

Убедитесь, что в поле выбран CDialog
После создания класса его код должен быть размещен в двух новых файлах MsgDlg.h и MsgDlg.cpp. Убедитесь в этом через панель Solution Explorer. Удобнее при создании новых классов размещать их в отдельных файлах. Мастер Add Class создал производный CDialog, поддерживающего диалоговые окна
Объявление производного класса CMsgDlg, наследника CDialog (код файла MsgDlg.h)
#pragma once
// CMsgDlg dialog
class CMsgDlg : public CDialog
{
DECLARE_DYNAMIC(CMsgDlg)
public:
CMsgDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CMsgDlg();
// Dialog Data
enum { IDD = IDD_MESSAGEDLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
Добавьте две ассоциированные переменные к элементам управления. Для этого выделите в панели
CMsgDlg ID (Объект связывания) Name (Имя)Type ( Тип)Category ( Категория)Accass ( Доступ)IDC_EMESSAGE m_strMessage Value CString public IDC_ROPTION1 m_iOption Value intpublic 

Мастер добавит в приложение код
Файл MsgDlg.h
class CMsgDlg : public CDialog
{
................................................
public:
// Для хранения значений поля редактирования
CString m_strMessage;
// Для распознавания выбранной радиокнопки
int m_iOption;
};
Файл MsgDlg.cpp
CMsgDlg::CMsgDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMsgDlg::IDD, pParent)
, m_strMessage(_T(""))
, m_iOption(0)
{
}
void CMsgDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EMESSAGE, m_strMessage);
DDX_Radio(pDX, IDC_ROPTION1, m_iOption);
}
Для переключателя с установленным свойством Group мы назначили ассоциированную целочисленную переменную m_iOption. Значение этой переменной зависит от того, какой из переключателей группы будет выбран пользователем. При выборе первого переключателя "Опция 1" эта переменная принимает значение 0, при выборе второго - значение 1, и т.д. , поскольку в C++ нумерация элементов массива или группы начинается с нуля.
Мы сконструировали собственный диалог, который теперь можно использовать точно также, как и стандартный диалог, а именно:
CMsgDlgDoModal() экземпляра и сохранить возвращаемое им значениеm_strMessage и m_iOptionprivate и добавив функции доступа к этим переменнымРешим эту задачу в соответствии со следующими пошаговыми инструкциями
Добавьте в объявление класса-клиента переменную-экземпляр созданного нами класса CMsgDlg в соответствии с настройкой мастера, приведенной ниже. Для этого выделите в панели Class View класс CDialogsDlg и через контекстное меню откройте мастер

Мастер добавит код
Объявление в классе CDialogsDlg переменной-экземпляра класса CMsgDlg
class CDialogsDlg : public CDialog
{
..............................................
private:
// Экземпляр класса нашего диалогового окна
CMsgDlg m_dMsgDlg;
};
Добавьте в класс-клиент CDialogsMsg директиву препроцессора (предварительного компилятора) для подключения к нему объявления класса-сервиса CMsgDlg. Для этого через панель Solution Explorer откройте на редактирование файл DialogsMsg.h и в самом начале файла, перед объявлением класса CDialogsDlg, подключите заголовочный файл с описанием класса CMsgDlg, как показано ниже
Подключение файла с объявлением класса-сервиса CMsgDlg
перед объявлением класса-клиента CDialogsDlg в файле DialogsDlg.h
// DialogsDlg.h : header file
//
#pragma once // Страж включения
#include "afxwin.h"
#include "MsgDlg.h"
// CDialogsDlg dialog
class CDialogsDlg : public CDialog
{
.....................................
};
Обратите внимание, что в каждом заголовочном файле, созданном оболочкой, она в самом начале файла размещает директиву препроцессора "#pragma once", которую называют стражем включения. Это связано с тем, что включение файла может быть размещено во многих местах приложения, а препроцессор должен включить в приложение только первый встретившийся экземпляр кода. Эта директива и поднимает флаг у препроцессора, заставляя его игнорировать повторные включения одного и того же кода. В реализациях других производителей компиляторов можно встретить иной прием
#ifndef ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА #define ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА код включаемого файла #endif
Добавьте обработчик к кнопке "Сконструированный диалог", запускающий на выполнение окно нашего диалога
Обработчик кнопки "Сконструированный диалог" запуска диалога
// Обработчик кнопки "Сконструированный диалог"
void CDialogsDlg::OnBnClickedBCustomdialog()
{
// Запросить информацию через диалог
if(m_dMsgDlg.DoModal() == IDOK){
m_strResult = m_dMsgDlg.m_strMessage;// Напрямую, т.к. public
// разблокировать кнопку "Какая опция?"
m_cWhichOption.EnableWindow(TRUE);
}
else
m_strResult = "Ввод информации отменен!";
// Передать на экран новое значение поля редактирования
UpdateData(FALSE);
}
Добавьте обработчик к кнопке "Какая опция?"Обработчик кнопки "Какая опция?"
// Обработчик кнопки "Какая опция?"
void CDialogsDlg::OnBnClickedBWhichoption()
{
// Какая радиокнопка включена
switch(m_dMsgDlg.m_iOption){
case 0:
m_strResult = "Была выбрана первая опция";
break;
case 1:
m_strResult = "Была выбрана вторая опция";
break;
case 2:
m_strResult = "Была выбрана третья опция";
break;
case 3:
m_strResult = "Была выбрана четвертая опция";
break;
default:
m_strResult = "Опция не выбрана!";
}
// Передать на экран новое значение поля редактирования
UpdateData(FALSE);
}
Запустите приложение и убедитесь в его работоспособности
Измените в объявлении класса CMsgDlg данные-члены m_strMessage и m_iOption как private
Добавьте к классу CMsgDlg методы доступа public, возвращающие значения этих переменных:CString GetMessage() {return m_strMessage;} int GetOption() {return m_iOption;}
Замените в последних двух обработчиках класса CDialogsMsg прямые вызовы переменных m_strMessage и m_iOption через вызовы функций доступа
Постройте окончательный вариант приложения в режиме Release и убедитесь, что размер исполнимого файла составляет примерно 15KЭто малый размер для такой задачи и объясняется это тем, что при создании приложения мы настроили мастер на использование библиотек DLL
| Таблица настройки мастера создания каркаса приложения | |
|---|---|
Use of MFC: |
Use MFC in a shared DLL |
Такое приложение не будет работать на компьютере, где нет этих библиотек. Поэтому следует построить автономное приложение, включающее в себя весь необходимый код. Для этого:
Выполните опцию Project/Dialogs Properties для нашего проекта Dialogs

Появится окно, в котором установите режим
| Изменение режима в таблице свойcтв приложения | |
|---|---|
Use of MFC: |
Use MFC in a Static Library |

Перестройте приложение и определите размер исполнимого файлаИсполнимый файл приложения увеличился примерно до 155K. Такой файл будет работать на любом компьютере с операционной системой Windows.
При работе с большинством приложений возникают ситуации, когда приложение запрашивает от пользователя некоторую информацию. В большинстве случаев для запроса открывается новое окно. Такие окна называются диалоговыми. Диалоговые окна обычно содержат несколько элементов управления и текст с пояснениями о запрашиваемой информации. В них нет такой обширной пустой рабочей области, как в редакторах.
В библиотеке MFC (как и в других подобных библиотеках) заготовлены некоторые виды типовых диалоговых окон для взаимодействия с пользователем:
Простые диалоговые окна сообщений реализуются двумя функциями
MessageBox() - является членом класса CWnd, поэтому доступна только для потомков этого класса. Это означает, что ее можно вызывать только из оконного класса или класса элемента управления. Имеет три параметра, которые можно передавать по порядку один, два или триAfxMessageBox() - применяется тогда, когда нужно открыть окно сообщения из класса, не являющегося потомком CWnd. Имеет два параметра. Ее можно вызывать и из класса-потомка CWndНазначение параметров по порядку:
AfxMessageBox() - отсутствует вообще)Сочетание кнопок и пиктограмм, определяемых третьим параметром (у функции AfxMessageBox() - вторым), предопределено, поэтому если необходимо что-то иное, придется создать свое диалоговое окно, похожее на стандартное. Ниже приведены все возможные значения третьего параметра
Идентификаторы комбинации кнопок в третьем параметре функции MessageBox() | |
|---|---|
| Идентификатор | Кнопки |
MB_ABORTRETRYIGNORE |
Три кнопки: Abort (Прервать), Retry (Повторить), Ignore (Пропустить) |
MB_OK |
Кнопка OK |
MB_OKCANCEL |
Две кнопки: OK, Cancel (Отмена) |
MB_RETRYCANCEL |
Две кнопки: Retry (Повторить), Cancel (Отмена) |
MB_YESNO |
Две кнопки: Yes (Да), No (Нет) |
MB_YESNOCANCEL |
Три кнопки: Yes (Да), No (Нет), Cancel (Отмена) |
MB_CANCELTRYCONTINUE |
Три кнопки: Cancel (Отмена), Try Again (Повторить попытку), Continue (Продолжить) |
Идентификаторы пиктограмм в третьем параметре функции MessageBox() | |
|---|---|
| Идентификатор | Пиктограммы |
MB_ICONINFORMATION |
Информационное сообщение |
MB_ICONQUESTION |
Вопросительный знак |
MB_ICONSTOP |
Знак остановки |
MB_ICONEXCLAMATION |
Восклицательный знак |
Если при вызове функции окна сообщений указывается сочетание кнопок, то нужно получить возвращаемое значение, чтобы определить, по какой кнопке щелкнул пользоватаель. Возвращаемые значения являются целочисленными и их идентификаторы приведены в таблице
Идентификаторы результатов, возвращаемый функцией MessageBox() | |
|---|---|
| Идентификатор | Кнопка, которую выбрал пользователь |
IDABORT |
Abort (Прервать) |
IDRETRY |
Retry (Повторить) |
IDIGNORE |
Ignore (Пропустить) |
IDYES |
Yes (Да) |
IDNO |
No (Нет) |
IDOK |
OK |
IDCANCEL |
Cancel (Отмена) |
IDTRYAGAIN |
Try Again (Повторить попытку) |
IDCONTINUE |
Continue (Продолжить) |
Создайте новый проект C++ на основе MFC и назовите его Dialogs
Ни в коем случае не называйте проекты русскими именами, поскольку оболочка использует имя проекта при автоматической генерации имен файлов проекта и классов. Компилятор из текстов на русском принимает только комментарии и строковые константы.
Укажите мастеру, что проект будет диалоговым приложением
Остальные настройки мастера оставьте по умолчанию
Установите для ресурсов русский язык
Измените заголовок формы на "свою фамилию" + " Lab7 - Диалоги"
Создайте макет диалогового окна, показанный на рисунке. Для этого воспользуйтесь таблицей свойств элементов управления, приведенной ниже
Для выравнивания элементов диалога включите и пользуйтесь панелью инструментов "Dialog Editor" оболочки
При выравнивании группы элементов отметьте, что первый из выделенных элементов группы является опорным: все остальные элементы подравниваются под него. Точное перемещение элементов выполняйте стрелками клавиатуры. Для быстрого просмотра результатов визуального проектирования пользуйтесь кнопкой Test Dialog панели инструментов Dialog Editor оболочки.
Определите порядок перехода по клавише табуляции между элементами управления
Обеспечьте выход по кнопке
Application Type Application Type Dialog Based Resource language:Project style:MFC standard Use of MFC:Use MFC in a shared DLL Advanced Features User Interface Features Main frame styles:System menu Dialog title:Dialogs Таблица свойств главной диалоговой формы Dialogs | ||
|---|---|---|
| Элемент управления | Свойство | Значение |
| Главная форма | Caption |
Студент Иванов. Lab7 - Диалоги |
Font(Size) |
MS Sans Serif(10) |
|
Maximize Box |
True |
|
|
True |
|
Button |
ID |
IDC_B_YESNOCANCEL |
Caption |
Да, Нет, Отмена | |
Button |
ID |
IDC_B_ABORTRETRYIGNORE |
Caption |
Прервать, Повторить, Пропустить | |
Button |
ID |
IDC_B_FILEOPEN |
Button |
Caption |
Диалог File Open |
ID |
IDC_B_CUSTOMDIALOG |
|
Caption |
Сконструированный диалог | |
Button |
ID |
IDC_B_WHICHOPTION |
Caption |
Какая опция? | |
Disabled |
True |
|
Static Text |
Caption |
Результаты диалога: |
Right Align Text |
True |
|
Edit Control |
ID |
IDC_E_RESULT |
Multiline |
True |
|
Auto VScroll |
True |
|
|
True |
|
Button |
ID |
IDC_B_EXIT |
Caption |
Выход | |
Нажмите на пиктограмму
Создайте и свяжите с полем редактирования и кнопкой "Какая опция?" две переменные| Переменные элементов управления | |||||
|---|---|---|---|---|---|
ID (Объект связывания) |
Name (Имя) |
Type ( Тип) |
Category ( Категория) |
Accass ( Доступ) |
Назначение |
IDC_E_RESULT |
m_strResult |
Value |
|
public |
Для хранения значений поля редактирования |
IDC_B_WHICHOPTION |
m_cWhichOption |
Control |
CButton |
Public |
Для управления блокированием кнопки |
Создайте обработчик для щелчка на первой кнопке "Да, Нет, Отмена"Обработчик для щелчка по первой кнопке "Да, Нет, Отмена"
void CDialogsDlg::OnBnClickedBYesnocancel()
{
int iResults; // Для возвращаемого значения MessageBox()
// Спросить пользователя
iResults = MessageBox(
"Щелкните по кнопке\nДа, Нет, Отмена"// В области клиента (символ новой строки)
,"Диалог \"Да, Нет, Отмена\"" // Заголовок окна (экраны)
,MB_YESNOCANCEL | MB_ICONINFORMATION // Комбинации кнопок и пиктограмм
);
// Определить, по какой кнопке щелкнул пользователь
switch(iResults){ // переключатель
case IDYES:
m_strResult = "Да! Да! Да!";
break;
case IDNO:
m_strResult = "Нет, нет, нет, нет, нет.";
break;
case IDCANCEL:
m_strResult = "Жаль, что \"Отмена\"";
// break здесь необязательно, все равно последний
}
// Выдать на экран
UpdateData(FALSE);
}
По аналогии создайте обработчик для щелчка по второй кнопке "Прервать, Повторить, Пропустить", используя идентификатор комбинации кнопок MB_ABORTRETRYIGNORE и идентификатор пиктограмм MB_ICONEXCLAMATIONВ библиотеки MFC предусмотрено несколько классов C++, предназначенных для поддержки общих (стандартных) диалогов
| Классы стандартных диалогов | |
|---|---|
| Класс | Тип диалога |
CFileDialog |
Выбор файла для чтения или записи |
CFontDialog |
Выбор шрифта |
CColorDialog |
Выбор цвета |
CPageSetupDialog |
Установка параметров страницы для печати |
CPrintDialog |
Печать |
CFindReplaceDialog |
Поиск и замена |
Все эти диалоговые окна используются одинаково, хотя отдельные свойства и функции класса отличаются в зависимости от назначения диалога.
Для использования конкретного диалога нужно выполнить следующее
new, своевременно освободив ее оператором delete после закрытия диалога и выборки из него необходимой информацииDoModal() класса. Класс CFindReplaceDialog создает немодальное окно, поэтому для него вместо метода DoModal() нужно вызывать метод Create()DoModal() значение, чтобы определить на какой кнопке щелкнул пользователь - на OK или CancelOK, то прочитать все необходимые для дальнейшей работы приложения свойства, которые могли быть установлены пользователем в окне диалога. Для этого имеются методы доступа к свойствам класса, которые имеет смыcл применять для чтения только после того, как завершиться выбор пользователя нажатием кнопки OKЛюбое диалоговое окно может отображаться в двух режимах:
modal ) - всякое иное взаимодействие пользователя с приложением приостанавливается до закрытия диалога. Модальные диалоговые окна применяются тогда, когда без завершения забора информации от пользователя продолжение работы приложения будет неопределенным. Пример - типовые окна сообщенийmodeless ) - пользователь может переключиться на основное окно приложения, не завершив диалог. Пример - окно "Find and Replace" (Найти и Заменить)Класс CFileDialog реализует содание двух типов диалогов, который зависит от того, с каким аргументом для конструктора класса создается экземпляр - окно диалога:
" CFileDialog openFile(TRUE); // создается окно Open File " " CFileDialog saveFile(FALSE); // создается окно Save File
Конструктору можно передать несколько аргументов, задав тем самым расширения отображаемых файлов (фильтры), маршрут, начальное имя файла и начальный путь по умолчанию. Все эти аргументы конструктора имеют значения по умолчанию, так что не обязательно указывать явно ни один из них.
| Основные методы доступа класса CFileDialog | |
|---|---|
| Функция | Описание |
GetPathName() |
Возвращает полный путь выбранного файла |
GetFileName() |
Возвращает имя выбранного файла |
GetFileExt() |
Вовращает расширение выбранного файла |
GetFileTitle() |
Возвращает имя выбранного фвйла без расширения (например, если был выбран файл "MyFile.txt", то вернется "MyFile" |
Примечание. Все перечисленные в таблице методы не могут вызываться до тех пор, пока не будет вызван метод DoModal() и пока он не вернет значение IDOK. Иначе в свойствах может храниться кодовый мусор.
Класс CFontDialog инкапсулирует встроенный в Windows стандартный диалог выбора шрифта. В таблице приводятся основные методы-члены класса CFontDialog.
| Основные методы доступа класса CFontDialog | |
|---|---|
| Функция | Описание |
GetFaceName() |
Возвращает имя выбранного шрифта. |
GetStyleName() |
Возвращает начертание выбранного шрифта (вид шрифта, тип шрифта). К одному типу шрифта может относиться несколько различных шрифтов. |
GetSize() |
Возвращает размер, указанный для выбранного шрифта. |
GetColor() |
Возвращает цвет, указанный для выбранного шрифта. |
GetWeight() |
Возвращает вес, указанный для выбранного шрифта. |
IsStrikeOut() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "зачеркнутый" ( strike out ) для выбранного шрифта. |
IsUnderline() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "подчеркнутый" ( underline ) для выбранного шрифта. |
IsBold() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "полужирный" ( bold ) для выбранного шрифта. |
IsItalic() |
Возвращает логическое значение, позволяющее определить, был ли выбран атрибут "курсив" ( italic ) для выбранного шрифта. |
Класс CColorDialog инкапсулирует стандартный диалог выбора цвета, используемый во многих Windows -приложениях для получения значений координат модели цвета RGB (RedGreenBlue) , которые затем можно передать любому методу интерфейса графических устройств , требующему код цвета. В таблице приводятся основные методы-члены класса CColorDialog
Основные методы доступа класса CColorDialog | |
|---|---|
| Функция | Описание |
GetColor() |
Возвращает выбранный цвет. |
GetSavedCustomColor() |
Возвращает массив созданных пользователем цветов. |
SetCurrentColor() |
Устанавливает текущий цвет. Вызывать данный метод следует перед вызовом метода DoModal(). |
Класс CPageSetupDialog инкапсулирует диалог Page Setup (параметры страницы), который используется для настройки вывода на печать.Этот диалог позволяет выбрать принтер, размер и поля печатаемой страницы. В таблице приводятся основные методы-члены класса CPageSetupDialog
Основные методы доступа класса CPageSetupDialog | |
|---|---|
| Функция | Описание |
CreatePrinterDC() |
Возвращает контекст устройства, используемого для печати |
GetDeviceName() |
Возвращает имя выбранного принтера |
GetDevMode() |
Возвращает структуру, содержащую информацию о выбранном принтере и его возможностях (цветной или черно-белый) |
GetMargins() |
Этому методу в качестве аргументов передаются два указателя - либо на класс CRect, либо на структуру RECT, - а он заносит в класс или структуру размеры полей и области печати |
GetPaperSize() |
Возвращает класс CSize, который определяет текущий размер бумаги |
GetDriveName() |
Возвращает имя драйвера выбранного принтера |
GetPortName() |
Возвращает имя выбранного порта вывода |
Класс CPrintDialog инкапсулирует стандартный диалог Print. Он содержит большинство методов класса CPageSetupDialog, за исключением методов GetMargins() и GetPaperSize(). Прочие важные функции класса CPrintDialog приведены в таблице
Прочие важные методы доступа класса CPrintDialog | |
|---|---|
| Функция | Описание |
GetCopies() |
Возвращает количество печатаемых копий |
GetFromPage() |
Возвращает номер начальной страницы (в случае, если был задан диапазон номеров печатаемых страниц) |
GetToPage() |
Возвращает номер конечной страницы (в случае, если был задан диапазон номеров печатаемых страниц) |
GetPrinterDC() |
Возвращает дескриптор контекста устройства для указанного принтера |
PrintAll() |
Возвращает логическое значение, позволяющее определить, нужно ли печатать все страницы текущего документа |
PrintCollate() |
Возвращает логическое значение, позволяющее определить, желает ли пользователь, чтобы страницы были разобраны по копиям |
PrintRange() |
Возвращает логическое значение, позволяющее определить, задан ли диапазон номеров печатаемых страниц |
PrintSelection() |
Возвращает логическое значение, позволяющее определить, нужно ли печатать только выбранные элементы или страницы целиком |
В отличие от методов класса CPageSetupDialog, метод CreatePrinterDC() можно вызывать без предварительного вызова метода DoModal(). Отображать этот диалог перед печатью необязательно, но класс CPrintDialog можно использовать для получения информации о принтере и контексте устройства.
Класс CFindReplaceDialog инкапсулирует стандартный диалог поиска и замены. В отличии от других стандартных диалогов, это окно немодальное, поэтому для отображения данного диалога нужно вызывать вместо метода DoModal() метод Create(). Метод Create() может принимать пять параметров, два первых из которых обязательны:
TRUE ) или для поиска и замены ( FALSE )FR_DOWN ). Направление "назад" устанавливается значением 0Принципы работы с классом CFindReplaceDialog более сложные, чем с другими классами стандартных диалогов. Мы их здесь рассматривать не будем. В таблице приводятся основные методы-члены класса CFindReplaceDialog
Основные методы доступа класса CFindReplaceDialog | |
|---|---|
| Функция | Описание |
|
Возвращает логическое значение, указывающее, нужно ли найти следующее вхождение искомой строки |
GetFindString() |
Возвращает введенную пользователем строку для поиска |
GetReplaceString() |
Возвращает введенную пользователем строку для замены |
IsTerminating() |
Возвращает логическое значение, позволяющее определить, решил ли пользователь закрыть этот диалог |
MatchCase() |
Возвращает логическое значение, которое указывает, нужно ли в поиске строки учитывать регистр |
MatchWholeWord() |
Возвращает логическое значение, которое указывает, нужно ли искать слово только целиком |
ReplaceAll() |
Возвращает логическое значение, которое указывает, нужно ли заменить все вхождения искомой строки |
ReplaceCurrent() |
Возвращает логическое значение, которое указывает, нужно ли заменить текущее найденное вхождение искомой строки |
SearchDown() |
Возвращает логическое значение, которое указывает, нужно ли выполнить поиск вперед от текущей позиции |
Создайте обработчик для кнопки "Диалог File Open"
Заполните его кодомОбработчик для щелчка по кнопке "Диалог File Open"
void CDialogsDlg::OnBnClickedBFileopen()
{
CFileDialog openFile(TRUE); // Создать диалог
if(openFile.DoModal() == IDOK){ // Отобразить и получить результат
m_strResult = openFile.GetFileName(); // Сохранить имя файла
UpdateData(FALSE); // Передать на экран
}
}
Добавим собственное диалоговое окно, которое будет предлагать пользователю поле редактирования, группу радиокнопок. Когда пользователь щелкнет на кнопке OK, введенный им текст отобразится в главном окне приложения. Для этого нужно будет выполнить следующие действия:
CDialog
Выберите вкладку
Выделите в нем пиктограмму
В панели Resource View выделите сгенерированный ресурс с дежурным именем IDD_DIALOG1 и через панель свойств присвойте ресурсу осмысленный идентификатор IDD_MESSAGEDLG. Не удаляйте кнопки OK и Cancel
Отредактируйте ресурс диалогового окна в соответствии с таблицей свойств| Таблица свойств диалогового ресурса IDD_MESSAGEDLG | ||
|---|---|---|
| Элемент управления | Свойство | Значение |
| Форма | Caption |
Диалог с сообщениями и опциями |
Font(Size) |
MS Sans Serif(10) |
|
Maximize Box |
False |
|
|
False |
|
Static Text |
Caption |
Введите сообщение: |
Right Align Text |
True |
|
Edit Control |
ID |
IDC_EMESSAGE |
Multiline |
True |
|
Auto VScroll |
True |
|
|
True |
|
Group Box |
Caption |
Выбор опции |
|
ID |
IDC_ROPTION1 |
Caption |
Опция 1 | |
Group |
True |
|
|
ID |
IDC_ROPTION2 |
Caption |
Опция 2 | |
Group |
False |
|
|
ID |
IDC_ROPTION3 |
Caption |
Опция 3 | |
Group |
False |
|
|
ID |
IDC_ROPTION4 |
Caption |
Опция 4 | |
Group |
False |
|
При редактировании диалогового ресурса периодически проверяйте дизайн кнопкой Test Dialog панели инструментов Dialog Editor. Размеры элементов управления контролируйте через панель состояния дизайнера. Для выравнивания элементов пользуйтесь инструментами на панели инструментов или опциями меню Format оболочки.
Окончательный вариант макета приведен на рисунке

Отметьте, что для согласованной работы радиокнопок мы для первого переключателя установили свойство Group в состояние True. В остальных же переключателях оставили его значение по умолчанию False. Это приведет к тому, что следующие по порядку их создания радиокнопки будут объединены в группу. Новая группа начнется с нового следующего по порядку создания радиопереключателя со свойством True (но у нас только одна группа). Порядок следования радиопереключателей можно посмотреть через опцию Edit/Resource Symbols (или через контекстное меню в панели Resource View, щелкнув на узле Dialogs.rc ) в окне Resource Symbols

Отредактировать порядок радиопереключателей можно в файле Resource.h, открыв его на редактирование через панель Solution Explorer (не рекомендуется!!!)

В этом файле оболочка формирует именованные константы
Именованные константы в файле Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Dialogs.rc
//
#define IDD_DIALOGS_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_MESSAGEDLG 131
#define IDC_B_YESNOCANCEL 1000
#define IDC_B_ABORTRETRYIGNORE 1001
#define IDC_B_CUSTOMDIALOG 1002
#define IDC_B_WHICHOPTION 1003
#define IDC_E_RESULT 1004
#define IDC_EMESSAGE 1005
#define IDC_B_FILEOPEN 1006
#define IDC_ROPTION1 1006
#define IDC_B_EXIT 1007
#define IDC_ROPTION2 1007
#define IDC_ROPTION3 1008
#define IDC_RADIO4 1009
#define IDC_ROPTION4 1009
............................................
Для управления диалоговым ресурсом создайте класс на основе базового класса CDialog. Для этого:
Выберите только что сконструированное окно приложения в режиме дизайна и через контекстное меню (или главное меню Project ) выполните опцию Add Class
Запустится мастер добавления класса, который нужно настроить в соответствии с рисунком

Убедитесь, что в поле выбран CDialog
После создания класса его код должен быть размещен в двух новых файлах MsgDlg.h и MsgDlg.cpp. Убедитесь в этом через панель Solution Explorer. Удобнее при создании новых классов размещать их в отдельных файлах. Мастер Add Class создал производный CDialog, поддерживающего диалоговые окна
Объявление производного класса CMsgDlg, наследника CDialog (код файла MsgDlg.h)
#pragma once
// CMsgDlg dialog
class CMsgDlg : public CDialog
{
DECLARE_DYNAMIC(CMsgDlg)
public:
CMsgDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CMsgDlg();
// Dialog Data
enum { IDD = IDD_MESSAGEDLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
Добавьте две ассоциированные переменные к элементам управления. Для этого выделите в панели
CMsgDlg ID (Объект связывания) Name (Имя)Type ( Тип)Category ( Категория)Accass ( Доступ)IDC_EMESSAGE m_strMessage Value CString public IDC_ROPTION1 m_iOption Value intpublic 

Мастер добавит в приложение код
Файл MsgDlg.h
class CMsgDlg : public CDialog
{
................................................
public:
// Для хранения значений поля редактирования
CString m_strMessage;
// Для распознавания выбранной радиокнопки
int m_iOption;
};
Файл MsgDlg.cpp
CMsgDlg::CMsgDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMsgDlg::IDD, pParent)
, m_strMessage(_T(""))
, m_iOption(0)
{
}
void CMsgDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EMESSAGE, m_strMessage);
DDX_Radio(pDX, IDC_ROPTION1, m_iOption);
}
Для переключателя с установленным свойством Group мы назначили ассоциированную целочисленную переменную m_iOption. Значение этой переменной зависит от того, какой из переключателей группы будет выбран пользователем. При выборе первого переключателя "Опция 1" эта переменная принимает значение 0, при выборе второго - значение 1, и т.д. , поскольку в C++ нумерация элементов массива или группы начинается с нуля.
Мы сконструировали собственный диалог, который теперь можно использовать точно также, как и стандартный диалог, а именно:
CMsgDlgDoModal() экземпляра и сохранить возвращаемое им значениеm_strMessage и m_iOptionprivate и добавив функции доступа к этим переменнымРешим эту задачу в соответствии со следующими пошаговыми инструкциями
Добавьте в объявление класса-клиента переменную-экземпляр созданного нами класса CMsgDlg в соответствии с настройкой мастера, приведенной ниже. Для этого выделите в панели Class View класс CDialogsDlg и через контекстное меню откройте мастер

Мастер добавит код
Объявление в классе CDialogsDlg переменной-экземпляра класса CMsgDlg
class CDialogsDlg : public CDialog
{
..............................................
private:
// Экземпляр класса нашего диалогового окна
CMsgDlg m_dMsgDlg;
};
Добавьте в класс-клиент CDialogsMsg директиву препроцессора (предварительного компилятора) для подключения к нему объявления класса-сервиса CMsgDlg. Для этого через панель Solution Explorer откройте на редактирование файл DialogsMsg.h и в самом начале файла, перед объявлением класса CDialogsDlg, подключите заголовочный файл с описанием класса CMsgDlg, как показано ниже
Подключение файла с объявлением класса-сервиса CMsgDlg
перед объявлением класса-клиента CDialogsDlg в файле DialogsDlg.h
// DialogsDlg.h : header file
//
#pragma once // Страж включения
#include "afxwin.h"
#include "MsgDlg.h"
// CDialogsDlg dialog
class CDialogsDlg : public CDialog
{
.....................................
};
Обратите внимание, что в каждом заголовочном файле, созданном оболочкой, она в самом начале файла размещает директиву препроцессора "#pragma once", которую называют стражем включения. Это связано с тем, что включение файла может быть размещено во многих местах приложения, а препроцессор должен включить в приложение только первый встретившийся экземпляр кода. Эта директива и поднимает флаг у препроцессора, заставляя его игнорировать повторные включения одного и того же кода. В реализациях других производителей компиляторов можно встретить иной прием
#ifndef ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА #define ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА код включаемого файла #endif
Добавьте обработчик к кнопке "Сконструированный диалог", запускающий на выполнение окно нашего диалога
Обработчик кнопки "Сконструированный диалог" запуска диалога
// Обработчик кнопки "Сконструированный диалог"
void CDialogsDlg::OnBnClickedBCustomdialog()
{
// Запросить информацию через диалог
if(m_dMsgDlg.DoModal() == IDOK){
m_strResult = m_dMsgDlg.m_strMessage;// Напрямую, т.к. public
// разблокировать кнопку "Какая опция?"
m_cWhichOption.EnableWindow(TRUE);
}
else
m_strResult = "Ввод информации отменен!";
// Передать на экран новое значение поля редактирования
UpdateData(FALSE);
}
Добавьте обработчик к кнопке "Какая опция?"Обработчик кнопки "Какая опция?"
// Обработчик кнопки "Какая опция?"
void CDialogsDlg::OnBnClickedBWhichoption()
{
// Какая радиокнопка включена
switch(m_dMsgDlg.m_iOption){
case 0:
m_strResult = "Была выбрана первая опция";
break;
case 1:
m_strResult = "Была выбрана вторая опция";
break;
case 2:
m_strResult = "Была выбрана третья опция";
break;
case 3:
m_strResult = "Была выбрана четвертая опция";
break;
default:
m_strResult = "Опция не выбрана!";
}
// Передать на экран новое значение поля редактирования
UpdateData(FALSE);
}
Запустите приложение и убедитесь в его работоспособности
Измените в объявлении класса CMsgDlg данные-члены m_strMessage и m_iOption как private
Добавьте к классу CMsgDlg методы доступа public, возвращающие значения этих переменных:CString GetMessage() {return m_strMessage;} int GetOption() {return m_iOption;}
Замените в последних двух обработчиках класса CDialogsMsg прямые вызовы переменных m_strMessage и m_iOption через вызовы функций доступа
Постройте окончательный вариант приложения в режиме Release и убедитесь, что размер исполнимого файла составляет примерно 15KЭто малый размер для такой задачи и объясняется это тем, что при создании приложения мы настроили мастер на использование библиотек DLL
| Таблица настройки мастера создания каркаса приложения | |
|---|---|
Use of MFC: |
Use MFC in a shared DLL |
Такое приложение не будет работать на компьютере, где нет этих библиотек. Поэтому следует построить автономное приложение, включающее в себя весь необходимый код. Для этого:
Выполните опцию Project/Dialogs Properties для нашего проекта Dialogs

Появится окно, в котором установите режим
| Изменение режима в таблице свойcтв приложения | |
|---|---|
Use of MFC: |
Use MFC in a Static Library |

Перестройте приложение и определите размер исполнимого файлаИсполнимый файл приложения увеличился примерно до 155K. Такой файл будет работать на любом компьютере с операционной системой Windows.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.