Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

 DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_Y | DLSZ_MOVE_X)

END_DLGRESIZE_MAP

Теперь поговорим о контролах, объединённых в группу.

ПРЕДУПРЕЖДЕНИЕ

Реализация групп в WTL подразумевает, что все контролы в группе должны располагаться рядом друг с другом по горизонтали или по вертикали. Флаги, которые вы задаёте для контролов в группе, должны относиться только к одному направлению (или X, или Y), но не к обоим сразу. Несоблюдение этих условий приведёт к странным эффектам. Кроме того, напомню ещё раз, что группы не могут быть вложенными.

Группы обрабатываются следующим образом. Сначала вычисляются координаты огибающего прямоугольника группы, то есть минимального прямоугольника, содержащего все контролы в ней. Далее размеры этого прямоугольника увеличиваются на dx и dy соответственно (dx и dy имеют то же значение, что и в обсуждении выше). После этого к каждому контролу в группе применяются следующие правила:

• DLSZ_MOVE_X: контрол сдвигается вдоль оси X пропорционально изменению ширины группы (то есть её огибающего прямоугольника).

• DLSZ_MOVE_Y: контрол сдвигается вдоль оси Y пропорционально изменению высоты группы.

• DLSZ_SIZE_X: действует аналогично DLSZ_MOVE_X, но ширина контрола также изменяется пропорционально изменению ширины группы.

• DLSZ_SIZE_Y: действует аналогично DLSZ_MOVE_Y, но высота контрола также изменяется пропорционально изменению высоты группы.

Проиллюстрирую сказанное простым примером. Допустим, у нас есть диалог с тремя расположенными в ряд кнопками. Если написать для него карту масштабирования вида:

BEGIN_DLGRESIZE_MAP(CMyDialog)

 BEGIN_DLGRESIZE_GROUP

DLGRESIZE_CONTROL(IDC_BUTTON1, DLSZ_SIZE_X)

DLGRESIZE_CONTROL(IDC_BUTTON2, DLSZ_SIZE_X)

DLGRESIZE_CONTROL(IDC_BUTTON3, DLSZ_SIZE_X)

 END_DLGRESIZE_GROUP

END_DLGRESIZE_MAP

то этот диалог будет масштабироваться следующим образом:

Рисунок 3. Масштабирование с использованием групп

Как это всё работает

Мы не будем надолго задерживаться на внутренней реализации класса CDialogResize<>, так как там нет почти ничего интересного. Когда вы вызываете функцию DlgResize_Init, начальные положения всех контролов в диалоге запоминаются во внутренних структурах WTL. Функция DlgResize_UpdateLayout использует новые размеры диалога и сохранённые ранее координаты контролов, чтобы назначить им новое положение в соответствии с заданными флагами. Что касается карты масштабирования, она просто превращается в статический массив структур _AtlDlgResizeMap, для доступа к которому используется функция GetDlgResizeMap. Структура _AtlDlgResizeMap хранит заданные вами в карте значения:

struct _AtlDlgResizeMap {

 int m_nCtlID;

 DWORD m_dwResizeFlags;

};

Хочу отметить несколько особенностей реализации класса CDialogResize<>, которые можно использовать в своих целях.

1. Элемент может встречаться в карте масштабирования более одного раза.

2. Элемент, не включённый в группу, двигается относительно его текущего положения.

3. Элемент, включённый в группу, масштабируется с учётом его начального положения (но без учёта его текущей позиции).

Таким образом мы можем, к примеру, отмасштабировать элемент по горизонтали, включив его в группу, а затем отдельно увеличить его высоту. Пример диалога с тремя кнопками, который мы рассмотрели выше, имел один недостаток: при увеличении высоты диалога кнопки не растягивались по вертикали. Теперь мы знаем, как решить эту проблему:

BEGIN_DLGRESIZE_MAP(CMyDialog)

 BEGIN_DLGRESIZE_GROUP

DLGRESIZE_CONTROL(IDC_BUTTON1, DLSZ_SIZE_X)

DLGRESIZE_CONTROL(IDC_BUTTON2, DLSZ_SIZE_X)

DLGRESIZE_CONTROL(IDC_BUTTON3, DLSZ_SIZE_X)

 END_DLGRESIZE_GROUP

 DLGRESIZE_CONTROL(IDC_BUTTON1, DLSZ_SIZE_Y)

 DLGRESIZE_CONTROL(IDC_BUTTON2, DLSZ_SIZE_Y)

 DLGRESIZE_CONTROL(IDC_BUTTON3, DLSZ_SIZE_Y)

END_DLGRESIZE_MAP

Кроме этого, можно включить элемент в несколько групп. Хотя на его местоположение повлияет только последняя группа, этот приём позволит сложным образом влиять на другие контролы. Но не стоит забывать о чувстве меры. Такие приёмы делают вашу программу более запутанной и более медлительной. Нетривиальное масштабирование контролов в диалоге лучше реализовать вручную, а не заниматься неочевидными фокусами с CDialogResize<>.

  • Читать дальше
  • 1
  • ...
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: