У меня есть сложная картина для реализации в моем главном окне WM_PAINT
обработчик.
Я представил картинку ниже, чтобы проиллюстрировать это:
Главное окно имеет статические элементы управления вместо кнопок, которые имеют стиль SS_NOTIFY
,
Когда пользователь нажимает на них, в программе происходят определенные действия.
На следующем рисунке показано, где находятся статические элементы управления в главном окне:
Карта на оранжевой панели представляет собой EMF
файл, верхний левый и правый логотипы PNG
файлы и другие изображения являются растровыми изображениями.
Чтобы выполнить эту задачу, я решил нарисовать всю картину в WM_PAINT
и наложить невидимые статические элементы управления на изображения, соответствующие им.
Поэтому я только возвращаюсь NULL_BRUSH
в WM_CTLCOLORSTATIC
обработчик, как это:
case WM_CTLCOLORSTATIC:
return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );
я работаю на Windows XP
, с помощью MS Visual Studio C++ 2008 Express Edition
а также pure Win32 API
,
Одна запись: с экспресс-издания VS не иметь редактор ресурсов, файл ресурсов и заголовок ресурса были созданы с использованием ResEdit отсюда: http://www.resedit.net/.
Когда я изменяю размер окна, статические элементы управления слегка мерцают.
Я справился WM_ERASEBKGND
(возвращаемый (LRESULT)1
) и я исключил стили CS_VREDRAW
а также CS_HREDRAW
из моего окна класса — поэтому мерцание не должно быть вызвано из-за этого.
Мое окно не имеет WS_CLIPCHILDREN
стиль.
РЕДАКТИРОВАТЬ:
В ответ на комментарий ниже я объясню, почему в моем окне не установлен этот стиль:
Проблема в том, что часть изображения рабочего стола видна там, где находятся статические элементы управления.
Я реализовал двойную буферизацию для обоих обработчиков, чтобы избежать мерцания.
Я использовал инструмент GDIView
скачал отсюда: http://www.nirsoft.net/utils/gdi_handles.html отслеживать GDI leaks
,
Каждый раз, когда я изменяю размер своего окна, GDIView
показывает +4 в столбце для регионов, что означает, что я утечки регионов.
Я не могу понять, как это возможно, так как я не использую API, которые манипулируют регионами.
Чтобы точно показать, с чем я сталкиваюсь, я сделал демонстрационное приложение с подробными комментариями:
http://www.filedropper.com/geotermistgrafika
Я считаю, что это более эффективный способ, чем размещение кода, поскольку он будет занимать слишком много места.
Как я могу изменить код в демонстрационном проекте, чтобы избавиться от мерцания?
Является ли мой подход неправильным, и если это так, то какой правильный?
Спасибо.
С уважением.
При изменении размера главного окна WM_SIZE
Обработчик перемещает статические дочерние окна.
При перемещении дочернего окна Windows автоматически копирует клиентскую область дочернего элемента управления из старого местоположения в новое местоположение.
Главное окно затем перекрасится в WM_PAINT
обработчик.
Другими словами, когда размер окна изменяется, все статические элементы управления перемещаются в новое положение, а затем остальная часть окна перерисовывается. Это отсутствие синхронизации выглядит как мерцание.
Вы можете избежать этого, передав SWP_NOCOPYBITS
флаг для SetWindowPos
,
Других решений пока нет …