» Мальчиш-Кибальчиш и военная тайна : Берлога инженера - бесплатные программы - стереофото - справочные материалы - обои для рабочего стола


Мальчиш-Кибальчиш и военная тайна

Приспичило мне тут как-то на досуге написать приложение с поддержкой XP Visual Styles. И все бы хорошо, да понадобились в этом приложении нестандартные кнопки, у котрорых цвет надписей мог бы задаваться вручную. Надо заметить, обычные кнопки таких вольностей не позволяют, рисуют себя сами как хотят, то есть строго в одном цвете. Сразу оговорюсь, пишу я на чистом Win API, потому любителям Delphi и всяких Билдеров, использующим всякие навороченные компоненты, просьба не начинать со мной священных войн, ибо нелепо получится.

Сначала я ударился во все тяжкие и попытался реализовать все через ownerdraw buttons – так понравилось мне описания этого в MSDN, но на пути этом постигло меня жестокое разочарование. Забуксовал я на сообщениях от мыши. Нет, нажатие левой кнопки я ловил вполне уверенно, но вот наведение курсора на область кнопки никак красиво отследить не удавалось.

После долгого мрачного раздумья решил сделать просто и добротно – через суперклассинг. И всё бы хорошо – и кнопка рисуется красиво, и подсвечивается при наведении, да вот шрифт надписи на ней какой-то получился крупный, неправильный.

Немного отступая от темы, расскажу каково оно – работать с Themes and Visual Styles в XP.

В простейшем случае, для того, чтобы приложение имело красивый интерфейс, достаточно добавить в него ресурс типа RT_MANIFEST с номером 1, в котором должен находиться специальный XML файл, именуемый, как вы уже наверное догадались, манифестом. Да, еще в начало приложения необходимо добавить функцию InitCommonControls. Про линковку соответствующей библиотеки я говорить не буду, поскольку без этого все равно у вас ничего не скомпилируется. Теперь, если у нас в системе имеется comctl32.dll версии 6 и выше и включены темы XP, ваше приложение будет выглядеть гораздо симпатичнее.

Немного по-другому дело обстоит, ежели вы сами в своей программе обрабатываете сообщение WM_PAINT или WM_DRAWITEM, или, говоря иными словами, сами выполняете отрисовку окон или элементов управления. В таком случае необходимо использовать библиотеку UxTheme.lib с соответствующим заголовочным файлом uxtheme.h. Найти их можно в последней версии Platform SDK, скачать который можно совершенно бесплатно с сайта Microsoft (тут идет небольшая рекламная пауза с раздачей халявных баранок :) ). На этом лирическое отступление прошу считать оконченным.

Не вдаваясь особо в технические подробности, скажу, что функциям из этой библиотеки, необходимо передавать в том числе такие параметры как тип элемента управления, его состояние и тип возвращаемого параметра. Вот с последним и возникла некоторая загвоздка. Если для первых двух в MSDN указаны конкретные возможные константы, то для него не указано ничего. Попытки обратиться ко Всемирному Разуму результата не дали. Везде такие же растеряные вопросы из разряда «Что делать?» и «Как жить дальше?»

На любые мои попытки подсунуть функции получения описания шрифта для кнопки внятную константу, она забивала мне возвращаемую структуру жутким мусором. Что после этого происходило с выводом, лучше не спрашивайте. После впустую потраченных четырех часов, в течение которых я чуть ли не методом перебора пытался получить хоть что-то похожее на осмысленный результат, я пришел в невменяемое состояние и пошел пить зеленый чай.

После третьего чайника в голове начало немного проясняться и кровавая пелена стала потихоньку исчезать с моих глаз.

Набравшись чаем под завязку, я сел опять думать. И тут мне в голову пришла совершенно безумная мысль. Терять мне было нечего, поэтому я сразу ее воплотил в реальность. И реальность была весьма позитивной – ОНО ЗАРАБОТАЛО.

А вот теперь объясните мне, почему такая функция:

HRESULT GetThemeFont(
HTHEME hTheme,
HDC hdc,
int iPartId,
int iStateId,
int iPropId,
LOGFONT *pFont
);

Parameters

hTheme
[in] Handle to a window's specified theme data. Use OpenThemeData to create an HTHEME.
hdc
[in] Handle to a device context (HDC). This parameter may be set to NULL.
iPartId
[in] integer that specifies the part that contains the font property. See Parts and States.
iStateId
[in] integer that specifies the state of the part. See Parts and States.
iPropId
[in] integer that specifies the property to retrieve. See Property Types
pFont
[out] Pointer to a LOGFONT structure that receives the font property value.

выдает всегда мусор при любом значении iPropId, а спасает только функция

HRESULT GetThemeSysFont(
HTHEME hTheme,
int iFontID,
LOGFONT *plf
);

Что, если у кнопки нестандартный несистемный шрифт? Да хоть и системный, вы мне объясните, почему эта функция не работает? Или я не те книжки курил? Или в Microsoft вообще не книжки курят?

Сие, видимо, есть великая, скорее всего, военная тайна. Я, лишь случайно прикоснувшись к ее краешку, почувствовал леденящее дыхание чего-то неведомого, непостижимого и ужасного.

Что ж, буду пробовать и дальше. И да не повредится мой рассудок!

Примечание: Для тех, кто желает получше разобраться в вопросе, есть неплохая статья на RSDN.

Читайте также:
Intel Core i7, деревня Гадюкино и Мальчиш
Ссылки на каждый день
Про современный компьютер. Процессор





Комментарии закрыты.