我試圖通過使用桌面畫布和直接繪製到整個屏幕來繪製。問題是我無法清除桌面畫布。我已經嘗試將canvas.pen.style設置爲psNotXOR並繪製舊圖像,但不幸的是,這不夠可靠,並且在某些情況下仍然存在一些殘留的圖像。使用Delphi繪製和清除桌面畫布
我的需求是當鼠標懸停在窗口/控件周圍時,繪製一個選擇矩形。
我試圖通過使用桌面畫布和直接繪製到整個屏幕來繪製。問題是我無法清除桌面畫布。我已經嘗試將canvas.pen.style設置爲psNotXOR並繪製舊圖像,但不幸的是,這不夠可靠,並且在某些情況下仍然存在一些殘留的圖像。使用Delphi繪製和清除桌面畫布
我的需求是當鼠標懸停在窗口/控件周圍時,繪製一個選擇矩形。
你不寫什麼操作系統你清理後的人工製品有問題。
至少在激活桌面組合的情況下,直接繪製桌面並進行異或繪畫是一個非常糟糕的主意(請參閱this blog post中的「繪圖和從屏幕讀取 - Baaaad!」)。除了負面的性能影響,您無法確定其他繪畫同時發生了什麼,以及哪些效果和動畫會改變顯示的內容,因此,簡單的XOR可能不足以完全抹去所有內容。
實現它的一種可能的方式是桌面大小的透明覆蓋窗口,並繪製您的橡皮筋選擇器。如果大小更改應該足夠,則無效整個窗口,不需要擦除舊的選擇線。如果疊加層被刪除,該行也將消失。桌面組成將確保不發生閃爍。但是,在選擇區域時切換應用程序將會出現問題,您需要理解並立即取消選擇。
編輯:
我剛剛與德爾福2009年測試了它,並用下面的測試程序:
FormStyle
設置爲fsStayOnTop
與AlphaBlend
設置爲True
CreateParams()
方法添加WS_EX_TRANSPARENT
擴展樣式標誌我可以將所有鼠標點擊傳遞到底層窗口,同時能夠在頂層窗口中繪製窗口。這應該讓你開始。
我在過去做過這樣的事情,我從來沒有想出一個可以接受的解決方案。
雖然您可以向桌面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;
這可能會做你想要什麼修改ListView控件,我沒有測試它,因爲我剛剛敲起來的例子。
這是我們如何做到這一點在我們的應用程序:
FBitmap.Canvas.Brush.Color := clWhite;
FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect);
-1這不是OP要求的「清算」。相反,它只是畫一個白色的矩形。 – jpfollenius 2009-11-02 21:54:08
啊,呃。沒有正確閱讀這個問題。 – 2009-11-03 23:07:00
的問題是,Windows將不會返回我的控制鼠標
我覺得背後您需要爲此掛鉤鼠標事件消息 - 掛鉤的消息會爲您提供鼠標懸停的窗口句柄。
查找SetWindowsHookEx(WH_MOUSE ,,,)和MOUSEHOOKSTRUCT。
我已經使用全局鼠標鉤來檢索窗口句柄,但是當我創建頂層窗口時,即使它是透明的,Windows總是選擇它的句柄:( – jonjbar 2009-11-03 08:28:34
我曾考慮過這個問題,但問題在於Windows不會將控制權交還給我。還是會呢?想想看,如果畫布是透明的,這可能會起到訣竅的作用。我會嘗試的。 謝謝你提供非常詳細和有用的答案。 – jonjbar 2009-11-02 19:49:57
那麼,選擇不起作用,頂級窗口始終是鼠標後面的一個窗口。 – jonjbar 2009-11-03 08:29:23
對不起,不明白。你是否通過在桌面上點擊鼠標並開始拖動來開始選擇?如果是這樣,你如何用全局(低級別)鼠標鉤子來捕捉這個問題?或者你是否創建了疊加層(當處於特殊選擇模式時),並通過點擊鼠標開始選擇?也許你可以用更多的細節來擴展你的問題。 – mghie 2009-11-03 08:37:19