| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Пользовательские контролы на Win32API |
| Автор: nitnat 4.8.2010, 20:49 |
| Здравствуйте! Уселся писать довольно сложное приложение на Win32API и решил сделать полностью уникальный графический интерфейс. Задумал совершенно уму не постижимые вещи, которые стандартными средствами винды не сделать, придется отрисовывать вручную, так что "создавать виндовые контролы и натягивать на них картинки" прошу не предлагать В общем, я так понял, собственный контрол можно создать, зарегистрировав его класс, создав окно и обрабатывая в его оконной процедуре события взаимодействия пользователя с ним и отрисовывать при получении WM_PAINT. Ну не грех ли не применять ООП в такой ситуации? Задумал я сделать класс, скажем, MyButton, там среди всего прочего метод Paint(void), в котором непосредственно отрисовка; этот метод надо вызывать в оконной процедуре по получению WM_PAINT. Объектов класса может быть сколько угодно, поэтому и оконные процедуры наверно удобнее лепить для каждого из них, т.е. тоже как член класса, но проблема состоит в том, что линкер ругается, если я подсовываю в структуру WNDCLASS non-static метод, а в static методе я не могу использовать this, а как тогда вызывать this->Paint()? А теперь, собственно, вопрос: есть ли способ сделать так, как я хочу, и если нет, то как лучше сделать? Заранее огромное спасибо. |
| Автор: 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 |
| можно сделать все на одном окне и по координатам определять к какому контролу относиться данное сообщение....ИМХО |
| Автор: ASMatic 4.8.2010, 21:59 |
| nitnat, кому как... думаете виндовс по другому определяет? пс. у моей(совмесной) программы интерфейс построен на таком принципе - хотите верте, хотите нет - все там читаемо и с помощью "двух кликов" добавляються новые контролы... учитесь абстрагировать - будет код читабельней. удачного написания!! |
| Автор: nitnat 4.8.2010, 23:23 | ||
Огромное спасибо! Вроде вкурил, буду пробовать. Еще хотел попросить совета: стоит ли для каждого "типа" контрола(кнопка, поле ввода, список) регить свой WNDCLASS, или тупо везде юзать виндовый STATIC ? И если стоит, то тогда что, у всех указывать одну и ту же "hidden" оконную процедуру? Спасибо. |
| Автор: Earnest 5.8.2010, 08:31 | ||
Ты ведь в основном внешний вид поменять хочешь? А ведь внешний вид - это даже не половина функциональности, а гораздо меньше. Так что не занимайся фигней, а настраивай стандартные контролы, по крайней мере кнопки точно глупо самому писать. Есть ведь 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 | ||||
Я в курсе... Это совет типа: берем Мерс, сдираем краску, меняем двигатель на оный от мопеда и получаем классный Запорожец, hand-made. Ты можешь объяснить, зачем делать кнопку из статика, если есть Button? Можно еще таблицу на основе эдита сварганить. Добавлено через 4 минуты и 56 секунд
Смотри, как бы твое приложение одним интерфейсом и не ограничилось. А то перегоришь на самопальных кнопках и получишь кучу никому не нужного кода. Интерфейс (в смысле форму кнопок, а не логику взаимодействия) - это последнее, что нужно шлифовать. Сначала добейся того, чтобы твое приложение работало и делало что-то полезное. А кнопки можно и потом раскрасить, если желание и энтузиазм останутся... Или поумнеешь, пока над функционалом работать будешь, и возьмешь какое-нибудь готовое решение... |
| Автор: Maks1509 5.8.2010, 17:05 | ||
Могу объяснить, мне нужен был контрол гиперссылки, но с некоторыми наворотами, а это практически кнопка полноценная (у меня шлёт родительскому окну STN_CLICKED - аналог BN_CLICKED). Так что путём нехитрых махинаций ради интереса и тренировки отрисовал потом целую кнопку, поддерживающую темы оформления на основе наработок со статиком. Ну и со статиком проще, достаточно WM_PAINT обработать, если не ошибаюсь, с кнопкой пришлось повозиться, не хватало WM_UPDATEUISTATE, иначе вся красота пропадала при потере фокуса и рисовалось всё стандартно, я пока узнал об этом сообщении уйму времени потратил на решение проблемы с отрисовкой стандартных кнопок. Но это опять же дело вкуса, кому как удобнее. |
| Автор: nitnat 6.8.2010, 23:22 |
Перечитайте внимательно первый пост. Я хочу сделать то, чего ни один из вас в Windows-приложениях еще не видел. |
| Автор: Amp 7.8.2010, 00:24 | ||
Ой ли? Заинтриговали |
| Автор: Earnest 9.8.2010, 10:50 | ||
Какая самонадеянность. И задаваемые вопросы прямо-таки гарантируют выполнение этих заяв. Не знаешь простых вещей, а собираешься сваять нечто сногсшибательное. Не смеши людей, парень. Но даже если так, то самый офигенно красивый и экзотический интерфейс никому не нужен, если программа ничего полезного не делает. И функционал гораздо важнее. А насчет "перегоришь" на кнопочках - ну не веришь, сам убедишься. Ничего страшного, конечно, "сын ошибок трудных" никому не повредит... |
| Автор: nitnat 9.8.2010, 18:16 | ||
Не стоит издеваться. Если я и мало работал с API винды, это вовсе не значит, что я ничего стоящего не напишу. Времени у меня полно и я никуда не спешу: успею и опыта понабраться и дописать то, что начал. А еще, с чего вы взяли, что в моем приложении не будет ничего кроме красивых кнопочек? Просто я считаю, что сначала надо убедиться, что хватит сил на оболочку, а потом строить каркас, тем более если программа изначально задумывалась как нечто с невероятным интерфейсом, а то так можно дописаться до того, что "красивые кнопочки" уже будет невозможно воткнуть. Еще один пункт: я пишу приложения не сугубо для опытных программистов и прошаренных айтишников, которые дофига рады работать в одной консольке, а в т.ч.(выделяю, чтобы не последовало глупых инсинуаций) и для гламурных девочек, которых подкупают именно "красивые кнопочки". |
| Автор: Earnest 9.8.2010, 20:04 | ||
Никто и не думал издеваться, бог с тобой. Просто советы старших товарищей.
Во-во. Т.е. ты хочешь сказать, что функциональная логика твоего программы и интерфейс будут так сильно повязаны. Тогда точно ничего не напишешь. Проектируй программу так, чтобы любую "кнопочку" можно было моментально выдернуть и заменить на другую крюкозябру, а функционал этого даже не заметил. Ладно, не буду я с тобой спорить, бесполезно... Набивай свои шишки. Когда мне было лет 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 |