Немодальный диалог
Для трех кнопок (TRI, PENT и STAR) установите стиль Owner draw, так как это будут не стандартные кнопки, а кнопки с изображениями, управляемые классом CBitmapButton. Для ползунков установите следующие стили: Orientation: Horizontal, TickMarks: True, AutoTicks: True, Point: Top/Left.
Для управления диалогом необходимо создать новый класс. Для этого можно воспользоваться контекстным меню, вызванным над формой диалога.
- Выберите в контекстном меню команду Add Class.
- В левом окне диалога Add Class раскройте дерево Visual C++, сделайте выбор MFC * MFC Class и нажмите кнопку Open.
- В окне мастера MFC Class Wizard задайте имя класса CPolyDlg, в качестве базового класса выберите CDialog. При этом станет доступным поле Dialog ID.
- В это поле введите или выберите из выпадающего списка идентификатор шаблона диалога IDD_POLYCOLOR и нажмите кнопку Finish.
Просмотрите объявление класса CPolyDlg, которое должно появиться в новом окне PolyDlg.h. Как видите, мастер сделал заготовку функции DoDataExchange для обмена данными с элементами управления на форме диалога. Самих функций обмена типа DDX_ еще нет, но мы их создадим немного позже.
Нестандартные элементы управления
Рассмотрим, как создаются элементы управления, имеющие индивидуальный нестандартный облик. Сравнительно новым подходом в технологии создания таких элементов является обработка подходящего сообщения не в классе родительского окна, а в классе, связанном с элементом управления диалога. Такая возможность появилась в MFC начиная с версии 4.0, и она носит название Message Reflection. Элементы управления Windows посылают уведомляющие сообщения своим родительским (parent) окнам. Например, многие элементы, в том числе и Edit controls, посылают сообщение WM_CTLCOLOR, позволяющее родительскому окну выбрать кисть для закраски фона элемента.
В версиях MFC (до 4.0), если какой-либо элемент должен выглядеть не так, как все, то эту его особенность обеспечивал класс родительского окна, обычно диалог. Теперь к старому механизму обработки уведомляющих сообщений от дочерних (child) элементов добавился новый, который позволяет произвести обработку уведомляющего сообщения в классе самого элемента. Уведомляющее сообщение как бы отражается (reflected) назад в класс дочернего окна элемента управления. Мы собираемся использовать нестандартные окна редактирования (Red, Green, Blue и Color), с тем чтобы они следили за изменением цвета, отражая текущий выбор как в числовом виде, так и в виде изменяющегося цвета фона своих окон. Эту задачу можно выполнить, создав класс (назовем его cclrEdit), производный от CEdit, и введя в него обработку отражаемого сообщения =WM CTLCOLOR.
Примечание
Обратите внимание на символ = перед идентификатором сообщения Windows. Он необходим, чтобы различить два сообщения с одним именем. Наличие символа = означает принадлежность сообщения к группе отражаемых (reflected) сообщений.
Применяя уже известный вам подход, создайте класс cclrEdit с базовым классом CEdit. В процессе определения атрибутов нового класса укажите существующие файлы (PolyDlg.h и PolyDlg.cpp) в качестве места для размещения кодов нового класса. Если возникнут окна диалогов с просьбой подтвердить необходимость погружения кодов в уже существующие файлы, то ответьте утвердительно. Введите изменения в файл PolyDlg.h, так чтобы он приобрел следующий вид:
#pragma once //===== Класс нестандартного окна редактирования class CClrEdit: public CEdit { DECLARE_DYNAMIC (CClrEdit) public: CClrEdit (); virtual – CClrEdit (); void ChangeColor (COLORREF clr); // Изменяем цвета protected: DECLARE_MESSAGE_MAP () private: COLORREF ra_clrText; // Цвет текста COLORREF ra_clrBk; // Цвет фона CBrush m_brBk; // Кисть для закраски фона }; //====== Класс для управления немодальным диалогом class CPolyDlg: public CDialog { friend class CClrEdit; DECLARE_DYNAMIC (CPolyDlg) public: enum (IDD = IDD_POLYCOLOR }; //====== Удобный для нас конструктор CPolyDlg (CTreeDoc* p); virtual – CPolyDlg (); //====== Отслеживание цвета void UpdateColor (); protected: virtual void DoDataExchange (CDataExchange* pDX); DECLARE_MESSAGE_MAP () private: CTreeDoc* m_pDoc; // Обратный указатель CBitmapButton m_cTri; // Кнопки с изображениями CBitmapButton m_cPent; CBitmapButton m_cStar; bool ra_bScroll; // Флаг использования ползунка }; };