Застосування DDX для передачі даних

Лекця № 19

Тема: Клас Cedit. Клас CListBox

План

1. Застосування класу CEdit

2. Застосування DDX для передачі даних

3. Застосування класу CListBox

4. Додавання і видалення елементів

5. Пошук і вибір елементів

 

Застосування класу CEdit

Елемент управління поле введення (edit control), що інкапсулюється класом CEdit, є прямокутне дочірнє вікно, в якому користувач може вводити дані. Як правило, це найбільший елемент управління в додатку. Змінюючи стилі цього елементу управління, можна отримати все, що завгодно, від простого поля введення з одним рядком тексту до багаторядкового вікна редагування (MLE — multiline edit) і поля введення пароля, вміст якого відображається зірочками, а не реально введеними даними. При кожному натисненні користувачем клавіші поле введення посилає повідомляюче повідомлення свого батьківського вікна перш, ніж введений символ буде відображений на екрані. Це дозволяє легко створювати різноманітні обробники, що фільтрують введення символів. Таким чином, основна увага цього розділу приділена опису способів маніпулювання цим багатоликим елементом управління.

У елементі управління класу CEdit можна розмістити не більше 60 Кбайт тексту. Це дозволяє використовувати елемент управління CEdit для введення лише невеликих об'ємів тексту, але якщо необхідно маніпулювати об'ємом тексту понад 60 Кбайт, можна скористатися класом CRichEditCtrl.

 

Застосування DDX для передачі даних

У розділі "Прімененіє DDX і шаблону елементу управління діалогового вікна" описувалося застосування DDX для організації взаємодії між класами елементу управління і самими елементами управління. Там же побіжно згадувалося про те, що DDX застосовується для передачі даних між елементами управління і змінними-членами класу елементу управління. Оскільки полем введення є перший елемент управління в цьому розділі, який допускає введення даних користувачем, — це якнайкраще місце, щоб почати вивчення даного аспекту застосування DDX.

Розмістивши елементи управління в шаблоні діалогового вікна, клацніть правою кнопкою миші на полі введення Те (Кому) і в контекстному меню, що з'явилося, виберіть пункт Add Variable (Додати змінну). Це приведе до виклику майстра Add Member Variable Wizard, робота якого демонструвалася вже не раз. В першу чергу необхідно скинути прапорець Control variable (Змінна, що управляє), оскільки він використовується для створення керівників змінних DDX (DDX control variable), а тут необхідно створити змінну значення DDX (DDX value variable). Скинувши цей прапорець, можна відмітити, що список доступних типів змінної став набагато більший. Прокрутивши список, можна побачити безліч різних типів змінних-членів, які можуть бути призначені елементу управління. У версії Visual Studio, використаній автором, тип CString не був передбачений в цьому списку, тому його доводилося просто указувати уручну: CString. Потім необхідно ввести ім'я змінної, m_strTo, і клацнути на кнопці Finish (Готово).

Тепер давайте розглянемо, що було зроблене від імені розробника. Відкрийте файл заголовка editdlg.h і відшукайте визначення змінної-члена m__strTo. Як можна відмітити, ця змінна-член була визначена як відкрита (public):

 

public: CString m_strTo;

 

Потім відкрийте файл реалізації editdlg.cрр і знайдіть конструктор CEditDlg. Тут ця змінна-член ініціалізувалася в списку ініціалізатора (initializer list) класу:

 

CEditDlg::CEclitDlg (CWnd* pParent/*=NULL*/):CDialog(CEditDlg::IDD

pParent), m strTo(L"")

{

}

 

Поки нічого нового, але скоро все зміниться. Знайдіть функцію DoDataExchange. Нагадуємо, що це головна функція DDX, яку викликає функція UpdateData, яку, у свою чергу, викликають як при ініціалізації діалогового вікна, так і в обробнику події ОПОК. Отже, розглянемо функцію DoDataExchange, а також функцію UpdateData, оскільки вона теж має відношення до застосування змінних значень DDX.

Звернете увагу на реалізацію функції DoDataExchange. Тепер замість функції DDX_Control, що застосовувалася раніше в цьому розділі, здійснюється звернення до функції DDX_Text:

 

void CEditDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

DDX_Text(pDX, IDC EDIT1, m strTo);

}

 

Після вивчення цієї функції, очевидно, стане трохи зрозуміліше, як здійснюється обмін даними між елементами управління і змінними-членами класу. До речі, функція DDX_Text має 37 переобтяжених версій реалізації! Таку кількість переобтяжених версій функції дозволяють використовувати змінні практично всіх основних типів даних, включаючи byte, short, int і CString. Можна навіть використовувати такі типи змінних, як COleCurrency і COleDataTime.

Прослідкувавши виклики усередині функції DDX_Text, можна відмітити, що після звернення до функції PrepareEditCtrl перевіряється вміст змінної m_bSaveAndValidate Якщо вона містить значення TRUE, то функція отримує текст з елементу управління (за допомогою звернення до функції SDK. Win32 GetWindowText) і привласнює його вказаній змінній. Якщо змінна m_bSaveAndValidate містить значення FALSE, то здійснюється прямо протилежна дія: елемент управління оновлюється значенням, що міститься у вказаній змінній.

У початковому коді MFC замість звернення до функції Win32::SetWindowText нерідко можна побачити звернення до функції AfxSetWindowText. Річ у тому, що перед привласненням значення допоміжна функція AfxSetWindowText перевіряє, чи не співпадає вміст зпемента управління із значенням змінної. Збіг обох значень означає, що ніяких змін не відбулося, тому функція завершує роботу, не роблячи нічого. Отже, ця недокументована функція MFC є вельми корисним засобом.

 

void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CStringi value)

{

HWND hWndCtrl = pDX->PrepareEditCtrl (nIDC) ;

if (pDX->m_bSaveAndValidate) {

int nLen = ::GetWindowTextLength(hWndCtrl);

::GetWindowText(hWndCtrl,value.GetBufferSetLength(nLen),nLen+1);

value.ReleaseBuffer ();

}

else { AfxSetWindowText(hWndCtrl, value); }

}

 

Виникає резонне питання; "Де встановлюється значення змінної CDataExchange: m_bSaveAndValidate?" У функції UpdateData. Функції UpdateData передають один параметр, bSaveAndValidate, який і визначає напрям переміщення даних: з члена класу в елемент управління (bSaveAndValidate = FALSE) або навпаки, з елементу управління в член класу (bSaveAndValidate = TRUE).

Вивчивши роботу цього механізму, область застосування змінних значення DDX можна описати таким чином.

- Існують дві можливості ініціалізації значень діалогового вікна, перш ніж воно буде відображено на екрані. Значення можна встановити перед зверненням до функції OnlnitDialog базового класу, а можна, привласнивши значення змінним, викликати уручну функцію UpdateData (FALSE).

- Щоб доручати поточні значення елементів управління діалогового вікна і розмістити їх в змінних-членах класу діалогового вікна, досить викликати функцію UpdateData(TRUE).

- Обробник події CDialog: :OnOK викликає функцію UpdateData (TRUE). Отже, якщо для виходу і завершення роботи діалогового вікна здійснюється виклик функції ОПОК, то та функція, яка викликала функцію діалогового вікна DoModal, отримає всі поточні дані діалогового вікна в коректному вигляді.