簡體   English   中英

使用Delphi繪制和清除桌面畫布

[英]Drawing and clearing the desktop canvas with Delphi

我正在嘗試通過使用桌面畫布並直接對其進行繪制來繪制整個屏幕。 問題是我無法清除該桌面畫布。 我嘗試將canvas.pen.style設置為psNotXOR並繪制舊圖像,但是不幸的是,這不夠可靠,在某些情況下仍存在一些剩余物。

我需要在鼠標懸停在窗口/控件周圍時在其周圍繪制一個選擇矩形。

清除后,您無需再寫關於哪個工件存在問題的操作系統。

至少在激活桌面合成的情況下,直接繪制到桌面上並進行XOR繪畫是一個非常糟糕的主意(請參閱本博客文章中的 “從屏幕上繪畫並閱讀-Baaaad!”)。 除了對性能的負面影響外,您無法確定同時會發生其他繪畫以及哪些效果和動畫會改變顯示的內容,因此,簡單的XOR可能不足以完全擦除所有內容。

一種可能的實現方式是在桌面上放置一個透明的疊加窗口,並在其上繪制橡皮筋選擇器。 如果大小更改應該足夠,則使整個窗口無效,無需擦除舊的選擇線。 如果移除覆蓋層,該線也將消失。 桌面合成將確保不會發生閃爍。 但是,在選擇區域時切換應用程序會出現問題,您需要抓住這一點並立即取消選擇。

編輯:

我剛剛使用Delphi 2009和以下測試應用程序對其進行了測試:

  • FormStyle設置為fsStayOnTopAlphaBlend設置為True的表單
  • 與重寫的CreateParams()方法一起添加WS_EX_TRANSPARENT擴展樣式標志

我可以將所有鼠標單擊傳遞到基礎窗口,同時能夠在它們之上繪制一個窗口。 這應該使您入門。

我過去做過類似的事情,但從來沒有想過可以接受的解決方案。

請考慮一下,盡管您可以向桌面HWND發送無效命令。

由於桌面是經過修改的listview控件,因此您應該可以使用類似

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

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

那可能會滿足您的要求,我還沒有對其進行測試,因為我只是將它作為示例。

問題是Windows不會向我返回鼠標背后的控件

我認為您需要為此掛鈎鼠標事件消息-掛鈎消息然后為您提供鼠標懸停的窗口句柄。

查找SetWindowsHookEx(WH_MOUSE ,,,)和MOUSEHOOKSTRUCT。

這是我們在應用程序中執行的操作:

    FBitmap.Canvas.Brush.Color := clWhite;
    FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM