Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии программирования. Программирование графических интерфейс

.pdf
Скачиваний:
3
Добавлен:
15.11.2022
Размер:
2.24 Mб
Скачать

Для создания немодального блока диалога и присоединения его к объекту CDialog вызывается конструктор

CDialog :: CDialog (),

а затем метод

BOOL CDialog :: Create(UINT nIDTemplate, CWnd

*pParentWnd= NULL)

При этом для немодального диалогового окна необходимо установить стиль WS_VISIBLE.

Немодальное окно отображается вызовом метода

CWnd :: ShowWindow();

а удаляется вызовом метода

CWnd :: DestroyWindow();

Вслучае модального окна функции Create(), ShowWindow()

иDestroyWindow() вызываютсявнутриметода DoModal().

Класс CDialog имеет встроенную поддержку обработки команд от кнопок OK и Cancel.

СDialog :: OnOK()

СDialog :: OnCancel()

Эти функции вызывают функцию СDialog :: EndDialog(), закрывающую диалоговое окно. При вызове функции EndDialog() ей передается один аргумент, значение которого возвращается создавшей данное диалоговое окно функцией DoModal(). Функция OnOK() передает функции EndDialog() значение IDOK,

а OnCancel() – IDCANCEL.

Создание диалогового окна можно связать с каким-либо обработчиком, например обработчиком команды меню.

Тогда в классе приложения CMyApp надо выполнить следующее:

1. В карту сообщений добавить

ON_COMMAND(ID_MENU1, OnMyDialog)

2. В определение класса добавить

afx_msg void OnMyDialog()

3. Определить функцию OnMyDialog следующим образом: void CMyApp :: OnMyDialog ()

91

{ СMyDialog dlg;

if (IDOK==dlg.DoModal())

{

/*действия при нажатии ОК*/

}

else

{

/*действия при нажатии Cancel*/

}

}

5.3. Обмен даннымипосредством диалогового окна

Механизм обмена данными посредством диалогового окна (Dialog Data Exchange-DDX) представляет собой простейший способ передачи информации в элементы управления диалогового окна и получения информации из них.

Для организации обмена используются объект класса

CDataExchange и две функции CWnd :: UpdateData() и CWnd

:: DoDataExchange().

Объект класса СDataExchange() содержит две переменные:

BOOL m_bSaveAndValidate – указывает направление при операциях обмена:

TRUE – от элементов управления к членам-данным класса, т.е. считывание информации;

FALSE – от членов-данных класса к элементам управления;

CWnd *m_pDlgWnd – указатель на объект, для которого осуществляется обмен.

Функции имеют следующий вид:

BOOL CWnd :: UpdateData(BOOL bSaveAndValidate=TRUE);

virtual void CWnd :: DoDataExchang(CDataExchange *pDX);

92

Когда с помощью мастера ClassWizard в классе диалогового окна создается переменная, связанная с одним из элементов управления шаблона диалогового окна, Class Wizard одновременно добавляет вызов функции DDX_ между строками

//AFX_DATA_MAP в функции DoDataExchange() класса диа-

логового окна.

Пример.

void CMyDlg :: DoDataExchange(CDataExchange *pDX) {CDialog :: DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg)

DDX_Text(pDX, IDC_NAME, m_strName); //}}AFX_DATA_MAP

}

Функция DoDataExchange() вызывается приложением для обмена информацией и ее проверки. В качестве аргумента ей передается указатель на объект класса СDataExchange, содержащий контекстную информацию, необходимую для реализации механизма DDX.

Функцию DoDataExchange() необходимо переопределить для каждого класса блока диалога, который должен обеспечивать взаимодействие с пользователем.

Функция DoDataExchange() никогда не вызовется непосредственно. Вместо нее вызывается функция UpdateData(). Эта функция создает объект класса СDataExchange и вызывает функцию

DoDataExchange(). Если аргумент функции UpdateData() имеет значение TRUE, функция формата DDX записывает информацию о состоянии элемента управления диалогового окна в соответствующуюпеременную класса; если– FALSE, то наоборот.

Функция UpdateData() автоматически вызывается приложением. Первый раз это происходит при вызове функции CDialog :: OnInitDialog(). Эта функция вызывает UpdateData(FALSE), что приводит к инициализации элементов управления диалогового окна. Второй раз функция UpdateData() автоматически вызывается

93

приложением в функции CDialog :: OnOK(), но в этом случае ей передается аргумент TRUE.

Для проверки данных при вводе в диалоговом окне используется вызов функции DDV_.

Если используется ClassWizard для добавления переменных в диалоговое окно, можно (для некоторых типов переменных) задать для них проверяемые параметры. В этом случае Class Wizard поместит за вызовом функции DDX_ вызов соответственно функции DDV_.

Общая схема определения функции DoDataExchange() следующая:

void CMyDlg :: DoDataExchange(CDataExchange *pDX)

{

// вызов родительского метода

CDialog :: DoDataExchange(pDX); //вызов DDX – функции для обмена

//вызовDDV – функциидляпроверкикорректностиввода

}

Для получения информации из диалогового окна может быть использован, например, следующий код:

CMyDialog dlg; dlg.m_strName=””;

if (dlg.DoModal()==IDOK)

{m_theName=dlg.m_strName;}

Перечислим основные DDXфункции:

DDX_Text – для обмена текстовыми или числовыми дан-

ными (CString, int, double),

DDX_Check – для обмена текстовыми или числовыми данными и данными логического типа,

DDX_Radio – для обмена данными типа int с группой радиокнопок,

DDX_Control – для обмена данными типа CWnd с некоторыми элементами управления.

94

Пример

Обмен с блоком редактирования CEdit

DDX_Text(pDX, IDC_EDIT1, m_sData);

Функции DDV имеют следующие параметры: первый параметр типа CDataExchange* – контекст обмена. Хранит информацию о направлении обмена; второй параметр – контролируемые переменные; следующий параметр – сами ограничения.

Например

DDV_MaxChars(pDX, m_sData, 3);

Вызов DDV_ функции рекомендуется помещать сразу после вызова соответствующей функции DDX_. У всех функций DDV существует одно ограничение – проверка осуществляется только после того, как пользовательнажимаетОК, а нев процессенабора.

МастерClassWizard размещаетфункцииDDV автоматически.

Пример

void CMyDlg :: DoDataExchange(CDataExchange *pDX) {CDialog :: DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg)

DDX_Text(pDX, IDC_PERSON_ID, m_nID); DDV_MinMaxUInt(pDX, m_nID,1,9999); DDX_Text(pDX, IDC_PERSON_NAME, m_strName); DDV_MaxChars(pDX, m_strName, 30); //}}AFX_DATA_MAP

}

5.4. Использование ClassWizard

ClassWizard – мастер классов предназначен для работы с классами: создание классов, добавление в них методов и свойств. При создании проекта «MFC AppWizard» ClassWizard автоматически подсоединяется к проекту.

ClassWizard хранит свои данные в файле с расширени-

ем *.clw.

95

ClassWizard вставляет специального вида комментарии, которые являются опознавательным знаком ClassWizard. Именно между строчками комментария он будет писать чтото свое.

Теперь посмотрим, как можно создать диалоговое окно

ссозданием нового класса.

1.Создаем ресурс для нового окна.

2.Вызываем для нового диалогового окна контекстное меню и выбираем в нем ClassWizard.

3.В появившемся окне Adding a class выбираем Create a new class инажимаем OK.

4.Появится окно New class. В нем задаем свойства Name

как «CMyDialog», Base class как «CDialog» и убеждаемся, что в списке DialogID выбран идентификатор нового диалога

«IDD_DIALOG». Нажимаем OK.

Для добавления в класс CMyDialog новых членовданных и членов-функций используем ClassWizard.

Для добавления членов-данных:

– в основном окне MFC ClassWizard (вкладка Member Variable) устанавливаем поля Class name, Control IDs (для ре-

сурса) и нажимаем кнопку Add Variable;

– в появившемся окне Add Member Variable устанавлива-

ем поля Member variable name, Category, Variable type. Нажи-

маем OK.

Для добавления новых функций, например обработчи-

ков сообщений:

– в основном окне MFC ClassWizard перейдите на вкладку MessageMaps и установите поля Class name, Object

IDs, Messages;

нажимаем на кнопку Add Function, а затем на EditCode;

в появившемся окне увидим заготовку обработчика сообщений.

96

5.5. Пример создания простой программы для обмена данными между диалоговыми окнами

1.Создайте рабочую область (workspace) с именем lab05.

2.В этой рабочей области создайте проект как приложение MFC AppWizard(exe). Выберите тип приложения SDI. Отключите поддержку архитектуры Document/View.

3.Используя редактор ресурсов, создайте шаблон блока диалога для ввода данных.

4.Используя ClassWizard, создайте класс диалогового окна для ввода данных.

5.Добавьте в класс члены-данные для обмена с блоком диалога. Функции DDX и DDV добавятся автоматически.

6.Проанализируйте сформированный мастером код.

7.Используя редактор ресурсов, добавьте меню «Диалог»

икоманды «Создать объект» и «Показать объект».

8.Запишите обработчик сообщения от команды «Создать объект».

9.Откомпилируйте и выполните программу. При выборе команды меню «Создать объект» появляется окно, подобное показанному на рис. 5.1.

Рис. 5.1

97

10. То же самое сделайте для просмотра данных.

Рис. 5.2

11. Откомпилируйте и выполните программу. При выборе команды меню «Просмотреть объект» появляется окно, подобное показанному на рис. 5.2.

98

6.ХРАНЕНИЕ ДАННЫХ В ПРОГРАММЕ MFC

6.1.Хранение данных в памяти – коллекции

Коллекции можно определить как набор элементов, объединенных в единое целое. В этом смысле коллекции в MFC играют ту же роль, что и контейнеры в стандартной библиотеке C++. MFC предоставляет группу классов коллекций – массивы (array), списки (list) и отображения (map), которые могут хранить различные объекты и данные предопределенных типов. Эти классы могут использоваться как в консольном, так

ив Windows-приложении.

Вбиблиотеке MFC Имеются следующие классы массивов:

Имя класса коллекции

Тип элементов коллекции

CByteArray

BYTE

CWordArray

WORD

 

 

CDWordArray

DWORD

 

 

CUIntArray

UINT

 

 

CObArray

Указатели на объекты типа CObject или

 

производных от него

CPtrArray

Указатели типа void

CStringArray

CString

Чаще всего используется массив CObArray.

Он создается конструктором CObArray(). Конструктор создает пустой массив для CObject указателей.

Следующие методы полезны для работы с массивом

CObArray:

int GetSize( ) const; возвращает размер массива. BOOL IsEmpty( ) const; определяет пустой ли массив. void RemoveAll( ); удаляет все указатели из масси-

ва, но не удаляет CObject-объекты.

99

void RemoveAt( INT_PTR nIndex, INT_PTR nCount = 1 );

удаляет nCount указателей, начиная с nIndex, не удаляя сами объекты.

int Add(CObject* newElement ); добавляет объект в конец массива и возвращает его индекс.

void SetAt(int nIndex, CObject* newElement ); заменяет объект в заданной позиции.

void InsertAt(INT_PTR nIndex, CObject* newElement, int nCount = 1); вставляет элементы в заданную позицию.

CObject* GetAt(int nIndex ) const; возвращает объект в за-

данной позиции.

CObject*& operator [](INT_PTR nIndex ); доступпоиндексу.

6.2. Пример создания GUI-программы, использующей коллекции

1. В существующей рабочей области создайте проект как приложение MFC AppWizard(exe). Выберите тип приложения SDI. Отключите поддержку архитектуры Document/View.

2.Определите пользовательский класс. Определение класса сохраните в h-файле, определение функций – в cpp-файле. Для успешной работы с массивом CObArray наследуйте пользовательский класс от CObject. Массив CObArray поместите в класс приложения

3.Используя редактор ресурсов, создайте шаблон блока диалога для ввода данных при создании объекта.

4.Используя ClassWizard, создайте класс диалогового окна для ввода данных.

5.Добавьте в класс члены-данные для обмена с блоком диалога. Функции DDX и DDV добавятся автоматически.

6.Используя редактор ресурсов, добавьте меню «Диалог»

икоманды «Создать объект» и «Показать объект». Обработчики команд меню поместите в класс приложения.

100