11

Text プロパティを頻繁に更新する必要がある RichTextBox がありますが、そうすると、RichTextBox がメソッド呼び出し全体で更新されるため、煩わしく「点滅」します。

メソッドが完了するまで画面の更新を一時的に抑制する簡単な方法を見つけたいと思っていましたが、Web で見つけた唯一の方法は、WndProc メソッドをオーバーライドすることです。私はこのアプローチを採用しましたが、いくつかの問題と副作用があり、デバッグも難しくなります。これを行うためのより良い方法が必要なようです。誰かがより良い解決策を教えてくれますか?

4

6 に答える 6

15

ここに完全で実用的な例があります:

    private const int WM_USER = 0x0400;
    private const int EM_SETEVENTMASK = (WM_USER + 69);
    private const int WM_SETREDRAW = 0x0b;
    private IntPtr OldEventMask;       

    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    public void BeginUpdate()
    {
        SendMessage(this.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
        OldEventMask = (IntPtr)SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
    }       

    public void EndUpdate()
    {
        SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
        SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
    }
于 2014-09-28T18:47:31.753 に答える
10

元の質問をしたところ、BoltBait で WM_SETREDRAW を使用して SendMessage() を使用するのが最も適切な回答でした。WndProc メソッドを使用するよりも副作用が少ないようで、私のアプリケーションでは LockWindowUpdate の 2 倍の速度で実行されます。

拡張された RichTextBox クラス内に、これら 2 つのメソッドを追加したところです。何らかの処理を行っているときに再描画の再開を停止する必要があるときはいつでも、これらのメソッドを呼び出します。これを RichTextBox クラスの外から実行したい場合は、"this" を RichTextBox インスタンスへの参照に置き換えるだけでうまくいくと思います。

    private void StopRepaint()
    {
        // Stop redrawing:
        SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
        // Stop sending of events:
        eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
    }

    private void StartRepaint()
    {
        // turn on events
        SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask);
        // turn on redrawing
        SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
        // this forces a repaint, which for some reason is necessary in some cases.
        this.Invalidate();
    }
于 2008-10-11T19:42:42.793 に答える
3

ここにあります: http://bytes.com/forum/thread276845.html

SendMessage を介して WM_SETREDRAW を送信し、無効にしてから再度有効にし、更新が完了した後に Invalidate() を送信することになりました。それはうまくいったようです。

この方法は試したことがありません。構文の強調表示を備えた RTB を使用してアプリケーションを作成し、RTB クラスで以下を使用しました。

protected override void WndProc(ref Message m)
{
    if (m.Msg == paint)
    {
        if (!highlighting)
        {
            base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc
        }
        else
        {
            m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems.
        }
    }
    else
    {
        base.WndProc(ref m); // message other than paint, just do what you normally do.
    }
}

お役に立てれば。

于 2008-10-10T17:58:06.513 に答える
0

Text を文字列に格納し、文字列に対して操作を行い、メソッドの最後でそれを Text プロパティに格納し直すことはできますか?

于 2008-10-10T17:50:36.747 に答える
-1

LockWindowUpdateを確認することをお勧めします


[DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true,
ExactSpelling=true, CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
于 2008-10-10T18:10:44.163 に答える
-3

これを試してください:

myRichTextBox.SuspendLayout();
DoStuff();
myRichTextBox.ResumeLayout();
于 2008-10-10T17:47:12.837 に答える