Шаг 248 - Организация немодального диалога

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

Делаем приложение на базе SDI с именем Test, создаем диалоговое окно и в свойствах окна ставим Visible (без этого флага надо вызывать ShowWindow()). Тут же вызываем ClassWizard и создаем новый класс CTestDial производный от Cdialog.

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

Добавляем в класс CTestDial указатель на CView (с помощью него мы будем посылать сообщения Виду), и конструктор вот так:

class CTestDial : public CDialog
{
// Construction
public:
	CTestDial(CWnd* pParent = NULL);   // standard constructor
	CTestDial(CView* pView);
	CView* m_pView;

Инициализируем указатель в конструкторе:

CTestDial::CTestDial(CView* pView)
{
	m_pView = pView;
}

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

BOOL CTestDial::Create()
{
	return CDialog::Create(CTestDial::IDD);
}

Далее добавляем в класс CTestView указатель на наш диалог:

// Attributes
public:
	CTestDial* m_pTestDial;

В конструкторе класса CTestView создаем объект диалога, а в деструкторе уничтожаем объект:

CTestView::CTestView()
{
	m_pTestDial = new CTestDial(this);
}

CTestView::~CTestView()
{
	delete m_pTestDial;
}

В начало файла Вида добавим объявление нашего класса диалога :

#include "TestDial.h"

Наш диалог будет вызываться на выбор команды меню. Создаем пункт меню TestDialog и обработчик к этому пункту в классе Вида, в обработчике создаем окно вот так:

void CTestView::OnTestdialog() 
{
	m_pTestDial->Create();	
}    

Мы создали окно, теперь нам надо его разрушить. Удаляем кнопку "OK" она нам не нужна, и создаем обработчик для кнопки "Cancel" с идентификатором IDCANCEL:

void CTestDial::OnCancel() 
{
	m_pView->PostMessage(WM_ENDOFDIAL);
}

В TestDial.h вставляем строку:

#define WM_ENDOFDIAL  WM_USER + 10

В карту сообщений Вида вставляем строку:

BEGIN_MESSAGE_MAP(CTestView, CView)
	//{{AFX_MSG_MAP(CTestView)
	ON_COMMAND(ID_TESTDIALOG, OnTestdialog)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_ENDOFDIAL, OnEndOfDial)
END_MESSAGE_MAP()

В класс вида добавляем функцию:

LONG CTestView::OnEndOfDial(UINT wParam, LONG lParam)
{
	m_pTestDial->DestroyWindow();

	return 0;
}

При нажатии на кнопку "Cancel" мы посылаем Виду свое сообщение, которое определили в TestDial.h, Вид может его обработать т.к. мы описали его в карте сообщений, далее запускается OnEndOfDial и окно уничтожается вот и вся немодальность. Запускаете и наслаждайтесь послушным окном.

Заметим, что объект диалогового окна существует на протяжении выполнения всей программы т.к. объект создается и уничтожается в классе Вида.

Шаг прислал Panov Denis (stream@yandex.ru).


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 27.10.2000