2010-05-25 42 views
13

我想直接在C#中的桌面上繪製。從搜索一下,我最終使用了桌面HDC的一個Graphics對象(null)。然後,我使用這個Graphics對象正常繪製。如何在C#中有效地繪製桌面?

問題是當屏幕的任何部分被重新繪製時,我的形狀會丟失。我嘗試了一個While循環,但實際上最終的繪圖速度與應用程序的速度一樣快,這不是桌面的更新速率。

通常情況下,我需要把我的繪製代碼在「的OnPaint」事件,但這樣的事情並沒有爲桌面存在。

我該怎麼做?

示例代碼:https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c

+0

什麼版本的Windows? – SLaks 2010-05-25 14:54:06

回答

8

當您繪製到HDC(NULL)時,以非託管方式繪製到屏幕。正如您發現的那樣,只要Windows刷新屏幕的這一部分,您的更改就會被覆蓋。

有幾個選項,這取決於你想要達到的目標:

  1. 建立一個無國界的,可能 非矩形窗口。 (使用 SetWindowRgn使窗口 非矩形。)您可以將其設置爲桌面窗口的子項。
  2. 子類的桌面窗口。這不是直截了當的,並且涉及到 Explorer.exe進程中的DLL注入 。
1

這是難以正確做。

改變自己的無邊界形式會容易得多,而且更可靠。

3

要獲得桌面的OnPaint,您需要繼承桌面窗口的子類,並在收到WM_PAINT/WM_ERASEBKGND消息時使用繪圖邏輯。

當你連接到螺紋說,你只能攔截髮送到使用鉤(SetWindowsHookEx從DLL)的外部過程的窗口消息。

如前所述,透明窗口是另一種方法,或者(取決於更新頻率)複製,繪製和設置臨時壁紙(如bginfo所做的那樣)。

15

我發佈了兩個解決方案,類似的要求here

基本上,你有兩個選擇。

1-獲取桌面的圖形對象並開始繪製它。問題是,如果你需要開始清除你先前已制定等

Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates 

using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) 
{   
    g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20); 
} 

2 - 我在上面的鏈接提供的第二個選擇是建立一個透明的最頂層窗口,做所有的繪圖中那個窗戶。這基本上爲您可以繪製的桌面提供透明覆蓋。正如我在最初的答案中提到的,其中一個可能的缺點是,其他窗口也是最頂級的,並且是在您的應用程序啓動後創建的,這將會掩蓋您最上層的窗口。這可以解決,如果它是一個問題,但。

對於選項2,使表單透明與使用透明鍵一樣簡單,這允許鼠標點擊等通過底層桌面。

BackColor = Color.LightGreen; 
TransparencyKey = Color.LightGreen; 
+0

據推測,這將*不適用於全屏應用程序(遊戲等)? – acron 2012-06-21 14:12:45

+2

應該將GetDesktopWindow()傳遞給Graphics.FromHwnd(),因爲IntPtr.Zero是一個可能會改變的實現細節,肯定會** NOT **適用於多桌面或多會話工作站。 – 2012-09-05 14:14:41