| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Опять окна. |
| Автор: ASMatic 31.8.2010, 02:46 |
| Есть окно одной программы. Решил его перерисовать на свое окно. WM_PRINT и его собратья пошли лесом, т.к. много процессора мне пожирает на таймере. Оформил в то приложение свою длл, перехватил BitBlt все подготовил - очаровательно все рисуется) Но когда я отсовываю окно за видимую область скрина WM_PAINT перестали приходить. Иследования подбивают на страшную мысль - это все сама винда контролирует кого рисовать а кого нет. По секрету скажу думал что это DefWindowProc() делает... +WM_PAINT в той прожке как я заметил приходит(врроде) по таймеру, т.к. там висит таймер примерно в 0.5сек и шлет WM_USER+ххх(сам себе видимо)...но когда я его засовываю за скрин - WM_PAINT который слался раньше два раза в секунду - исчезает.. Отсюда и появилась мысль что окно само за себя думает, когда рисоваться а когда нет... Перехватил WM_CAPTURECHANGED, WM_KILLFOCUS, WM_ACTIVATE, WM_ACTIVATEAPP, WM_NCACTIVATE, WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE и вернул типа все я сам обработал(по мсдн). Но дальше все плохо - может я чего не учел? Может мессагу какую надо послать...(пробовал WM_DISPLAYCHANGE перед и после SetWindowPos( out_of_screen ) - не помогло.... сэнкс! Добавлено через 10 минут и 28 секунд добавлю еще то что когда окно спрятать не полностью, т.е. один пиксель оставить на дисплее - перерисовывает практически все, не считая некоторых мелочей(нажатую кнопку, например не перерисовывает) +вся графика нарисована в одном окне, т.е. организованы свои контролы. |
| Автор: Earnest 31.8.2010, 06:42 |
| Экспериментальный зуд и энтузиазм налицо, но почему бы книжку не почитать-то? Все верно, WM_PAINT посылает окну система, если есть невалидная (нуждающаяся в перерисовке) область окна (на экране, конечно) и если ей (системе) больше делать нечего. Т.е. сообщение низкоприоритетное, ниже приоритетом только таймер. Что перерисовывать - это уже решает оконная функция, ей ведь сообщают невалидный регион, а использовать его или чихать и рисовать все - ее дело. Но, конечно, реально обновится только то, что не закрыто регионом отсечения. Вот, нарпимер, кнопка может быть закрыта, если у окна стоит стиль ClipChildren. И вообще, каждое окно получает WM_PAINT отдельно (т.е. родительское окно и его контролы). Так что для твоей задачи - таки WM_PRINT. |
| Автор: ASMatic 31.8.2010, 07:27 | ||
каким образом можно узнать этот регион,а то найти его не смог(правда особо и не искал))? По поводу того что система посылает WM_PAINT знаю) Теперь объясни мне пожалуйста( если не трудно, естественно): Почему когда окно почти полностью находиться за пределами экрана, обработчик WM_PAINT игнорирует что ему там сказала система и на главную DC копирует ПОЧТИ все, не считая некоторых мелочей. На картинке (не постеснялся_выложил) Видно снизу окно с которого я перемещаю изображение на свое тестовое. В Spy++ видны мессаги, т.е. таймер с айди 19 отвечает за перерисовку курсора в едитах (едиты самописные, не виндозные) В данном случае он не перерисовал, т.к. смысла не было (где то проверка не сошлась) НО когда я снизу торчащее окно перекрою чем небудь - однократно приходит и WM_PAINT. Как я понимаю ситуацию - программа сама определяет что она вне окна и перерисовывать не хочет. Только КАК ОНА ЭТО ВИДИТ??? если
Добавлено через 5 минут *в данный момент был выделен эдит со значением 685 - должен был изменить фон на коричневый... Меняет когда перекрыть чем то и забрать, т.е. винда увидела кусок не перерисованого окна и послала мессагу. Но обычно (когда окно видно полностью) WM_PAINT приходит по таймеру, помимо виндозной "провокации")) |
| Автор: artsb 31.8.2010, 10:38 |
| ASMatic, имхо, для вас самый лучший вариант: создать виртуальный экран; переместить туда форму; и спокойненько получать скрины как и раньше. ЗЫ виртуальных скринов я не создавал, поэтому помочь не смогу. |
| Автор: artsb 31.8.2010, 10:56 |
| Пара ссылок: http://www.fengyuan.com/article/wmprint.html http://www.codeproject.com/KB/system/VirtualDesktop.aspx http://stackoverflow.com/questions/1149978/how-to-create-a-new-desktop-c http://www.computerra.ru/terralab/softerra/406940/ |
| Автор: ASMatic 31.8.2010, 16:14 | ||||||||
Как понял ты о "загадочной" (для мня) структуре, о которой мне всю жизнь не было желания почитать зачем она)) Сейчас перехвачу еще BeginPaint и попробую заставить гада рисовать что я хочу) Ну да, еще бы) - утром уже после ночи немного выразился не корректно. Имелось ввиду DC самого окна, не служебные созданые приложением CreateCompatibleDC и т.п. которых приложение во сремя инициализации создает, их много на самом деле.. у меня не отсекаеться)
думаю что и сужать можно, т.к. StretchBlt все нормальненько сужает( уменя) и растягивать, думаю не запарилось бы) Ну это знаю, не первый день за "рулем)
Во первых этот месадж не все окна обрабатывают! По крайней мере это окно не хотело рисовать + гдето вычитал(вродже мсдн) что не все контролы в DefWindowProc имеют такой функционал. Слал PrintWindow по таймеру - бред! Боком пока не вылезло - ща надеюсь paitnctruct подправлю и будет норм...И что самое главное - я не буду говорить - перерисуйся, оно само когда ему надо будет переисовываться - что есть ни чем иным как оптимальным решением...
это было первой мыслю когда понял что задесктопные окна не прорисовую себя, но это - извращение! ИМХО! но полюбому спасибо!! ссылки почитаю!!! итог - сейчас валю перхватывать BeginPaint и если всетаки я прав - будет очаровательно красивое решение по перерисовке окна. пока спасибо, тестану - отпишусь! |
| Автор: ASMatic 31.8.2010, 16:51 |
| итог утром оказался не верным) - вовремя понял что это не оно, т.к. мне вообще WM_PAINT по таймеру перестет приходить. В ф-и обработки одного из таймеров есть зарыта проверка на десктопе ли мы! Её определить пока не получаеться(( |
| Автор: ASMatic 31.8.2010, 19:50 |
| Итак WM_WINDOWPOSCHANGING - приходит окну когда я сделал SetWindowPos(),в структуре подменили x=0,y=0, вызвали орижинал процедуру... Все оно бы ничего, но как оказалось за перемещение окна отвечает само окно. Т.е. я установил 0, 0 и окно быстренько переместилось на нулевые координаты. Вопрос, как окно само себя перемещает? Т.е. есть координаты где оно в данные момент находиться, вм_паинт - прорисовывает, тут пришел пос_чендж и окно почему то начало рисовать себя в другом месте. Но в PAINTSTRUCT координаты задаються относительно начала клиентской области самого окна, а не десктопа - как тогда перерисовка происходит? *просветлите мою голову в ГУИ, плз... |
| Автор: Earnest 1.9.2010, 06:36 | ||
Мне нравится это "почему-то". Ты же сам поменял координаты в WM_WINDOWPOSCHANGING! Собственно, для этого примерно это сообщение и посылается - ДО перемещения, сообщая куда собралось перемещаться, и в этот момент еще можно что-то изменить. А WM_WINDOWPOSCHANGED уже приходит после свершившегося перемещения. За координаты отвечает DC - в нем установлена система координат, которая "знает", что 0, 0 - это не "совсэм" 0, а левый верхний угол клиента. Твою бы энергию да в мирных целях... Все это написано в MSDN, ну почему бы не почитать-то. |
| Автор: ASMatic 1.9.2010, 14:57 |
только в мирных единственное что там могу читать - описания апи и структур, т.к. с остальным зачастую поиски заканчиваються неудачами) Да и не думаю что на мсдн будуть расписывать свои внутренности.) Вчера полез в исходники ReactOS, посмотрел что там - оказалось что WM_WINDOWPOSCHANGING парктически ничего не делает..Несколько проверкок и все... Но вот WM_WINDOWPOSCHANGED все уже и делает. И как "быстрым взглядом" посмотрел - в конечном итоге посылаеться WM_MOVE а та уже все перемещает....Но вот я сам обрабатываю WM_MOVE, т.е. ретурн - но окно всеравно перемещаеться, видимо в р0 послали какой-нить "месадж" и окно переместилось уже там.... - громоздкая функа по обработке WM_MOVE, поэтому не полностью разобрался... Решено было разобраться с таймерами, т.е. почему 19-й таймер(WM_PAINT сендает) ориентируться что окно не надо перерисовывать....Покаместь сижу в иде и виндбг с надеждой что всетаки пойму где это происходит(проверочка). По дороге нашел еще мессагу, которая может влиять на состояние активный или нет WM_IME_SETCONTEXT, надо её тоже в обработку взять. Может есть еще какие мессаги о которых я не догадываюсь и они могут влиять на активный\не активный и положение окна? |
| Автор: artsb 1.9.2010, 15:31 |
| ASMatic, вот в http://forum.vingrad.ru/forum/topic-269227/unread-1/hl/%25D1%2581%25D0%25BA%25D1%2580%25D0%25B8%25D0%25BD%25D1%2588%25D0%25BE%25D1%2582/index.html, совместными усилиями Данкинг и Keeper89 написан пример. Надеюсь поможет ;) Добавлено через 54 секунды Правда он на Делфях. Но думаю, разберёшься... |
| Автор: Earnest 1.9.2010, 20:01 |
Напрасно. Кроме reference (т.е. описания функция и их параметров) там есть такая штука как Technical Notes. Там много интересного. А что касается ReactOS - кто тебе сказал, что она устроена так же как windows? Похоже - наверное. WM_MOVE тоже приходит после свершившегося перемещения, так что изменить уже ничего нельзя. |
| Автор: ASMatic 2.9.2010, 02:57 | ||
| artsb, пасиб, но это не то. недакно встечался с одни, интересные там вещи говорят - однозначно.
также нет, но многие части похожи... В данный момент продолжаю искать TimerProc. Если уже точно надоест - есть заплаточное решение с таймерами Но если вдруг кто знает чего интересного - пишите,) Earnest, по поводу Technical Notes - может есть ссылки на "наборы" или по окнам, например уже ссыль готовый? благодарочка!) |
| Автор: Earnest 2.9.2010, 06:40 |
| Не очень поняла вопрос. Можно просто набрать Tech notes в индексе MSDN, там есть оглавление "по категориям" и посмотри, что тебе интересно. Кроме того, есть много интересных статей о разных тонкостях в Microsoft Knowledge Base. Да и в интернетах немало инфы. В общем, в поиск. |
| Автор: ASMatic 2.9.2010, 15:51 |
все же поняла пасиб! к стате - вчера уже нашелся путь как заставить таймер работать - WM_IME_SETCONTEXT, перехватили сделали всегда в активацию - таймер остаеться работать, но вот WM_PAINT не отправляет, поправил что теперь еще и инвалидатит рект 19-й таймер и усё - все работает, процессорр не жрёт и что самое главное - НИКАКИХ ТАЙМЕРОВ С МОЕЙ СТОРОНЫ! artsb, тебе благодарочка но это не то что надо... |