Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Опять окна. кто отвечает за перерисовку окна? 
V
    Опции темы
ASMatic
Дата 31.8.2010, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



Есть окно одной программы. Решил его перерисовать на свое окно. 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 секунд
добавлю еще то что когда окно спрятать не полностью, т.е. один пиксель оставить на дисплее - перерисовывает практически все, не считая некоторых мелочей(нажатую кнопку, например не перерисовывает)
+вся графика нарисована в одном окне, т.е. организованы свои контролы.
PM MAIL   Вверх
Earnest
Дата 31.8.2010, 06:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Экспериментальный зуд и энтузиазм налицо, но почему бы книжку не почитать-то?
Все верно, WM_PAINT посылает окну система, если есть невалидная (нуждающаяся в перерисовке) область окна (на экране, конечно) и если ей (системе) больше делать нечего. Т.е. сообщение низкоприоритетное, ниже приоритетом только таймер. Что перерисовывать - это уже решает оконная функция, ей ведь сообщают невалидный регион, а использовать его или чихать и рисовать все - ее дело. Но, конечно, реально обновится только то, что не закрыто регионом отсечения. Вот, нарпимер, кнопка может быть закрыта, если у окна стоит стиль ClipChildren. И вообще, каждое окно получает WM_PAINT отдельно (т.е. родительское окно и его контролы).

Так что для твоей задачи - таки WM_PRINT.


--------------------
...
PM   Вверх
ASMatic
Дата 31.8.2010, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



Цитата(Earnest @  31.8.2010,  04:42 Найти цитируемый пост)
ей ведь сообщают невалидный регион

каким образом можно узнать этот регион,а то найти его не смог(правда особо и не искал))?

По поводу того что система посылает WM_PAINT знаю)
Теперь объясни мне пожалуйста( если не трудно, естественно):
Почему когда окно почти полностью находиться за пределами экрана, обработчик WM_PAINT игнорирует что ему там сказала система и на главную DC копирует ПОЧТИ все, не считая некоторых мелочей.
На картинке (не постеснялся_выложил) Видно снизу окно с которого я перемещаю изображение на свое тестовое. В Spy++ видны мессаги, т.е. таймер с айди 19 отвечает за перерисовку курсора в едитах (едиты самописные, не виндозные) В данном случае он не перерисовал, т.к. смысла не было (где то проверка не сошлась) НО когда я снизу торчащее окно перекрою чем небудь - однократно приходит и WM_PAINT. Как я понимаю ситуацию - программа сама определяет что она вне окна и перерисовывать не хочет. Только КАК ОНА ЭТО ВИДИТ???
если
Код

LRESULT
CALLBACK
GarminWndProc(
    IN      HWND    hWnd,
    IN      UINT    Msg,
    IN      WPARAM  wParam,
    IN      LPARAM  lParam
    )
{

    switch (Msg) {

        case WM_CAPTURECHANGED:
            return FALSE;

        case WM_KILLFOCUS:
            return FALSE;

        case WM_ACTIVATE:
            wParam = WA_CLICKACTIVE;
            break;

        case WM_ACTIVATEAPP:
            if (!(BOOL)wParam)
                return FALSE;

        case WM_NCACTIVATE:
            return FALSE;

        case WM_WINDOWPOSCHANGING:
        case WM_WINDOWPOSCHANGED:
            //return FALSE;
            ((PWINDOWPOS)lParam)->flags |= SWP_NOOWNERZORDER | SWP_NOREPOSITION |
                                           SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW;

            ((PWINDOWPOS)lParam)->flags &= (~SWP_HIDEWINDOW);
            ((PWINDOWPOS)lParam)->flags &= (~SWP_NOACTIVATE);

            //((PWINDOWPOS)lParam)->x = 0;
            //((PWINDOWPOS)lParam)->y = 0;
            break;

        case WM_MOVE:
            //return FALSE;
            lParam = 0;
            break;
            //return FALSE;

        //case WM_TIMER:
        //    if ((wParam == 23) || (wParam == 26))
        //        return FALSE;
    }

    DPRINT( "\nGARMIN message:\n  Msg: %x\n  wParam: %x\n  lParam: %x\n\n",
            Msg,
            wParam,
            lParam );

    return CallWindowProc( OrigGarminWndProc,
                           hWnd,
                           Msg,
                           wParam,
                           lParam );
}


Добавлено через 5 минут
*в данный момент был выделен эдит со значением 685 - должен был изменить фон на коричневый... Меняет когда перекрыть чем то и забрать, т.е. винда увидела кусок не перерисованого окна и послала мессагу. Но обычно (когда окно видно полностью) WM_PAINT приходит по таймеру, помимо виндозной "провокации"))

Присоединённый файл ( Кол-во скачиваний: 14 )
Присоединённый файл  Screen.png 827,40 Kb
PM MAIL   Вверх
Earnest
Дата 31.8.2010, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(ASMatic @  31.8.2010,  08:27 Найти цитируемый пост)
каким образом можно узнать этот регион,а то найти его не смог(правда особо и не искал))?

Спросить у DC (которое получается из запроса BeginPaint).
Цитата(ASMatic @  31.8.2010,  08:27 Найти цитируемый пост)
Почему когда окно почти полностью находиться за пределами экрана, обработчик WM_PAINT игнорирует что ему там сказала система и на главную DC копирует ПОЧТИ все, не считая некоторых мелочей.

Не очень понимаю, кто такая "главная DC", но я ведь уже говорила, что невалидный регион - только рекомендация к сведению, многие  приложения перерисовывают все, если так проще. 
Цитата(ASMatic @  31.8.2010,  08:27 Найти цитируемый пост)
Как я понимаю ситуацию - программа сама определяет что она вне окна и перерисовывать не хочет. Только КАК ОНА ЭТО ВИДИТ???

Если окно программы чем-то перекрыто, есть регион отсечения - тоже можно узнать у DC. Там рисуй - не рисуй, все равно отсечется.
Кстати, его можно и поменять. Расширять, я правда никогда не пробовала, только сужать. Но попробовать можно.
Цитата(ASMatic @  31.8.2010,  08:27 Найти цитируемый пост)
 Но обычно (когда окно видно полностью) WM_PAINT приходит по таймеру,

Таймер по дефолту с прорисовкой никак не связан. Но исследуемое приложение, вполне возможно, по таймеру инвалидэйтит окна.

Все таки корректно сдирать чужое окно через WM_PRINT. Остальное наверняка где-то да выйдет боком. Что касается производительности, так насколько я поняла, ты пытался делать это по таймеру, что, видимо, чересчур. Лучше подумать на предмет оптимизации.



--------------------
...
PM   Вверх
artsb
Дата 31.8.2010, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



ASMatic, имхо, для вас самый лучший вариант: создать виртуальный экран; переместить туда форму; и спокойненько получать скрины как и раньше.

ЗЫ виртуальных скринов я не создавал, поэтому помочь не смогу.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
artsb
Дата 31.8.2010, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64





--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
ASMatic
Дата 31.8.2010, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Спросить у DC (которое получается из запроса BeginPaint).

Как понял ты о "загадочной" (для мня) структуре, о которой мне всю жизнь не было желания почитать зачем она)) Сейчас перехвачу еще BeginPaint и попробую заставить гада рисовать что я хочу)

Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Не очень понимаю, кто такая "главная DC",

Ну да, еще бы) - утром уже после ночи немного выразился не корректно. Имелось ввиду DC самого окна, не служебные созданые приложением CreateCompatibleDC и т.п. которых приложение во сремя инициализации создает, их много на самом деле..


Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Там рисуй - не рисуй, все равно отсечется.

у меня не отсекаеться)
Код

BOOL
WINAPI
BitBltProc(
    IN      HDC     hDestDC,
    IN      INT     xDest,
    IN      INT     yDest,
    IN      INT     Width,
    IN      INT     Height,
    IN      HDC     hSrcDC,
    IN      INT     xSrc,
    IN      INT     ySrc,
    IN      DWORD   Flags
    )
{
    INT     result;

        result = OrigBitBlt( hBackDC,
                             xDest,
                             yDest,
                             Width,
                             Height,
                             hSrcDC,
                             xSrc,
                             ySrc,
                             Flags );


        InvalidateRect( hDllWnd,
                        NULL,
                        FALSE );

    return result;
}

hBackDC - єто мой компатибл:) , а hDllWnd - мое окно...



Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Расширять, я правда никогда не пробовала, только сужать. Но попробовать можно.


думаю что и сужать можно, т.к. StretchBlt все нормальненько сужает( уменя) и растягивать, думаю не запарилось бы)


Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Таймер по дефолту с прорисовкой никак не связан

Ну это знаю, не первый день за "рулем)



Цитата(Earnest @  31.8.2010,  08:22 Найти цитируемый пост)
Все таки корректно сдирать чужое окно через WM_PRINT. Остальное наверняка где-то да выйдет боком. 


 Во первых этот месадж не все окна обрабатывают! По крайней мере это окно не хотело рисовать + гдето вычитал(вродже мсдн) что не все контролы в DefWindowProc имеют такой функционал. Слал PrintWindow по таймеру - бред!
Боком пока не вылезло - ща надеюсь paitnctruct подправлю и будет норм...И что самое главное - я не буду говорить - перерисуйся, оно само когда ему надо будет переисовываться - что есть ни чем иным как оптимальным решением...


Цитата(artsb @  31.8.2010,  08:38 Найти цитируемый пост)
имхо, для вас самый лучший вариант: создать виртуальный экран; переместить туда форму; и спокойненько получать скрины как и раньше.


это было первой мыслю когда понял что задесктопные окна не прорисовую себя, но это - извращение!
ИМХО!
но полюбому спасибо!!
ссылки почитаю!!!

итог - сейчас валю перхватывать BeginPaint и если всетаки я прав - будет очаровательно красивое решение по перерисовке окна.
пока спасибо, тестану - отпишусь!

PM MAIL   Вверх
ASMatic
Дата 31.8.2010, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



итог утром оказался не верным) - вовремя понял что это не оно, т.к. мне вообще WM_PAINT по таймеру перестет приходить. В ф-и обработки одного из таймеров есть зарыта проверка на десктопе ли мы! Её определить пока не получаеться((
PM MAIL   Вверх
ASMatic
Дата 31.8.2010, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



Итак
WM_WINDOWPOSCHANGING - приходит окну когда я сделал SetWindowPos(),в структуре подменили x=0,y=0, вызвали орижинал процедуру... Все оно бы ничего, но как оказалось за перемещение окна отвечает само окно. Т.е. я установил 0, 0 и окно быстренько переместилось на нулевые координаты. Вопрос, как окно само себя перемещает?
Т.е. есть координаты где оно в данные момент находиться, вм_паинт - прорисовывает, тут пришел пос_чендж и окно почему то начало рисовать себя в другом месте. Но в PAINTSTRUCT координаты задаються относительно начала клиентской области самого окна, а не десктопа - как тогда перерисовка происходит?

*просветлите мою голову в ГУИ, плз...
PM MAIL   Вверх
Earnest
Дата 1.9.2010, 06:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(ASMatic @  31.8.2010,  20:50 Найти цитируемый пост)
 тут пришел пос_чендж и окно почему то начало рисовать себя в другом месте.

Мне нравится это "почему-то". Ты же сам поменял координаты в WM_WINDOWPOSCHANGING! Собственно, для этого примерно это сообщение и посылается - ДО перемещения, сообщая куда собралось перемещаться, и в этот момент еще можно что-то изменить. А WM_WINDOWPOSCHANGED уже приходит после свершившегося перемещения.
Цитата(ASMatic @  31.8.2010,  20:50 Найти цитируемый пост)
как тогда перерисовка происходит?

За координаты отвечает DC - в нем установлена система координат, которая "знает", что 0, 0 - это не "совсэм" 0, а левый верхний угол клиента.

Твою бы энергию да в мирных целях... Все это написано в MSDN, ну почему бы не почитать-то.   smile 




--------------------
...
PM   Вверх
ASMatic
Дата 1.9.2010, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



Цитата(Earnest @  1.9.2010,  04:36 Найти цитируемый пост)
Твою бы энергию да в мирных целях..

только в мирныхsmile


Цитата(Earnest @  1.9.2010,  04:36 Найти цитируемый пост)
Все это написано в MSDN, ну почему бы не почитать-то.

единственное что там могу читать  - описания апи и структур, т.к. с остальным зачастую поиски заканчиваються неудачами)

Да и не думаю что на мсдн будуть расписывать свои внутренности.)

Вчера полез в исходники ReactOS, посмотрел что там - оказалось что WM_WINDOWPOSCHANGING парктически ничего не делает..Несколько проверкок и все... Но вот WM_WINDOWPOSCHANGED все уже и делает. И как "быстрым взглядом" посмотрел - в конечном итоге посылаеться WM_MOVE а та уже все перемещает....Но вот я сам обрабатываю WM_MOVE, т.е. ретурн - но окно всеравно перемещаеться, видимо в р0 послали какой-нить "месадж" и окно переместилось уже там.... - громоздкая функа по обработке WM_MOVE, поэтому не полностью разобрался...

Решено было разобраться с таймерами, т.е. почему 19-й таймер(WM_PAINT сендает) ориентируться что окно не надо перерисовывать....Покаместь сижу в иде и виндбг с надеждой что всетаки пойму где это происходит(проверочка).

По дороге нашел еще мессагу, которая может влиять на состояние активный или нет WM_IME_SETCONTEXT, надо её тоже в обработку взять. Может есть еще какие мессаги о которых я не догадываюсь и они могут влиять на активный\не активный и положение окна?
PM MAIL   Вверх
artsb
Дата 1.9.2010, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



ASMatic, вот в этой теме, совместными усилиями Данкинг и Keeper89 написан пример. Надеюсь поможет ;)

Добавлено через 54 секунды
Правда он на Делфях. Но думаю, разберёшься...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Earnest
Дата 1.9.2010, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(ASMatic @  1.9.2010,  15:57 Найти цитируемый пост)
Да и не думаю что на мсдн будуть расписывать свои внутренности

Напрасно. Кроме reference (т.е. описания функция и их параметров) там есть такая штука как Technical Notes. Там много интересного.
А что касается  ReactOS - кто тебе сказал, что она устроена так же как windows? Похоже - наверное. WM_MOVE тоже приходит после свершившегося перемещения, так что изменить уже ничего нельзя.


--------------------
...
PM   Вверх
ASMatic
Дата 2.9.2010, 02:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 14.3.2009

Репутация: 1
Всего: 1



artsb, 
пасиб, но это не то.


Цитата(Earnest @  1.9.2010,  18:01 Найти цитируемый пост)
 Technical Notes

недакно встечался с одни, интересные там вещи говорят - однозначно.



Цитата(Earnest @  1.9.2010,  18:01 Найти цитируемый пост)
А что касается  ReactOS - кто тебе сказал, что она устроена так же как windows

также нет, но многие части похожи...

В данный момент продолжаю искать TimerProc.
Если уже точно надоест - есть заплаточное решение с таймерамиsmile

Но если вдруг кто знает чего интересного - пишите,)


Earnest, 
по поводу Technical Notes - может есть ссылки на "наборы" или по окнам, например уже ссыль готовый?
благодарочка!)
PM MAIL   Вверх
Earnest
Дата 2.9.2010, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Не очень поняла вопрос. Можно просто набрать Tech notes в индексе MSDN, там есть оглавление "по категориям" и посмотри, что тебе интересно. Кроме того, есть много интересных статей о разных тонкостях в Microsoft Knowledge Base. Да и в интернетах немало инфы. В общем, в поиск.


--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0793 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.