如何防止RichTextBox刷新其显示

本文关键字:显示 刷新 RichTextBox 何防止 | 更新日期: 2023-09-27 17:48:48

我有一个RichTextBox,需要经常更新Text属性,但当我这样做时,RichTextBox会"闪烁",因为它在整个方法调用中都会刷新。

我希望找到一种简单的方法来暂时抑制屏幕刷新,直到我的方法完成,但我在网上找到的唯一一件事就是覆盖WndProc方法。我采用了这种方法,但有一些困难和副作用,而且它也使调试更加困难。似乎必须有更好的方法来做到这一点。有人能给我指一个更好的解决方案吗?

如何防止RichTextBox刷新其显示

以下是完整的工作示例:

    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);
    }

我问了最初的问题,最适合我的答案是BoltBait在WM_SETREDRAW中使用SendMessage()。它似乎比使用WndProc方法有更少的副作用,而且在我的应用程序中,它的执行速度是LockWindowUpdate的两倍。

在我的扩展RichTextBox类中,我只添加了这两个方法,每当我在进行一些处理时需要停止重新开始绘制时,我就会调用它们。如果我想在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();
    }

在此处找到: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.
    }
}

希望这能有所帮助。

您可以将Text存储到一个字符串中,对该字符串进行操作,然后在方法结束时将其存储回Text属性中吗?

我建议查看LockWindowUpdate


[DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true,
ExactSpelling=true, CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]

试试这个:

myRichTextBox.SuspendLayout();
DoStuff();
myRichTextBox.ResumeLayout();