Приложение с немодальной диалоговой панелью
Процедура создания немодальной диалоговой панели несколько отличается от процедуры создания модальной диалоговой панели. Как и в случае с модальной диалоговой панелью, в первую очередь необходимо создать шаблон диалоговой панели и добавить его в файл ресурсов приложения.
Затем нужно создать класс, управляющий диалоговой панелью, - класс диалоговой панели. Этот класс наследуется непосредственно от базового класса CDialog. Для создания немодальной диалоговой панели необходимо объявить объект класса диалоговой панели. В примере класс немодального диалога определяется как переменная класса CMainFrame nodialog (см. файл MainFrm.h):
#include "MyDialog.h"
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
CMyDialog nodialog;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg void OnModal();
afx_msg void OnNomodal();
afx_msg void OnNoshowdialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Для инициализации панели немодального диалога надо вызвать метод Create класса CDialog.
Метод Create можно вызвать непосредственно из конструктора класса диалоговой панели, либо уже после создания объекта. Если Create вызывается из конструктора класса диалоговой панели, надо определить конструктор, объявив его как public. В примере метод Create вызывается в конструкторе класса CMainFrame:
CMainFrame::CMainFrame()
{
nodialog.Create(IDD_MYDIALOG , NULL );
}
В классе CDialog определены два прототипа метода Create. Один позволяет указать диалоговую панель через ее текстовое имя, а другой - через числовой идентификатор.
BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL );
BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );
Параметр lpszTemplateName содержит указатель на строку с именем шаблона, параметр nIDTemplate определяет номер идентификатора ресурса. Параметр pParentWnd указывает на родительское окно, которому принадлежит диалог. Если pParentWnd равен NULL, то владелец - основное окно приложения.
Метод Create возвращает ненулевое значение, если создание диалоговой панели завершилось успешно, и нуль в противном случае.
Если диалоговая панель имеет стиль WS_VISIBLE, то она сразу появляется на экране. В противном случае для ее отображения надо вызвать метод ShowWindow, а для убирания панели с экрана можно вызваит метод DestroyWindow(этот метод определен в классе CWnd, и его можно вызвать для объектов класса диалоговой панели). В примере эти дейтвия выполняются в обработчиках команд меню:
void CMainFrame::OnNomodal()
{
nodialog.ShowWindow( SW_SHOW );
}
void CMainFrame::OnNoshowdialog()
{
nodialog.DestroyWindow();
}
Для удаления объекта немодальной диалоговой панели можно переопределить виртуальный метод PostNcDestroy(этот метод первоначально определен в базовом классе CWnd). В нем можно вызвать оператор delete, передав ему в качестве параметра указатель на данный объект this. Удалять нужно те объекты, которые создавались при помощи оператора new (в примере это дейтвие выполнить нельзя, кстати, почему?).
В примере (файл dlg2.zip) расширено меню за счет добавления двух пунктов - "Немодальный диалог" и "Убрать модальный диалог", добавлены соответствующие обработчики событий.
Некоторые функции для работы с диалоговыми панелями.
CWnd* CWnd::GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
Функции по идентификатору элемента управления, заданному при создании элемента в редакторе ресурсов, возвращают указатель на оконный объект или дескриптор окна этого элемента.
void CDialog::GotoDlgCtrl( CWnd* pWndCtrl );
Переводит фокус на другой элемент в диалоге.
void CDialog::NextDlgCtrl( ) const;
Переводит фокус на следующий элемент управления. Порядок перехода может быть задан при создании диалога в редакторе ресурсов ( найдите, как это делается )
void CDialog::PrevDlgCtrl( ) const;
Переводит фокус на предыдущий элемент управления. Порядок перехода может быть задан при создании диалога в редакторе ресурсов ( найдите, как это делается )
Для того, чтобы узнать, какая кнопка действует "по умолчанию", а также изменить ее программно, можно воспользоваться функциями:
DWORD CDialog::GetDefID( );
void CDialog::SetDefID( UINT nID );
Функция GetDefID возвращает в младшем слове идентификатор кнопки по умолчанию. Старшее слово при этом содержит значение DC_HASDEFID.
Задания к работе.
Создать приложение Modal, которое выводит главное окно, содержащее меню с пунктами "Диалог", "About" и "Выход". При выборе пункта "Диалог" появляется модальная диалоговая панель, которая позволяет показать различные элементы Windows (кнопки с текстом и рисунками, статические элементы (текст и иконки),элемент редактирования, списки, check- кнопки и radio-кнопки). Показать управление этими элементами.
Все программы должны иметь нестандартные иконки.
Добавить в меню пункт для вывода немодального диалогового окна. придумать внешний вид и используемые элементы в диалоге.
Изменить диалог About.