Рисование и очистка рабочего стола с помощью Delphi - PullRequest
1 голос
/ 02 ноября 2009

Я пытаюсь нарисовать весь экран, используя рабочий стол и рисуя его напрямую. Проблема в том, что я не могу очистить этот рабочий стол. Я попытался установить для canvas.pen.style значение psNotXOR и нарисовать старое изображение, но, к сожалению, это недостаточно надежно, и в некоторых условиях некоторые остатки все еще присутствуют.

Мне нужно нарисовать прямоугольник выделения вокруг окна / элемента управления, когда над ним находится мышь.

Ответы [ 4 ]

5 голосов
/ 02 ноября 2009

Вы не пишете в какой ОС у вас проблемы с артефактами после очистки.

По крайней мере, с активированной композицией рабочего стола очень плохая идея рисовать прямо на рабочем столе и рисовать XOR (см. «Рисование и чтение с экрана - Baaaad!» В этом сообщении в блоге ). Помимо негативного влияния на производительность, вы не можете быть уверены, что происходит одновременно с другой картиной и какие эффекты и анимации влияют на отображаемый контент, поэтому простого XOR может быть недостаточно для полного удаления всего.

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

Edit:

Я только что протестировал его с Delphi 2009 и со следующим тестовым приложением:

  • форма с FormStyle, установленным на fsStayOnTop и с AlphaBlend, установленным на True
  • с переопределенным методом CreateParams() для добавления флага WS_EX_TRANSPARENT расширенного стиля

Я могу передавать все щелчки мышью до нижележащих окон, но при этом могу рисовать в окне поверх них. Это должно начать вас.

0 голосов
/ 03 ноября 2009

проблема в том, что Windows не возвращает мне управление мышью

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

Найдите SetWindowsHookEx (WH_MOUSE ,,,) и MOUSEHOOKSTRUCT.

0 голосов
/ 03 ноября 2009

Вот как мы делаем это в нашем приложении:

    FBitmap.Canvas.Brush.Color := clWhite;
    FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect);
0 голосов
/ 02 ноября 2009

Я делал такие вещи в прошлом и никогда не придумал приемлемого решения.

Подумав об этом, вы можете отправить настольному HWND недействительную команду.

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

procedure InvalidateDesktop;
begin
  RedrawWindow(GetDesktopWindow, 0, 0, RDW_INVALIDATE);

  //if that doesn't work then try this:
  //Sendmessage(GetDesktopWindow, wm_setredraw, 1, 0);
end;

Это может делать то, что вы хотите, я не проверял это, я только что подобрал это для примера.

...