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

Немодальный диалог

Для трех кнопок (TRI, PENT и STAR) установите стиль Owner draw, так как это будут не стандартные кнопки, а кнопки с изображениями, управляемые классом CBitmapButton. Для ползунков установите следующие стили: Orientation: Horizontal, TickMarks: True, AutoTicks: True, Point: Top/Left.

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

  1. Выберите в контекстном меню команду Add Class.
  2. В левом окне диалога Add Class раскройте дерево Visual C++, сделайте выбор MFC * MFC Class и нажмите кнопку Open.
  3. В окне мастера MFC Class Wizard задайте имя класса CPolyDlg, в качестве базового класса выберите CDialog. При этом станет доступным поле Dialog ID.
  4. В это поле введите или выберите из выпадающего списка идентификатор шаблона диалога 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; // Флаг использования ползунка };
};
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.