すべての更新を実行するまで、フォームの再描画を一時停止できますか?

StackOverflow https://stackoverflow.com/questions/615781

質問

C#と.Net 2.0を使用して、不規則な形状のフォーム(TransparencyKey、FormBorderStyle = Noneなど)を使用しており、「通常」を許可したいボーダー付きモード。

背景色をLimeからデフォルトに変更します FormBorderStyleをFixedSingleに変更します TransparencyKeyをColour.Noneに変更します

残念ながら、これは画面上で完全に混乱しているように見えます。画像は数ピクセル下にジャンプして、ライムグリーンの形になります。

これは、コードの各行の後にフォームが再描画されることが原因だと思いますが、変更を加えるまでフォームの描画を一時停止し、一度だけフォームを再描画することは可能ですか?

G

役に立ちましたか?

解決

新しい回答:新しいウィンドウプロパティを適用している間、WndProcをオーバーライドし、WM_PAINTメッセージをブロックします。

古い回答:WndProcをオーバーライドし、 WM_ERASEBKGND メッセージをブロックします。

以下のコードの機能の説明:

ウィンドウの領域が無効化されると、Windowsはコントロールに一連のメッセージを送信し、その結果、新しくペイントされたウィジェットが作成されます。このシリーズの初期のメッセージは WM_ERASEBKGND です。通常、このメッセージに応じて、コントロールはそれ自体を単色で塗りつぶします。後で、 WM_PAINT メッセージ(通常はOnPaintイベントで消費される)への応答で、実際の描画が行われます。この描画が重要でない場合、ウィジェットが更新されるまでに遅延が発生し、迷惑なちらつきが発生します。

もう一度コードを見ると、明らかに別の問題を解決していました。この新しい例を試してください。 bAllowPaint フラグが設定されていない場合、フォーム/コントロールの描画をブロックします。

NEW の例:

    private const int WM_PAINT = 0x000F;

    protected override void WndProc(ref Message m)
    {
        if ((m.Msg != WM_PAINT) ||
            (bAllowPaint && m.Msg == WM_PAINT))
        {
            base.WndProc(ref m);
        }
    }

OLD の例:

    private const int WM_ERASEBKGND = 0x0014;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg != WM_ERASEBKGND) // ignore WM_ERASEBKGND
        {
            base.WndProc(ref m);
        }
    }

他のヒント

Form.DoubleBufferedプロパティを試してください。 「true」に設定します。

また、フォームに子コントロールがある場合は、それらについてもDoubleBufferedをtrueに設定します(そして子の子など)。

最後に、変更の前にSuspendLayoutを呼び出し、その後でResumeLayoutを呼び出します。これは子コントロールの配置にのみ影響することに注意してください。カスタム描画を行う場合は、DoubleBufferedプロパティを使用すると、より大きな価値が得られます。

フォームにかなり大きな影響を及ぼすプロパティを変更しています。 TransparencyKeyとFormBorderStyleでは、ウィンドウスタイルビットを変更する必要があります。 Windowsでは、これらのスタイルビットを変更することはできません。 Windows Formsは、ウィンドウを完全に破棄し、ゼロから再作成することで実装します。きちんとしたトリックですが、それには時間がかかり、スタイルを変更するたびにフォームが再描画されます。不快な視覚効果を引き起こす。

これを試してください: 1. Opacityを0に設定して、フォームを非表示にします 2. BackColorの変更、問題なし 3. FormBorderStyleを変更すると、ウィンドウが再作成されます 4. TransparencyKeyを変更すると、ウィンドウが再作成されます 5.不透明度を1に変更すると、ウィンドウが再作成されて表示されます

例:

  this.Opacity = 0;
  this.BackColor = Color.FromKnownColor(KnownColor.Control);
  this.FormBorderStyle = FormBorderStyle.Sizable;
  this.TransparencyKey = Color.Empty;
  this.Opacity = 1;

すべてが失敗した場合は、フォームへのすべてのペイントメッセージをブロックすることにより、低レベルのハッキングを試みることができます。

警告:この方法の使用は推奨していませんが、本当にやりたい場合は試してください。過去に私を助けてくれました。

Win32.LockWindowUpdate(this.Handle);
try
{
   //make your changes here
}
finally
{
  //release the lock
  Win32.LockWindowUpdate((IntPtr)0);
}

このコードは、次のサポートコードに依存しています。

public class Win32
{
  private Win32() { }

    /// <summary>
    /// Lock ore relase the wndow for updating.
    /// </summary>
    [DllImport("user32")]
    public static extern int LockWindowUpdate(HWND hwnd);
 }

すべての&quot; image&quot;を送信する方法フォームの画面への1ステップでのDoubleBufferの有効化です。

コンストラクターでControlStylesを設定できます

VB.NET:

SetStyle(ControlStyles.DoubleBuffer, True)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top