Улучшение кода для обработчиков WM_PAINT и WM_CTLCOLORSTATIC

ВВЕДЕНИЕ И СООТВЕТСТВУЮЩАЯ ИНФОРМАЦИЯ:

Я реализовал сложную отрисовку фона главного окна и его дочерних статических элементов управления.

На рисунке ниже показано, как это выглядит.

введите описание изображения здесь

Статические элементы управления имеют SS_NOTIFY стиль, который важно упомянуть, поскольку определенные вещи происходят, когда пользователь нажимает на них.

На данный момент действия, активируемые при нажатии на них, не актуальны.

Как основное окно, так и статические элементы управления имеют градиентный фон, который был сделан с помощью GradientFill(...) API.

Верхний баннер главного окна создается серой кистью, а линии сетки — LineTo(...) а также MoveTo(...) API.

Карта на оранжевом статическом контроле, а верхний левый логотип EMF файлы, верхний правый логотип PNG файл и другие изображения являются растровыми изображениями.

Оранжевый статический элемент управления имеет 4 дочерних статических элемента управления, которые owner drawn а также есть SS_NOTIFY стиль.

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

Чтобы покрасить оранжевый статический элемент управления, я решил покрасить его фон в WM_CTLCOLORSTATIC обработчик, а владельцу нарисовать дочерние статические элементы управления в процедуре подкласса.

Уведомления, полученные от дочерних статических элементов управления, также обрабатываются в процедуре подкласса оранжевых статических элементов управления, поскольку я не знал, как переслать их в родительское окно, но опущен, поскольку они также не имеют значения в данный момент.

Я решил предоставить ссылку на демонстрационный проект, вместо того, чтобы сделать этот пост довольно длинным с фрагментами кода.

Я попытался подать демо-заявку как можно меньше и проще.

Я не скупился на комментарии, поэтому считаю, что все хорошо освещено и объяснено в исходном коде.

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

Вот ссылка на демонстрационный проект:http://www.filedropper.com/geotermistgrafika_1

Важное обновление:

/ ================================================= ========= /

Текст ниже в квадратных скобках был первоначальной частью вопроса, но теперь он опущен, так как в проекте были утечки памяти. Приведенная выше ссылка ссылается на улучшенную версию.

[ Обновлено в ответ на комментарий участника xMRi: Эта ссылка должна быть в порядке: http://www.filedropper.com/geotermistgrafika ]

/ ================================================= ========= /

Я работаю на Windows XP, используя MS Visual Studio C ++ и чистый Win32 API.

Одна запись: с экспресс-издания VS не имеет редактора ресурсов, файл ресурса и заголовок ресурса были созданы с использованием ResEdit отсюда: http://www.resedit.net/.

ПРОБЛЕМА:

Когда я изменяю размер окна, статические элементы управления слегка мерцают.

МОИ УСИЛИЯ ДЛЯ РЕШЕНИЯ ПРОБЛЕМЫ:

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

Я думаю, что я правильно справился WM_ERASEBKGNDи я исключил стили CS_VREDRAW а также CS_HREDRAW из моего окна класса — поэтому мерцание не должно быть вызвано из-за этого.

Я забыл упомянуть, что мое окно имеет WS_CLIPCHILDREN стиль, поэтому я упоминаю, что сейчас, в ответ на комментарий ниже, сделанный участником Роджер Роуланд.

Я реализовал двойную буферизацию для обоих обработчиков, чтобы избежать мерцания.

ВОПРОСЫ:

  1. Как я могу изменить код в демонстрационном проекте, чтобы избавиться от мерцания?

  2. Мне нужен совет о том, как оптимизировать оба WM_PAINT а также WM_CTLCOLORSTATIC обработчики, поэтому мой код рисования становится более эффективным и быстрым.

Небольшая заметка для второго вопроса:

Я думал улучшить свой код, рисуя всю картинку на фоне главного окна, и поместить прозрачные статические элементы управления поверх той части изображения, которая соответствует фону статических элементов управления.

Таким образом, я бы только вернулся NULL_BRUSH в моем WM_CTLCOLORSTATIC обработчик, и делать всю работу в WM_PAINT,

Я на правильном пути с этой идеей? Может ли это работать?

Спасибо.
С уважением.

4

Решение

Во-первых, ваше приложение чертовски дырявое. Не искали утечек, но большинство из них должно быть в WM_CTLCOLORSTATIC как вы забыли удалить HBITMAP (используйте эту аккуратную бесплатную http://www.nirsoft.net/utils/gdi_handles.html искать утечки gdi).

Во-вторых, ваш код — это путь к большому. Я заметил, что вы не использовали функции, возможно, потому что вы не знаете, на что они способны. Например, я бы использовал:

void DrawBackground(HDC &hDC, SOMEINFOSTRUCT GradientInfo, LPCTSTR Text);

значительно упростить ваш код.

Во всяком случае достаточно лекций, давайте вернемся к вашей проблеме. В WM_CTLCOLORSTATIC Вы должны вернуть кисть, вы хотите нарисовать фон с. Теперь вы рисуете фон вручную, используя Bitblt(), затем верните кисть NULL и программа нарисует ее на уже окрашенном фоне. Вместо того, чтобы красить это самостоятельно, позвольте кисти делать работу.
Просто вместо последнего Bitblt() использование CreatePatternBrush(), но тогда вам нужно позаботиться об этой кисти и вот что вы должны сделать:

HBRUSH TempBrush = NULL; //Create global brush

//Some Code....

case WM_CTLCOLORSTATIC:
{
if (TempBrush != NULL)
{
DeleteObject(TempBrush);
TempBrush = NULL;
}

//Let's skip to the end....
GradientFill( MemDC, vertex3, 3, &gTriangle, 1,
GRADIENT_FILL_TRIANGLE );

TempBrush  = CreatePatternBrush(bmp);// these 3 line should be at the
//end of every if
DeleteDC(MemDC);      // or put them once outside if's
DeleteObject(bmp);  // also if you delete HDC first, you don't need to
//unselect hbitmap
}
return (LRESULT)TempBrush;
}
break;

case WM_CLOSE:
{
if (TempBrush != NULL)
{
DeleteObject(TempBrush);
TempBrush = NULL;
}
//.......
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]