MFC: как сделать комбо-бокс в стиле Aero для рисования владельцем? - PullRequest
3 голосов
/ 15 марта 2012

Я унаследовал большое приложение MFC, которое содержит подкласс CComboBox, который переопределяет OnPaint. В настоящее время он рисует все вручную (с помощью линий и прямоугольников) и отображает поле со списком, которое выглядит явно в стиле Windows 98. Однако в остальном он отлично работает и предоставляет множество полезных пользовательских функций, на которые мы полагаемся, и перезапись всего элемента управления, вероятно, не вариант.

Я хотел бы модернизировать его так, чтобы OnPaint рисовал в стиле Aero, где это возможно (отступая к старому коду, когда современные темы недоступны). Я сделал это с некоторыми другими пользовательскими элементами управления, такими как кнопки, и он отлично работает для наших целей. Я знаю, что есть некоторые крошечные варианты поведения, которые не получатся правильными, например плавные выделения при наведении мыши, но это не имеет большого значения для этого приложения.

У меня есть доступ к CVisualStylesXP ckass, поэтому у меня уже есть инфраструктура, позволяющая довольно легко совершать такие звонки, как OpenThemeData, GetThemeColor или DrawThemeBackground (через LoadLibrary, поэтому мы не форсируем Vista как минимальная система). К сожалению, я не знаю правильную последовательность вызовов, чтобы получить красивое комбинированное окно с соответствующей темой рамкой и кнопкой раскрывающегося списка.

Кто-нибудь знает, что здесь делать?

Ответы [ 3 ]

0 голосов
/ 24 марта 2012

Я думаю, что лучше всего снимать без погружения в глубину xp тематики и различные системные метрики, взгляните на этот проект: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1

Проверьте OnPaint класса CAdvComboBox - естьполная реализация перерисовки элемента управления, включая проблемы, связанные с темой xp.

0 голосов
/ 14 апреля 2012

Не уверен, что это та же самая ситуация - но когда я столкнулся с этой проблемой (в моем случае с подклассами CButton), для ее решения потребовалось только изменить объявление элемента управления на указатель и создать элемент управления динамически.

Предположим, что ваш подклассный элемент управления называется CComboBoxExt.
Где ты был

CComboBoxExt m_cComboBoxExt;

Теперь у вас будет

CComboBoxExt* m_pcComboBoxExt; 

И в OnInitDialog окна, в котором находится элемент управления, вы создаете его, используя

m_pcComboBoxExt = new CComboBoxExt();  
m_pcComboBoxExt->Create(...)

Поскольку теперь это указатель, не забудьте вызвать DestroyWindow() и удалить указатель при завершении.

Это решило мою конкретную проблему - если ваш элемент управления объявлен таким же образом, попробуйте попробовать.

0 голосов
/ 15 марта 2012

Честно говоря, я не знаю, почему они изначально пытались переопределить OnPaint. Есть ли веская причина? Я думаю, что по крайней мере в 99% случаев вы просто захотите переопределить рисование элементов в ComboBox. Для этого вы можете переопределить DrawItem, MeasureItem и CompareItem в производном поле со списком, чтобы получить желаемую функциональность. В этом случае ОС будет правильно отображать не-пользовательский контент, специфичный для каждой ОС.

...