web-dev-qa-db-ja.com

C#でデスクトップに効果的に描画する方法は?

C#でデスクトップに直接描画したい。少し検索したところ、デスクトップHDC(null)のGraphicsオブジェクトを使用することになりました。次に、このGraphicsオブジェクトを使用して通常どおりペイントしました。

問題は、画面のいずれかの部分を再描画すると、形状が失われることです。 Whileループを試しましたが、実際にはアプリケーションで可能な限り高速に描画されます。これはデスクトップの更新速度ではありません。

通常、描画コードを「OnPaint」イベントに配置する必要がありますが、そのようなものはデスクトップには存在しません。

どうすればいいですか?

コード例: https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c

14
Lazlo

HDC(NULL)に描画すると、管理されていない方法で画面に描画されます。あなたが発見したように、ウィンドウが画面のその部分を更新するとすぐに、あなたの変更は上書きされます。

達成したいことに応じて、いくつかのオプションがあります。

  1. ボーダレス、場合によっては長方形ではないウィンドウを作成します。 (SetWindowRgnを使用して、ウィンドウを非長方形にします。)これをデスクトップウィンドウの子にすることができます。
  2. デスクトップウィンドウをサブクラス化します。これは簡単ではなく、Explorer.exeプロセスにDLLを挿入する必要があります。
8
mdma

同様の要件に対して2つのソリューションを投稿しました ここ

基本的に2つのオプションがあります。

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番目のオプションは、透明な最上部のウィンドウを作成し、そのウィンドウですべての描画を行うことです。これは基本的に、描画できるデスクトップに透明なオーバーレイを提供します。これの1つの考えられる欠点は、元の回答で述べたように、アプリの起動後に作成される最上位のウィンドウが最上位のウィンドウを覆い隠すことです。それが問題であるならば、これは解決することができます。

オプション2の場合、フォームを透明にするのは透明キーを使用するのと同じくらい簡単です。これにより、マウスクリックなどが下にあるデスクトップに落ちることができます。

BackColor = Color.LightGreen; 
TransparencyKey = Color.LightGreen; 
15
Chris Taylor

デスクトップのOnPaintを取得するには、デスクトップウィンドウをサブクラス化し、WM_Paint/WM_ERASEBKGNDメッセージを受信したときに描画ロジックを使用する必要があります。

リンクしたスレッドが言うように、フック(DLLからのSetWindowsHookEx)を使用して外部プロセスのウィンドウに送信されたメッセージのみをインターセプトできます。

前述のように、透明なウィンドウはそれを行う別の方法です。または(更新頻度に応じて)一時的な壁紙をコピー、描画、および設定します( bginfo のように)。

3
Alex K.

これを正しく行うのは困難です。

代わりに、独自のボーダレスフォームを作成する方がはるかに簡単で、信頼性が高くなります。

1
SLaks