Вопрос № 54718: Здравствуйте уважаемые знатоки WinAPI!
Наверно я не очень понимаю механику окна Win, поэтому заранее прошу простить если сморожу глупость...;-)
Вот написал некий визуализатор некоей внешней относительно PC информации. Чистый WinAPI ...
Вопрос № 54.718
Здравствуйте уважаемые знатоки WinAPI!
Наверно я не очень понимаю механику окна Win, поэтому заранее прошу простить если сморожу глупость...;-)
Вот написал некий визуализатор некоей внешней относительно PC информации. Чистый WinAPI (в плане визуализации и самого окна). VSC++7.1. Всё работает: циферки бегают, лампочки мигают, батончики нажимаются... Но(!)...
Технологически необходимо, чтобы окошко было максимизировано (окно - основное, или как там оно называется, НЕ диалоговое, НЕ из ресурсов, создаётся VS-шаблоном в WinMain()).
Так вот, сама проблема: при появлении на экране любого другого окна, которое не перекрывает всю область экрана и убирания оного (всё равно какого: MessageBox'а из этой же программы или другого окошка, или просто при перемешении основного окна в "Восстановленном" виде (кнопочка "восстановить" оставлена в целях отладки)), основное окно продолжает перерисовываться только в том месте, где находилось то окошко. Вся остальная область окна - игнорируется для перерисовывания. Т.е. на той части окна,
которая была видна из-под другого окна изображение становится статичным, застывшим. Лечится либо кнопочкой "Восстановить", либо <Ctrl+Tab> на другую задачу, полностью перекрываюшую окном Desktop.
Как заставить окно продолжать перерисовываться _полностью_?
И вот, заодно ещё вопросик: перерисовывать некоторые графические объекты в окне нужно не только при WM_PAINT, но и по другим событиям, например WM_TIMER и при нажатии мышиных кнопок.
Так вот, если делаю отдельную процедуру рисования сразу всего (включающую пару BeginPaint/EndPaint или если упомянутую пару делаю глобальной, в WM_PAINT (со станической ps и hdc) - не важно), оконо перестаёт перерисовываться совсем (рисуется первый кадр статики). Приходится делать так:
в WM_PAINT делаю BeginPaint с глобальными переменными, рисую статику окна, а EndPaint делаю только при WM_DESTROY. В остальных местах вызываю самоперерисовывающиеся объекты с соответствующим hdc.
Почему не рисуется ничего когда (теоритически) код тот же самый, но оформлен в процедуру?
Заранее спасибо за ответы...
Отправлен: 08.09.2006, 12:15
Вопрос задал: Sergijj (статус: 5-ый класс)
Всего ответов: 3 Мини-форум вопроса >>> (сообщений: 3)
Отвечает: dentist
Здравствуйте, Sergijj!
не буду утверждать, что я скажу что-то на 100% приемлимое но...
я бы оставил в обработке сообщения WM_PAINT всё по старому т.е.
BeginPaint/EndPaint
и вызывал бы UpdateWindow().
но боюсь у вас проблема совсем не в этом.
если смотреть на код то мне в данном случае интересно былобы в первую очередь глянуть на цикл обработки сообщений.
у меня он обычно выглядит так:
for(;;)
{
if (GetMessage(...))
{
TranslateMessage(...)
DispatchMessage(...)
}
}
и никогда подобных вашей проблем не возникало.
с другой стороны в функции обработчике сообщений могли касяки выскачить.
жаль что кода вы не привели.
а так, на скорую руку, чтоб не вдаваться в подробности, в том же цикле кидать окну сообщение типа WM_PAINT.
примерно так:
for(;;)
{
if (GetMessage(...))
{
TranslateMessage(...)
DispatchMessage(...)
}
SendMessage(..., WM_PAINT....)
}
--------- "Software is like sex, it's better then it's free" (c) Linus Torvalds
Ответ отправил: dentist (статус: 3-ий класс)
Ответ отправлен: 08.09.2006, 15:37
Отвечает: Mystic
Здравствуйте, Sergijj!
Предлагаю попробовать при каждом событии WM_PAINT в конце добавлять функцию InvalidateRect(hWnd, Rect, true);
Rect - прямоугольник, где находится ваше окно (а можно, наверное, сделать и весь экран, не пробовал).
Не знаю, поможет ли, но, по идее, должно.
Ответ отправил: Mystic (статус: 1-ый класс)
Ответ отправлен: 08.09.2006, 19:42
Отвечает: estiGi
Здравствуйте, Sergijj!
дело в том, что получая контекст для рисования с помощью BeginPaint/EndPaint, вы получаеете только ту часть, которая, как считает система, в данный момент должба быть отрисована. Чтобы получить весь контекст, всего окна, и применить нарисованное ко всему окну, делайте так:
Если рисование сложное, объемное etc, лучше рисовать на созданном в памяти контексте, а в WM_PAINT просто копировать - будет намного быстрее. Рисовать можно в отдельном потоке - если объемные работы, а если статическая или малоизменяемая картинка, то вообще один раз просто отрисовать в памяти и просто уже копировать готовый контекст
вызываеть перересовку своего ркна лучше всего посылкой себе же сообщения:
SendMessage (m_hWnd, WM_PAINT, 0, 0);
Ответ отправил: estiGi (статус: Студент)
Ответ отправлен: 09.09.2006, 23:08