Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Пользовательские контролы на Win32API


Автор: nitnat 4.8.2010, 20:49
Здравствуйте!
Уселся писать довольно сложное приложение на Win32API и решил сделать полностью уникальный графический интерфейс. Задумал совершенно уму не постижимые вещи, которые стандартными средствами винды не сделать, придется отрисовывать вручную, так что "создавать виндовые контролы и натягивать на них картинки" прошу не предлагать smile Сторонние библиотеки тоже не приветствую: это лишнее.
В общем, я так понял, собственный контрол можно создать, зарегистрировав его класс, создав окно и обрабатывая в его оконной процедуре события взаимодействия пользователя с ним и отрисовывать при получении WM_PAINT. Ну не грех ли не применять ООП в такой ситуации? Задумал я сделать класс, скажем, MyButton, там среди всего прочего метод Paint(void), в котором непосредственно отрисовка; этот метод надо вызывать в оконной процедуре по получению WM_PAINT. Объектов класса может быть сколько угодно, поэтому и оконные процедуры наверно удобнее лепить для каждого из них, т.е. тоже как член класса, но проблема состоит в том, что линкер ругается, если я подсовываю в структуру WNDCLASS non-static метод, а в static методе я не могу использовать this, а как тогда вызывать this->Paint()?
А теперь, собственно, вопрос: есть ли способ сделать так, как я хочу, и если нет, то как лучше сделать? smile
Заранее огромное спасибо.

Автор: jonie 4.8.2010, 20:52
есть. Например использовать можно связку SetWindowLong\GetWindowLong с параметром GWL_USERDATA
уверен, существуют и другие методы...

Автор: nitnat 4.8.2010, 21:35
Я не понимаю. Пожалуйста, объясните поподробнее, что вы предлагаете сделать. Спасибо.

Автор: jonie 4.8.2010, 21:37
nitnat, в общем тут пример http://www.gamedev.net/community/forums/topic.asp?topic_id=59171
и гугл по словам "static wnd proc this"

Автор: ASMatic 4.8.2010, 21:38
можно сделать все на одном окне и по координатам определять к какому контролу относиться данное сообщение....ИМХО

Автор: nitnat 4.8.2010, 21:52
Цитата(ASMatic @  4.8.2010,  21:38 Найти цитируемый пост)
можно сделать все на одном окне и по координатам определять к какому контролу относиться данное сообщение....ИМХО 

По-моему это вообще извращение. Так можно докатиться до свалки тяжелочитаемого кода, который я потом сам понимать с трудом буду. Я собираюсь свой проект развивать и там будет столько этих кнопок(и не только кнопок), что я попросту запутаюсь в этих многочисленных проверках по координатам.
Цитата(jonie @  4.8.2010,  21:37 Найти цитируемый пост)
и гугл по словам "static wnd proc this"

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

Автор: ASMatic 4.8.2010, 21:59
nitnat, 
кому как...
думаете виндовс по другому определяет?

пс. у моей(совмесной) программы интерфейс построен на таком принципе - хотите верте, хотите нет - все там читаемо и с помощью "двух кликов" добавляються новые контролы...
учитесь абстрагировать - будет код читабельней.
удачного написания!!

Автор: nitnat 4.8.2010, 23:23
Цитата(jonie @  4.8.2010,  21:37 Найти цитируемый пост)
nitnat, в общем тут пример http://www.gamedev.net/community/forums/to...?topic_id=59171

Огромное спасибо! Вроде вкурил, буду пробовать.
Еще хотел попросить совета: стоит ли для каждого "типа" контрола(кнопка, поле ввода, список) регить свой WNDCLASS, или тупо везде юзать виндовый STATIC ? И если стоит, то тогда что, у всех указывать одну и ту же "hidden" оконную процедуру? Спасибо.

Автор: Earnest 5.8.2010, 08:31
Цитата(nitnat @  5.8.2010,  00:23 Найти цитируемый пост)
 стоит ли для каждого "типа" контрола(кнопка, поле ввода, список) регить свой WNDCLASS, или тупо везде юзать виндовый STATIC 

Ты ведь в основном внешний вид поменять хочешь? А ведь внешний вид - это даже не половина функциональности, а гораздо меньше. Так что не занимайся фигней, а настраивай стандартные контролы, по крайней мере кнопки точно глупо самому писать. Есть ведь OWNERDRAW и CUSTOMDRAW, с внешним видом можно что угодно сделать. А с помощью перехвата других сообщений можно и другое поведение изменить. Так что для каждого контрола подумай сначала, какую функциональность он реализует, и не использовать ли в качестве основы один из стандартных контролов. А STATIC использовать глупо, он тупо даже клики на себя хреново обрабатывает - ну процедура такая у него стандартная.
Что касается метода связывания "зыза" с HWND я знаю 2 метода - первый тебе описал joinie (засунуть this в данные окна), второй - регистратор (т.е. при создании объекта-окна соответствие HWND->CBaseWnd* записывается в статический контейнер, откуда потом и достается при получении сообщений). 

Автор: Maks1509 5.8.2010, 13:36
Статик подходит для обработки нажатий мышки, для этого надо стиль поменять у него на SS_NOTIFY, после этого можно хоть полноценную свою кнопку сделать на его основе. Делаю большинство своих контролов на основе статика. Правда немного корректнее нахлобучивать на контролы свои данные через SetProp, ежели через SetWindowLong - этих свойств может быть несколько, а вот GWL_USERDATA всего одна. Вот так вот захочешь перезасабклассить сдуру окно и затрёшь GWL_USERDATA.

Автор: Earnest 5.8.2010, 16:22
Цитата(Maks1509 @  5.8.2010,  14:36 Найти цитируемый пост)
Статик подходит для обработки нажатий мышки, для этого надо стиль поменять у него на SS_NOTIFY, после этого можно хоть полноценную свою кнопку сделать на его основе

Я в курсе... Это совет типа: берем Мерс, сдираем краску, меняем двигатель на оный от мопеда и получаем классный Запорожец, hand-made. Ты можешь объяснить, зачем делать кнопку из статика, если есть Button? Можно еще таблицу на основе эдита сварганить.

Добавлено через 4 минуты и 56 секунд
Цитата(nitnat @  4.8.2010,  21:49 Найти цитируемый пост)
Уселся писать довольно сложное приложение на Win32API и решил сделать полностью уникальный графический интерфейс.

Смотри, как бы твое приложение одним интерфейсом и не ограничилось. А то перегоришь на самопальных кнопках и получишь кучу никому не нужного кода. Интерфейс (в смысле форму кнопок, а не логику взаимодействия) - это последнее, что нужно шлифовать. Сначала добейся того, чтобы твое приложение работало и делало что-то полезное. А кнопки можно и потом раскрасить, если желание и энтузиазм останутся... Или поумнеешь, пока над функционалом работать будешь, и возьмешь какое-нибудь готовое решение...
 smile 

Автор: Maks1509 5.8.2010, 17:05
Цитата(Earnest @ 5.8.2010,  16:22)
Я в курсе... Это совет типа: берем Мерс, сдираем краску, меняем двигатель на оный от мопеда и получаем классный Запорожец, hand-made. Ты можешь объяснить, зачем делать кнопку из статика, если есть Button? Можно еще таблицу на основе эдита сварганить.

Могу объяснить, мне нужен был контрол гиперссылки, но с некоторыми наворотами, а это практически кнопка полноценная (у меня шлёт родительскому окну STN_CLICKED - аналог BN_CLICKED). Так что путём нехитрых махинаций ради интереса и тренировки отрисовал потом целую кнопку, поддерживающую темы оформления на основе наработок со статиком. Ну и со статиком проще, достаточно WM_PAINT обработать, если не ошибаюсь, с кнопкой пришлось повозиться, не хватало WM_UPDATEUISTATE, иначе вся красота пропадала при потере фокуса и рисовалось всё стандартно, я пока узнал об этом сообщении уйму времени потратил на решение проблемы с отрисовкой стандартных кнопок. Но это опять же дело вкуса, кому как удобнее.

Автор: nitnat 6.8.2010, 23:22
Цитата(Earnest @  5.8.2010,  08:31 Найти цитируемый пост)
Ты ведь в основном внешний вид поменять хочешь?

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

Автор: Amp 7.8.2010, 00:24
Цитата(nitnat @  6.8.2010,  23:22 Найти цитируемый пост)
Я хочу сделать то, чего ни один из вас в Windows-приложениях еще не видел. 

Ой ли? Заинтриговали smile

Автор: Earnest 9.8.2010, 10:50
Цитата(nitnat @  7.8.2010,  00:22 Найти цитируемый пост)
Я хочу сделать то, чего ни один из вас в Windows-приложениях еще не видел. 

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

Автор: nitnat 9.8.2010, 18:16
Цитата(Earnest @  9.8.2010,  10:50 Найти цитируемый пост)
Какая самонадеянность. И задаваемые вопросы прямо-таки гарантируют выполнение этих заяв. 
Не знаешь простых вещей, а собираешься сваять нечто сногсшибательное.
Не смеши людей, парень.  
Но даже если так, то самый офигенно красивый и экзотический интерфейс никому не нужен, если программа ничего полезного не делает.
И функционал гораздо важнее. А насчет "перегоришь" на кнопочках - ну не веришь, сам убедишься. Ничего страшного, конечно, "сын ошибок трудных" никому не повредит...

Не стоит издеваться. Если я и мало работал с API винды, это вовсе не значит, что я ничего стоящего не напишу. Времени у меня полно и я никуда не спешу: успею и опыта понабраться и дописать то, что начал. А еще, с чего вы взяли, что в моем приложении не будет ничего кроме красивых кнопочек? Просто я считаю, что сначала надо убедиться, что хватит сил на оболочку, а потом строить каркас, тем более если программа изначально задумывалась как нечто с невероятным интерфейсом, а то так можно дописаться до того, что "красивые кнопочки" уже будет невозможно воткнуть. Еще один пункт: я пишу приложения не сугубо для опытных программистов и прошаренных айтишников, которые дофига рады работать в одной консольке, а в т.ч.(выделяю, чтобы не последовало глупых инсинуаций) и для гламурных девочек, которых подкупают именно "красивые кнопочки".

Автор: Earnest 9.8.2010, 20:04
Никто и не думал издеваться, бог с тобой. Просто советы старших товарищей.
Цитата(nitnat @  9.8.2010,  19:16 Найти цитируемый пост)
а то так можно дописаться до того, что "красивые кнопочки" уже будет невозможно воткнуть.

Во-во. Т.е. ты хочешь сказать, что функциональная логика твоего программы и интерфейс будут так сильно повязаны. Тогда точно ничего не напишешь. Проектируй программу так, чтобы любую "кнопочку" можно было моментально выдернуть и заменить на другую крюкозябру, а функционал этого даже не заметил.
Ладно, не буду я с тобой спорить, бесполезно... Набивай свои шишки.
 smile 
Когда мне было лет 14 (оч. давно, увы), я как-то заявила папе (с утомленным видом), что я все знаю об этой жизни. Он спорить не стал, но смеялся долго.

Автор: v987 11.8.2010, 12:39
Надеюсь, что еще актуально:

1) http://www.gamedev.net/community/forums/topic.asp?topic_id=59171
2) http://msdn.microsoft.com/en-us/library/ff708696.aspx

В п.2 тоже все решается через GWL_USERDATA, но ИМХО он интересн тем, что там все сделано в стиле COM и без ATL/WTL. С одной стороны, все можно объяснить тем, что это пример и он не требует студии с ATL. С другой стороны, я бы сказал, что выглядит он "альтернативно" ATL/WTL smile)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)