C++ Windows API перерисовать когда курсор в зоне

233
28 января 2019, 11:00

В WM_PAINT рисуется Rectangle (GDI+). Как изменить толщину края Rectangle когда курсор наведен на него и вернуть обратно когда нет? Изначально толщину задаю в Pen. Проверить наведение на Rectangle удалось в WM_MOUSEMOVE, но pen.SetWidth в WM_MOUSEMOVE или не работает или работает но нет перерисовки

Answer 1

Как уже ответили в комментариях, в обработчике WM_MOUSEMOVE нужно вызывать функцию InvalidateRect. Больше ничего не нужно, обработчик WM_PAINT все сделает сам.

Это решение имеет очевидные недостатки: 1) неэффективность, и 2) мерцание. Можно сделать сложнее, но лучше.

В обработчике WM_MOUSEMOVE:

1) Функцией CreateRectRgn создать два прямоугольных региона - первый включает себя область полностью, второй только внутреннюю часть без границы.

2) Функцией CombineRgn с аргументом RGN_DIFF создать разность регионов. Результирующий регион будет содержать только границу.

3) Вызвать InvalidateRgn (не InvalidateRect!). Таким образом, будет запрошено обновление только границы. Причем аргумент bErase должен быть FALSE, иначе будет мелькание в области границы.

Примечание: разумеется, это надо делать только тогда, когда курсор вошел в зону или вышел из зоны. То есть некий флажок должен хранить текущее состояние границы, и его надо проверять, прежде чем затевать перерисовку.

В обрабочике WM_PAINT:

1) Получить регион обновления функцией GetUpdateRgn.

2) Полученный регион использовать как аргумент функции SelectClipRgn.

3) Дальше обновлять обычным образом. Будет обновляться только граница (и прочие измененные области, если такие есть).

Можно пойти дальше и сделать обновление еще эффективней. Для этого нужно в WM_PAINT построить регион границы (как это делалось в WM_MOUSEMOVE) и найти его XOR с результатом функции GetUpdateRgn. Если XOR этих регионов даст в результате пустой регион, значит было запрошено обновление только границы, и ее можно просто отрисовать пером, само окно обновлять не нужно. Ну а если регион не пустой, значит нужно, как описано выше, установить клипинг и рисовать.

READ ALSO
QFile from native handle

QFile from native handle

Можно ли создать QFile из уже имеющегося "родного" дескриптора файла?

165
собственный класс-исключение java

собственный класс-исключение java

Пытаюсь реализовать собственный класс-исключениеСогласно условию он должен выводить сообщение об ошибке по умолчанию ("Устройство недоступно")...

200
как заставить JPanel накладыватсья на JPanel

как заставить JPanel накладыватсья на JPanel

Суть в том, что я добавил фото как Background, и сверху хочу еще добавить элементов (линии, другие панели, текс - это не важно), но при добавлении,...

183
Picasso 2.7. Как очистить кэш?

Picasso 2.7. Как очистить кэш?

Приложение загружает в RecyclerView много изображений из сети с помощью Picasso, версия 271828

179