| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Принцип отрисовки окна (контролы - изображения) |
| Автор: ZC1989 28.4.2010, 17:33 | ||
| Ребят, помогите с теорией, пожалуйста. Сама программа уже написана и работает, но она сделана на DialogBox, мне во первых не хотелось бы переписывать все окна вручную, а по возможности сделать то же самое на уже имеющейся платформе. Для примера создал болванку и пробую в ней отрисовывать теже контролы, но столкнулся с глюкаму уже в самом начале( вопрос первый: объясните в теории как правильно замещать и перерисовывать элементы окна что бы небыло глюков, тормозов и зависаний? понятно что фон диалога правильнее всего отрисовывать по WM_PAINT, а вот скажем кнопка, у неё есть 2 изображения (первое, когда она не активна, второе когда она нажата / на неё наведён курсор). такую кнопку надо отрисовывать то же по WM_PAINT и по действию над ней? вопрос второй: залил фон диалога изображением, но если перетаскивать окно так что бы оно попало на пуск, то на нём остаются куски картинки, типа ошибка отрисовки. и окно стало подёргиваться при перетаскивании, что можно с этим сделать? код:
вопрос третий: кнопка как видно из кода не перерисовывается, и получился то же странный эффект, если как я выше описал окно перетащить на пуск. то эта кнопка IDC_INDEXPAGE на время пропадает с формы... с чём я ошибся? |
| Автор: Emura 28.4.2010, 22:17 | ||||||||||
однозначно WM_PAINT.
или
или
на нём - это на чем? скрин показывай. |
| Автор: GremlinProg 29.4.2010, 09:36 | ||
для стандартных компонент принцип зарисовки такой: 1. каждый компонент типа static, button, listbox, listview и т.п. имеют свои собственные процедуры окна 2. в каждой из этих процедур перехватывается WM_PAINT 3. если у компонента установлен спец. стиль, типа OWNERDRAW, то прежде, чем WM_PAINT будет обработано, родительскому окну будет послано спец. уведомление, обычно это WM_DRAWITEM (или NM_CUSTOMDRAW, инкапсулированный в WM_NOTIFY) 4. с этим уведомлением будет послана любая служебная информация о том: что рисовать, где рисовать и какое состояние рисовать т.е. WM_PAINT - всему голова, от него все и идет, просто иногда этот WM_PAINT может быть передан на доработку, через другое сообщение, чтобы извне можно было внести в облик компонента любые изменения в зависимости от версии библиотек стандартных компонент, могут меняться: флаги, сообщения и служебная информация, но принцип останется тот же |
| Автор: GremlinProg 29.4.2010, 10:04 |
| а помимо ручной отрисовки, некоторые компоненты могут сами рисовать простые изображения, для этого, им достаточно послать в любое время соответствующие сообщения, например: кнопке - BM_SETIMAGE, BCM_SETIMAGELIST; статику - STM_SETICON, STM_SETIMAGE |
| Автор: ZC1989 29.4.2010, 12:25 |
| GremlinProg, в смысле "пытаться чтото нарисовать поверх диалога"? Тоесть я неправильно рисую фон диалога? вот примеры того как и что работает: 1. Окно только открыто, если его перетаскивать в рамках рабочего стола, то всё нормально. http://www.dici-group.ru/__cpp/1/normal.JPG 2. я опустил окно так, что бы оно зашло за пуск и поднял обратно, на пуске остались куски картинки. http://www.dici-group.ru/__cpp/1/bad.JPG 3. исходник http://www.dici-group.ru/__cpp/1/ase_style.zip кстати, на счёт того что окно лагает когда его переместить на пуск и обратно. Такое происходит когда окно создано как щас, когда я создал окно руками. то такого уже небыло...что это может быть? |
| Автор: GremlinProg 29.4.2010, 12:37 | ||||
уже неважно, из картинок все понятно:
т.е., у тебя hwndStatic равен NULL, поэтому, GetDC возвращает экранный HDC, а он не привязан к твоему окну, т.е. он не будет перерисован в тех местах, откуда твое окно было сдвинуто исправляй во первых IDDlgItem, который должен быть ассоциирован с конкретным компонентом на диалоге во вторых - тот же GetWindowRect заменяй на GetClientRect ( это ошибка связана с первой ошибкой ) ну и в третьих, как увидишь результат, используй все же WM_DRAWITEM для такого рисования статика Добавлено через 6 минут и 56 секунд о, кстати, IDD_ADMIN - идентификатор самого диалога чтоли? диалог - это не статик, дескриптор диалога искать не надо через GetDlgItem если я правильно читаю мысли, то убирай из Paint_bg второй параметр и hwndStatic, а hwnd - используй вместо hwndStatic Добавлено через 10 минут и 20 секунд
|
| Автор: ZC1989 29.4.2010, 12:49 | ||
GremlinProg, так, я переделал функцию отрисовки
теперь на пуске ничего не остаётся, но почему то всё равно есть лаг: если схватить окно за середину и поочереди перетащить во все углы экрана, так что бы прога скрывалась за пределами экрана, то окно перестаёт прорисовываться. |
| Автор: GremlinProg 29.4.2010, 12:54 | ||||
тогда останется только правильно использовать Begin(End)Paint:
Добавлено через 3 минуты и 1 секунду угу
http://www.google.ru/search?q=gdi+leaks Добавлено через 5 минут и 45 секунд http://www.google.ru/search?q=gdi+leaks+task+manager |
| Автор: ZC1989 29.4.2010, 13:09 | ||
| ерунда какая то, вот изменил функцию как ты показал, глюк тот же, окно перестаёт прорисовываться.... и на счёт WM_DRAWITEM пытаюсь отрисовать кнопку
это правильно? |
| Автор: GremlinProg 29.4.2010, 13:18 |
это не зависит от рисования, gdi-leaks - утечки GDI-ресурсов, я же дал ссылки как их искать, утечки - значит где-то распределил GDI-ресурс, а после использования не освободил, ищи эти места и освобождай как полагается мы же уже выяснили, что компоненты у тебя ни какие не рисуются, т.е. WM_DRAWITEM не пригодился, последний вид Paint_bg вполне работоспособен, здесь уже можно не копать |
| Автор: ZC1989 29.4.2010, 13:27 |
| GremlinProg, О! ты прав)) спасибо) я забыл очищать битман, загнал LoadBitmap и DeleteObject в функцию и лагать перестало)) только постой, почему WM_DRAWITEM не пригодился? я добавил кнопку которую то же перерисовываю, разве её не лучше как раз здесь и перерисовывать? 0.о Добавлено через 5 минут и 30 секунд и ещё вопрос в догонку: в WM_DRAWITEM у меня получается изменение вида кнопки только при нажатии, а можно ли тут отсладить находится ли курсор над кнопкой программным способом? не высчитывая координат мышки и расчётов? а то это кажется не больно рационально( |
| Автор: GremlinProg 29.4.2010, 14:54 | ||
| а, кнопку, не заметил... ну да, кнопку можно, только надо сначала ей включить стиль BS_OWNERDRAW
это уже было в соседней теме: http://forum.vingrad.ru/forum/topic-298498/kw-отрисовка-кнопки-ownerdraw.html |
| Автор: ZC1989 30.4.2010, 16:06 |
| опять столкнулся с проблемой: хотел сделать static с прозрачностью и белым цветом шрифта,но почему то неполучается задать никаких параметров. пробовал отлавливать WM_COLORSTATIC, но оно вобще не приходит( |
| Автор: ZC1989 3.5.2010, 18:26 |
| ерунда какая то у меня в программе получилась... всё что отрисовываю (фон, кнопки, статики) всё нормально, но при обловлении окна (при скрытии и появлении контролов) они словно мерцают тоесть появляется сначала серый фон под ним, а потом уже перерисовывается...и если сдругим каким нибудь окном наехать на моё, а потом брать, оно то же не своевременно обновляется (появляется серый фон) что может быть такое? |
| Автор: GremlinProg 4.5.2010, 09:02 | ||||||
мы много раз уже обсуждали эту тему: 1. заходишь в поиск: http://forum.vingrad.ru/act-Search/f-96.html 2. пишешь "мерцание" 3. нажимаешь "найти" |