Есть окно со стилем WS_POPUPWINDOW & ~WS_VSCROLL & ~WS_HSCROLL & ~WS_CAPTION & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX & ~WS_THICKFRAME
Делаю вручную resize окна с помощью функции MoveWindow c флашком repaint == true
Отрабатываю:
— WM_SIZE: меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер.
— WM_ERASEBKGND: return 1;
— WM_PAINT: ложу бэкбуффер на фронтбуффер;
В итоге неприятный эффект при ресайзе окна выходит, а именно если ресайзить окно из большего размера в меньший размер то сначала окно ресайзится пользователь видит несколько долей секунды обрезанную часть старого фронт буффера и затем только новый фронт буффер с новым содержимым под новый размер окна.
Как исправить? Как сделать чтобы видимый ресайз windows окна происходил одновременно с отрисовкой нового фронтбуфера без лагов или пусть даже ресайз с некоторой задержкой но главное чтобы одновременно?
Здравствуйте, Аноним, Вы писали:
А>Привет,
А>Есть окно со стилем WS_POPUPWINDOW & ~WS_VSCROLL & ~WS_HSCROLL & ~WS_CAPTION & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX & ~WS_THICKFRAME А>Делаю вручную resize окна с помощью функции MoveWindow c флашком repaint == true А>Отрабатываю: А> — WM_SIZE: меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер. А> — WM_ERASEBKGND: return 1; А> — WM_PAINT: ложу бэкбуффер на фронтбуффер;
А>В итоге неприятный эффект при ресайзе окна выходит, а именно если ресайзить окно из большего размера в меньший размер то сначала окно ресайзится пользователь видит несколько долей секунды обрезанную часть старого фронт буффера и затем только новый фронт буффер с новым содержимым под новый размер окна.
А>Как исправить? Как сделать чтобы видимый ресайз windows окна происходил одновременно с отрисовкой нового фронтбуфера без лагов или пусть даже ресайз с некоторой задержкой но главное чтобы одновременно?
Это в релизе? Обычно в дебаге есть небольшие лаги...
Попробуйте WS_EX_COMPOSITED...
Re[2]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
29.07.14 12:32
Оценка:
_>Это в релизе? Обычно в дебаге есть небольшие лаги...
Дебаг. При ресайзе окна из меньшего в большый размер — лага не наблюдается. А вот из большего размера окна в меньший выходит заметно неприятный эффект.
_>Попробуйте WS_EX_COMPOSITED...
Не годится — добавляет к окну системный заголовок и бордеры.
Здравствуйте, Аноним, Вы писали:
_>>Это в релизе? Обычно в дебаге есть небольшие лаги...
А>Дебаг. При ресайзе окна из меньшего в большый размер — лага не наблюдается. А вот из большего размера окна в меньший выходит заметно неприятный эффект.
На так, а в релизе что? Если нет бага, не вижу причин для страданий
Re[4]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
29.07.14 12:56
Оценка:
_>На так, а в релизе что? Если нет бага, не вижу причин для страданий
Тоже самое только менее заметно. Я думал может я что то накосячил или есть выбор как вести себе окну при ресайзе — мне предпочтительнее ресайз с задержкой но чтобы видеть сразу то что нужно.
Здравствуйте, Аноним, Вы писали:
А>Есть окно со стилем WS_POPUPWINDOW & ~WS_VSCROLL & ~WS_HSCROLL & ~WS_CAPTION & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX & ~WS_THICKFRAME А>Делаю вручную resize окна с помощью функции MoveWindow c флашком repaint == true А>Отрабатываю: А> — WM_SIZE: меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер. А> — WM_ERASEBKGND: return 1; А> — WM_PAINT: ложу бэкбуффер на фронтбуффер;
А>В итоге неприятный эффект при ресайзе окна выходит, а именно если ресайзить окно из большего размера в меньший размер то сначала окно ресайзится пользователь видит несколько долей секунды обрезанную часть старого фронт буффера и затем только новый фронт буффер с новым содержимым под новый размер окна.
А>Как исправить? Как сделать чтобы видимый ресайз windows окна происходил одновременно с отрисовкой нового фронтбуфера без лагов или пусть даже ресайз с некоторой задержкой но главное чтобы одновременно?
WM_SIZE приходит довольно редко.
Если нужна моментальная реакция — смотрите на WM_SIZING
Re[2]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
29.07.14 19:34
Оценка:
VF>WM_SIZE приходит довольно редко.
Как оно может приходить чаще, чем количество вызов MoveWindow? VF>Если нужна моментальная реакция — смотрите на WM_SIZING
MoveWindow sends the WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE, and WM_NCCALCSIZE messages to the window.
WM_SIZING не шлется вообще потому как нет смысла его слать.
Здравствуйте, Аноним, Вы писали:
А> — WM_PAINT: ложу бэкбуффер на фронтбуффер;
Имеется в виду, что WM_PAINT придет автоматически ? Попробуй его вызывать принудительно, то есть UpdateWindow на WM_SIZE, естественно, после переделки backbuffer. Не уверен, что поможет.
With best regards
Pavel Dvorkin
Re[4]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
30.07.14 13:18
Оценка:
VF>Тогда похоже, что задержка вызвана длительной отрисовкой второго буфера? Значит, надо отрисовать его ДО MoveWindow, поскольку размер известен заранее.
Не универсальный метод потому как еще есть MAXIMIZE, RESTORE, MINIMIZE там я не контролирую размеры окна вместо операционной системы но в самом крайнем случае попробую взять на себя такую ответственность.
Re[2]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
30.07.14 13:24
Оценка:
CEM>Лучше использовать SetWindowPos
Чем лучше?
Re[2]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
30.07.14 13:37
Оценка:
PD>Имеется в виду, что WM_PAINT придет автоматически ?
Да.
PD>Попробуй его вызывать принудительно, то есть UpdateWindow на WM_SIZE, естественно, после переделки backbuffer. Не уверен, что поможет.
Не помогло.
Здравствуйте, CEMb, Вы писали:
CEM>>>Лучше использовать SetWindowPos А>>Чем лучше? CEM>Глюков с отрисовкой не бывает
Дело, похоже, не в глюках. Просто Windows быстро перерисовывает "свою" часть, а клиент — долго.
Не понятно, что нужно перерисовывать при уменьшении размера. Масштабировать? Тогда можно на WM_ERASEBKGND не просто возвращать 1, а перерисовать прошлый буфер в нужном размере, например StretchBlt(). А потом, когда будет время, перерисовать правильно.
Здравствуйте, Аноним, Вы писали:
А>Привет,
А> — WM_SIZE: меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер. А> — WM_ERASEBKGND: return 1; А> — WM_PAINT: ложу бэкбуффер на фронтбуффер;
case WM_SIZE:
// ... меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер.
::InvalidateRect(hwnd,NULL,FALSE);
::UpdateWindow(hwnd);
return 0;
Здравствуйте, VladFein, Вы писали:
CEM>>>>Лучше использовать SetWindowPos А>>>Чем лучше? CEM>>Глюков с отрисовкой не бывает
VF>Дело, похоже, не в глюках. Просто Windows быстро перерисовывает "свою" часть, а клиент — долго. VF>Не понятно, что нужно перерисовывать при уменьшении размера. Масштабировать? Тогда можно на WM_ERASEBKGND не просто возвращать 1, а перерисовать прошлый буфер в нужном размере, например StretchBlt(). А потом, когда будет время, перерисовать правильно.
Ничё не понял но у нас были проблемы с перерисовкой, с MoveWindow, с уменьшением окна, со следами под окном. Решилось просто заменой на SetWindowPos.
Re[2]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
31.07.14 10:43
Оценка:
CS>
CS>case WM_SIZE:
CS> // ... меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер.
CS> ::InvalidateRect(hwnd,NULL,FALSE);
CS> ::UpdateWindow(hwnd);
CS> return 0;
CS>
Никакого эффекта. Не работает.
Re[4]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
31.07.14 10:49
Оценка:
CEM>Глюков с отрисовкой не бывает
Заменил MoveWindow на SetWindowPos таким вот образом:
VF>Дело, похоже, не в глюках. Просто Windows быстро перерисовывает "свою" часть, а клиент — долго. VF>Не понятно, что нужно перерисовывать при уменьшении размера. Масштабировать? Тогда можно на WM_ERASEBKGND не просто возвращать 1, а перерисовать прошлый буфер в нужном размере, например StretchBlt(). А потом, когда будет время, перерисовать правильно.
Мысль интересная, надо будет попробовать — возможно это наименьшее зло в данном случае.
CS>>case WM_SIZE:
CS>> // ... меняю размеры фронтбуффера и бэкбуффера под новый размер окна, перерисовываю бэкбуффер.
CS>> ::InvalidateRect(hwnd,NULL,FALSE);
CS>> ::UpdateWindow(hwnd);
CS>> return 0;
CS>>
А>Никакого эффекта. Не работает.
Значит проблема у тебя где-то еще.
InvalidateRect/UpdateWindow фосирует WM_PAINT (внутри UpdateWindow). Скорее всего или бэкбуффер у тебя медленно перерисоввыется, либо ты что-то напутал с бэкбуффер / front-buffer.
Кстати непонятно вообще зачем тебе два буффера.
CS>InvalidateRect/UpdateWindow фосирует WM_PAINT (внутри UpdateWindow). Скорее всего или бэкбуффер у тебя медленно перерисоввыется, либо ты что-то напутал с бэкбуффер / front-buffer. CS>Кстати непонятно вообще зачем тебе два буффера.
Ну да медленно. Фронтбуффер это и есть поверхность окна в оконном режиме или видеопамять если речь о полноэкранном режиме.
Вопрос о том как синхронизировать системный ресайз и отрисовку.
Re[4]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
01.08.14 11:16
Оценка:
PD>Покажи обработчик WM_PAINT
BeginPaint(get_hwnd(), &paint_struct);
video->present(); //в недрах библиотек это Blt бэкбуффера на фронтбуффер.
EndPaint(get_hwnd(), &paint_struct);
Re[6]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
01.08.14 11:21
Оценка:
CEM>А можно код, чтоб у себя посмотреть?
Нет конечно, проект до 500Mb под NDA
Здравствуйте, Аноним, Вы писали:
А>[ccode] А>BeginPaint(get_hwnd(), &paint_struct); А>video->present(); //в недрах библиотек это Blt бэкбуффера на фронтбуффер. А>EndPaint(get_hwnd(), &paint_struct);
Что понимается здесь под фронтбуффером ? Здесь должен быть BitBlt с бэкбуфера на hdc от BeginPaint, это так ? И ничего больше быть не должно.
With best regards
Pavel Dvorkin
Re[6]: Проблема с отрисовкой при resize окна
От:
Аноним
Дата:
01.08.14 12:24
Оценка:
PD>Что понимается здесь под фронтбуффером ? Здесь должен быть BitBlt с бэкбуфера на hdc от BeginPaint, это так ? И ничего больше быть не должно.
По сути так и есть. фронтбуффер это и есть поверхность окна в оконном режиме.
Здравствуйте, Аноним, Вы писали:
PD>>Что понимается здесь под фронтбуффером ? Здесь должен быть BitBlt с бэкбуфера на hdc от BeginPaint, это так ? И ничего больше быть не должно. А>По сути так и есть. фронтбуффер это и есть поверхность окна в оконном режиме.
Замени video->present() на нечто простое. Например, Rectangle(hdc_от_hWnd, весь размер) с рандомным цветом заливки прямоугольника. Эффект останется ?
Здравствуйте, Аноним, Вы писали:
А>Ну да медленно. Фронтбуффер это и есть поверхность окна в оконном режиме или видеопамять если речь о полноэкранном режиме. А>Вопрос о том как синхронизировать системный ресайз и отрисовку.
Ловите WM_WINDOWPOSCHANGING message, готовьте буффер ДО return;
Re: Вопрос закрыт
От:
Аноним
Дата:
01.08.14 13:43
Оценка:
Здравствуйте, Аноним, Вы писали:
Повесил на WM_ERASEBKGND: StretchBlt в итоге не обрезает изображение но теперь присутствует эффект дергания так как меняется масштаб видимых объектов вместо угла видимого обзора. Но все же это терпимее чем тупое обрезание.
Заморозить видимость системного ресайза окна до момента полной перерисовки окна я так понял нереально.
Re[2]: UPD: Вопрос закрыт
От:
Аноним
Дата:
01.08.14 17:23
Оценка:
А>Заморозить видимость системного ресайза окна до момента полной перерисовки окна я так понял нереально.
Благодаря совету здесь
Здравствуйте, Аноним, Вы писали:
А>>Заморозить видимость системного ресайза окна до момента полной перерисовки окна я так понял нереально. А>Благодаря совету здесь