尝试在RichTextBox中调整图像大小时,光标闪烁

时间:2015-08-31 05:17:07

标签: c# winforms richtextbox

我希望这是一个简单的问题。我做了以下事情:

  1. 在VS2010中,我创建了一个Windows窗体应用程序
  2. 从“工具箱”中,将RichTextBox控件拖到窗体
  3. 将表单和RichTextBox控件的大小调整到足以显示小图片。
  4. 运行(开始调试)。
  5. 从网络浏览器复制一张小图片并粘贴到richtextbox(使用ctrl-v)。
  6. 在richtextbox中选择图像。显示带有小方框的调整大小框架。
  7. 现在,当我将光标放在一个小的缩放器框上时,光标会闪烁。我看到调整大小箭头光标的瞥见,但大多数时候它显示工字梁光标。当图片被粘贴到写字板并且光标放在其中一个小调整大小框上时,它不能像箭头一样稳定地显示箭头光标。应该在RichTextBox中调整图片大小的行为与写字板中的相同吗?如何阻止光标闪烁?

3 个答案:

答案 0 :(得分:1)

这是2018年,这个问题仍在发生......

这不是最好的,但我创建了一个解决方法。我相信我们可以改进这段代码---也许将来我自己做。

您需要继承RichTextBox,然后添加以下内容以强制Cursor成为它应该是什么。

请注意,Cursor对于对象Cross,对于图片来说是I-Beam

工作原理:

  1. 每次RichTextBox请求光标更改(SetCursor)时,我们都会拦截它并检查对象是否为Selected

  2. 如果为true,则更改Cross的光标。如果为false,则将其更改为I-Beam

  3. class RichTextBoxEx : RichTextBox
    {
        private const int WM_SETCURSOR = 0x20;
    
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern IntPtr SetCursor(IntPtr hCursor);
    
        protected override void WndProc(ref Message m) {
            if (m.Msg == WM_SETCURSOR) 
            {
                if (SelectionType == RichTextBoxSelectionTypes.Object) 
                {
                    // Necessary to avoid recursive calls
                    if (Cursor != Cursors.Cross) 
                    {
                        Cursor = Cursors.Cross;
                    }
                }
                else 
                {
                    // Necessary to avoid recursive calls
                    if (Cursor != Cursors.IBeam) 
                    {
                        Cursor = Cursors.IBeam;
                    }
                }
    
                SetCursor(Cursor.Handle);
                return;
            }
    
            base.WndProc(ref m);
        }
    }
    

答案 1 :(得分:1)

使用此 hack ,您将能够调整图像的大小而不会闪烁,并且使用正确的Arrows Cursors

如何

首先,您需要继承RichTextBox的子类并覆盖方法WndProc,因此,当RichTextBox收到更改其Cursor的消息时,我们将检查是否选择图像---好吧,我真的不知道是否是Image,但是它是Object而不是Text

如果选择了Image,我们会将message重定向到DefWndProc ---这是默认窗口过程。

代码:

public class RichTextBoxEx : RichTextBox
{
    private const int WM_SETCURSOR = 0x20;

    protected override void WndProc(ref Message m) 
    {
        if (m.Msg == WM_SETCURSOR) 
        {
            if (SelectionType == RichTextBoxSelectionTypes.Object) 
            {
                DefWndProc(ref m);
                return;
            }
        }

        base.WndProc(ref m);
    }
}

答案 2 :(得分:0)

使用以下属性

/// <summary>
/// The Lower property CreateParams is being used to reduce flicker
/// </summary>
protected override CreateParams CreateParams
{
    get
    {
        const int WS_EX_COMPOSITED = 0x02000000;
        var cp = base.CreateParams;
        cp.ExStyle |= WS_EX_COMPOSITED;
        return cp;
    }
}

我已经回答here