Иллюстрированный самоучитель по Visual Studio .NET

Диалог по управлению светом

Особенности немодального режима

Рассматриваемый диалог используется в качестве панели управления освещением сцены, поэтому он должен работать в немодальном режиме. Особенностью такого режима, как вы знаете, является то, что при закрытии диалога он сам должен позаботиться об освобождении памяти, выделенной под объект собственного класса. Эту задачу можно решить разными способами. Здесь мы покажем, как это делается в функции обработки сообщения WM_CLOSE.

До того как уничтожено Windows-окно диалога, мы обнуляем указатель m_pDlg, который должен храниться в классе COGView и содержать адрес объекта диалогового класса. Затем вызываем родительскую версию функции OnClose, которая уничтожает Windows-окно. Только после этого мы можем освободить память, занимаемую объектом своего класса:

void CPropDlg::OnClose (void)
{
//=== Обнуляем указатель на объект своего класса
m_pView › m_pDlg = 0;
//====== Уничтожаем окно
CDialog::OnClose ();
//====== Освобождаем память
delete this;
}

Реакция на нажатие кнопки IDC_FILENAME совсем проста, так как основную работу выполняет класс COGView. Мы лишь вызываем функцию, которая реализована в этом классе:

void CPropDlg:: OnClickedFilename (void)
{
//=== Открываем файловый диалог и читаем данные
m_pView › ReadData ();
}

Создание немодального диалога должно происходить в ответ на выбор команды меню Edit › Properties. Обычно объект диалогового класса, используемого в немодальном режиме, создается динамически. При этом предполагается, что класс родительского окна хранит указатель m_pDlg на объект класса диалога. Значение указателя обычно используется не только для управления им, но и как признак его наличия в данный момент. Это позволяет правильно обработать ситуацию, когда диалог уже существует и вновь приходит команда о его открытии. Введите в класс COGView новую public-переменную:

CPropDlg *m_pDlg; // Указатель на объект диалога

В начало файла заголовков OGView.h вставьте упреждающее объявление класса:

CPropDlg:
class CPropDlg; // Упреждающее объявление

В конструктор COGView вставьте обнуление указателя:

m_pDlg =0; // Диалог отсутствует

Для обеспечения видимости класса CPropDlg дополните список директив препроцессора файла OGView.cpp директивой:

linclude "PropDlg.h"

Теперь можно ввести коды функции, которая создает диалог и запускает его вызовом функции Create (в отличие от DoModal для модального режима). Если происходит попытка повторного открытия диалога, то возможны два варианта развития событий:

  • новый диалог не создается, но окно существующего диалога делается активным;
  • команда открытия диалога недоступна, так как ее состояние зависит от значения указателя m_pDlg.

Реализуем первый вариант:

void COGView::OnEditProperties (void)
{
//====== Если диалог еще не открыт
if (!m_pDlg)
{
//=== Создаем его и запускаем в немодальном режиме
m_pDlg = new CPropDlg(this);
m_pDlg › Create(IDD_PROP);
}
else
// Иначе, переводим фокус в окно диалога
m_pDlg › SetActiveWindow();
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.