Итак, нам надо создать диалог, который будет во время работы давать доступ к основному окну приложения.
Делаем приложение на базе 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).