Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Для активизации DDX требуется перегрузить виртуальную функцию CDialog::DoDataExchange. В нее надо внести специальные функции DDX, предназначенные для обмена данными между ЭУ и переменными-членами различных типов данных. Например, в нашем классе CMyDialog функция-член DoDataExchange может быть реализована так:

void CMyDialog::DoDataExchange( CDataExchange* pDX )

{

DDX_Text( pDX, IDC_NAME, m_strName );

DDX_Text( pDX, IDC_PHONE, m_strPhone );

}

MFC вызывает DoDataExchange один раз при создании диалогового окна (из обработчика сообщения WM_INITDIALOG) и еще раз при нажатии кнопки OK. Параметр pDX указывает на объект класса CDataExchange, который, например, задает функциям наподобие DDX_Text направление копирования данных – из ЭУ в переменные-члены или наоборот. Т. о., одного вызова DoDataExchange достаточно для передачи данных во все ЭУ, данные от которых требуется получать в данном окне. Список функций передачи данных DDX приведен в табл. 8.1.

Таблица 8.1. Функции диалогового информационного обмена (DDX)

Функция DDX

Описание связи ЭУ и переменных-членов

DDX_Text

Элемент редактирование и переменная-член одного из следующих типов: BYTE, int, short, UINT, long, DWORD, CString, string, float, double, COleDateTime, COleCurrency

DDX_Check

Кнопка с независимой фиксацией и переменная int

DDX_Radio

Группа кнопок с независимой фиксацией и переменная int

DDX_LBIndex

Список и переменная int

DDX_LBString

Список и переменная CString

DDX_LBStringExact

Список и переменная CString

DDX_CBIndex

Комбинированный список и переменная int

DDX_CBString

Комбинированный список и переменная CString

DDX_CBStringExact

Комбинированный список и переменная CString

DDX_Scroll

Полоса прокрутки и переменная int

Кроме DDX, в MFC есть родственный механизм DDV – диалоговый информационный обмен с проверкой данных (Dialog Data Validation, DDV). Он позволяет перед закрытием диалогового окна проверить данные ЭУ на корректность. Функции DDV делятся на две группы: проверка численных значений на попадание в диапазон и проверка переменных типа CString для того, чтобы строки были заданной длины. Ниже приведен пример функции DoDataExchange, в которой DDX_Text применяется для связи строки ввода и целочисленной переменной, а DDV_MinMaxInt – для проверки попадания значения этой переменной в диапазон от 0 до 100 (проверка выполняется только при нажатии кнопки OK):

НЕ нашли? Не то? Что вы ищете?

void CMyDialog::DoDataExchange( CDataExchange* pDX )

{

DDX_Text( pDX, IDC_COUNT, m_nCount );

DDV_MinMaxInt( pDX, m_nCount, 0, 100 );

}

Если значение m_nCount будет меньше 0 или больше 100, то DDV_MinMaxInt установит фокус ввода строку ввода и выведет сообщение об ошибке. Для данного ЭУ вызов функции DDV должен следовать непосредственно после вызова функции DDX, чтобы MFC смогла правильно установить фокус ввода при обнаружении ошибки.

Сами средства DDX/ DDV реализованы внутри CDialog. Когда диалоговое окно создается, CDialog::OnInitDialog вызывает функцию CWnd::UpdateData с параметром FALSE. В свою очередь, UpdateData создает объект CDataExchange и передает указатель на него функции диалогового окна DoDataExchange. Внутри DoDataExchange вызываются функции DDX для инициализации ЭУ значениями из переменных-членов. Позднее, когда пользователь нажимает OK, из CDialog::OnOK вызывается UpdateData с параметром TRUE, что приводит к копированию функциями DDX данных из ЭУ в переменные-члены. Если в DoDataExchange есть вызовы функций DDV, то именно на этом этапе они проверяют корректность введенных пользователем данных. Описанный порядок работы DDX/DDV объясняет, почему из перегруженных функций OnOK и OnInitDialog обязательно надо вызывать эти функции из базового класса – иначе не будет вызвана UpdateData и DDX/DDV не будет работать.

1.4.1 Поддержка механизма DDX/DDV в ClassWizard'е

Если при разработке приложения вы пользуетесь мастерами MFC, то вы можете не добавлять в DoDataExchange вызовы функций DDX/DDV вручную, а делать это с помощью ClassWizard. ClassWizard может даже автоматически добавлять в описание класса диалогового окна все необходимые для DDX/DDV переменные-члены. Ниже описан порядок добавления в класс диалогового окна переменной-члена и ее связи с ЭУ через механизм DDX/ DDV:

1)  Вызовите ClassWizard (командой меню View) и перейдите на закладку Member Variables (рис. 8.4).

Рис. 8.4. Окно ClassWizard'а: закладка с переменными-членами класса диалогового окна.

Рис. 8.5. Диалоговое окно ClassWizard для добавления новой переменной-члена в диалоговый класс.

2)  В списке Class Name выберите имя класса диалогового окна.

3)  В списке Control ID выделите идентификатор ЭУ, который вы хотите связать с переменной членом, и нажмите кнопку Add Variable.

4)  В диалоговом окне Add Member Variable (рис. 8.5) введите имя новой переменной-члена и выберите ее тип в списке Variable Type. Затем нажмите кнопку OK.

Если вы посмотрите на исходный текст класса диалогового окна после закрытия окна ClassWizard, то увидите, что ClassWizard добавил в класс переменную-член, а в функцию DoDataExchange поместил вызов функции DDX для связи переменной-члена с ЭУ. Если переменная числовая (как на рис. 8.4), то в нижней части закладки Member Variables окна ClassWizard вы можете указать минимальное и максимальное значение диапазона, попадание в который будет контролироваться с помощью функции DDV_MinMax.

1.5 Взаимодействие с элементами управления диалогового окна

Несмотря на удобство средств DDX/DDV, полностью отказаться от обращения к ЭУ с помощью классов-оболочек ЭУ удается далеко не всегда. Например, может потребоваться вызывать функции CListBox для заполнения списка строками из OnInitDialog. Для этого необходим указатель на объект CListBox, представляющий список – ЭУ окна. Как его получить?

Указатель типа (CWnd*) для любого ЭУ окна можно получить функцией CWnd::GetDlgItem. Например, для включения запрещенной кнопки с независимой фиксацией IDC_CHECK, можно записать следующие вызовы:

CWnd* pWnd = GetDlgItem( IDC_CHECK );

pWnd->EnableWindow( TRUE );

Этот исходный текст правилен, т. к. GetDlgItem возвращает указатель на CWnd, а функция EnableWindow является членом класса CWnd. Теперь рассмотрим следующий фрагмент текста:

CListBox* pListBox = (CListBox*)GetDlgItem( IDC_LIST );

pListBox->AddString( "Первый элемент" );

pListBox->AddString( "Второй элемент" );

pListBox->AddString( "Третий элемент" );

Здесь для вызова функций-членов CListBox потребовалось выполнить преобразование типа для указателя, полученного от GetDlgItem. Явное преобразование типа указателей – плохой стиль программирования, и если ЭУ с идентификатором IDC_LIST в окне не окажется, может произойти серьезная ошибка доступа по нулевому указателю.

Лучшим решением является присоединение оконного дескриптора ЭУ к классу-оболочке ЭУ с помощью CWnd::Attach. Сначала надо создать объект класса ЭУ (например, CListBox), а затем динамически присоединить к нему ЭУ, например:

CListBox wndListBox;

wndListBox. Attach( GetDlgItem( IDC_LIST )->m_hWnd );

wndListBox. AddString( "Первый элемент" );

wndListBox. AddString( "Второй элемент" );

wndListBox. AddString( "Третий элемент" );

wndListBox. Detach();

Т. к. объект CListBox был создан в стеке, очень важно вызывать Detach до того, как объект CListBox будет уничтожен. Иначе деструктор CListBox удалит ЭУ и список исчезнет из диалогового окна.

Чтобы не писать вызовы функций присоединения/отсоединения ЭУ от объекта-оболочки, можно сопоставить их с помощью функции DDX_Control. Например, чтобы связать переменную-член m_wndListBox класса CListBox со списком с идентификатором IDC_LIST, в DoDataExchange надо внести вызов:

DDX_Control( pDX, IDC_LIST, m_wndListBox );

Теперь добавлять строки в список можно, просто вызывая AddString у m_wndListBox:

m_wndListBox. AddString( "Первый элемент" );

m_wndListBox. AddString( "Второй элемент" );

m_wndListBox. AddString( "Третий элемент" );

Вызовы DDX_Control в функцию DoDataExchange удобно добавлять с помощью ClassWizard. Для этого надо перейти на закладку Member Variables и с помощью кнопки Add Variable добавить в класс переменную-член. Но в окне Add Member Variable (рис. 8.5) в списке Category надо вместо Value выбрать Control. Затем в списке Variable Type выберите класс ЭУ и нажмите кнопку OK. Если после выхода из ClassWizard вы посмотрите на исходный текст диалогового класса, то увидите, что ClassWizard добавил в класс переменную-член, а также вызов функции DDX_Control для связи этой переменной с элементом управления.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32