2

部分的に透明な黒い背景を描画するフォームで .NET 3.5 アプリを作成しています。これを達成するために OnPaintBackground をオーバーライドしています:

protected override void OnPaintBackground( PaintEventArgs e )
{
    using ( Brush brush = new SolidBrush( Color.FromArgb( 155, Color.Black ) ) )
    {
        e.Graphics.FillRectangle( brush, e.ClipRectangle );
    } 
}

機能しますが、フォームが画面をクリアせずに描画され、透明度が本来よりも暗くなることがあります。Graphics.Flush()とで遊んでみましたGraphics.Clear()が、役に立たないか、透明度が完全に削除されます。助言がありますか?

編集: 左側でアプリを起動した後、右側で (あるコントロールから別のコントロールへのタブ移動に応答して) フォームが数回再描画された後、次のようになります。

透明性の問題 http://www.quicksnapper.com/files/5085/17725729384A10347269148_m.png

編集 2: 今朝いくつか試してみたところ、透明な部分の背後にあるデスクトップが変更されたときに、実際には再描画されていないことに気付きました。たとえば、タスク マネージャーを開いてウィンドウの後ろに置いた場合、それ自体が更新されることはありません。これは、私が透明度レベルで見てきたことから理解できます。ウィンドウの後ろの領域を Windows に再描画させる機能はありますか?

編集 3: フォームのいくつかのプロパティを変更しようとしましたが、すべてフォームが非透明な黒で描画されます。

this.AllowTransparency = true;
this.DoubleBuffered = true;
this.Opacity = .99;

オーバースラッキングで述べたように、透明部分用に別のウィンドウを作成してみますが、他のアイデアはまだ歓迎されています。

4

2 に答える 2

3

実際、私はこれをこの予想される動作と呼んでいると思います。私が行うことは、背景をメモリ内のビットマップにレンダリングし、ペイントイベントで、それをフォームにコピーすることです(基本的なダブルバッファリング)。

ベースから離れている場合は、スクリーンショットを投稿していただけますか?あなたが正しく説明していることを私が想像していることを私は知りません。

編集:

OnPaintBackground ... pre-.NETの使用について疑問に思っています。ダブルバッファリングを行っている場合は、WM_ERASKBKGNDメッセージをキャッチして無視し(ちらつきを防ぐため)、画像をオフスクリーンバッファにレンダリングし、 WM_PAINTの画面へのバッファ。したがって、OnPaintBackgroundからOnPaintに変更してみてください。

私は.NETでこの種のことをあまり行ったことがありませんが、以前はかなりうまく処理していました。うまく翻訳できるかどうかわかりません!

編集2:

マーク、あなたがやろうとしていることについて考えれば考えるほど、より多くの問題が現れます。画面をキャプチャして暗くするための専用のバックグラウンドスレッドを作成することを提案しました。ただし、独自のフォームを削除するには、可視性をfalseに設定する必要があり、他の問題が発生します。

諦めたくない場合は、2つのウィンドウを作成し、それらを「バインド」することをお勧めします。背景ウィンドウに(不透明度を設定して)半透明のウィンドウを作成し、前景に2番目の「通常の」ウィンドウを作成します。前景ウィンドウでSetWindowRgnを使用して、背景を切り取り、それらを互いに重ねて配置します。

幸運を!

于 2009-05-17T01:42:32.327 に答える
1

Graphics.CompositingModeに設定されていCompositingMode.SourceCopyますか?これにより、背景を 2 回ペイントすることは、1 回ペイントすることと同じになるはずです。これは、合成する代わりに既存のアルファ/カラー データを置き換えるためです。

于 2009-05-17T00:45:49.373 に答える