RichTextBox 选择突出显示

RichTextBox Selection Highlight

有没有可能在用户选择之后,每一个被选中的字母都显示它原来的颜色?并不总是默认的白色?

我想实现这样的目标 可以在写字板中看到。

而不是您在 RichTextBox 中看到的

您可以使用 RichTextBox 的最新版本 RICHEDIT50W,为此您应该继承标准 RichTextBox 并覆盖 CreateParams 并设置 ClassNameRICHEDIT50W:

代码

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class ExRichText : RichTextBox
{
    [DllImport("kernel32.dll", EntryPoint = "LoadLibraryW", 
        CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr LoadLibraryW(string s_File);
    public static IntPtr LoadLibrary(string s_File)
    {
        var module = LoadLibraryW(s_File);
        if (module != IntPtr.Zero)
            return module;
        var error = Marshal.GetLastWin32Error();
        throw new Win32Exception(error);
    }
    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            try
            {
                LoadLibrary("MsftEdit.dll"); // Available since XP SP1
                cp.ClassName = "RichEdit50W";
            }
            catch { /* Windows XP without any Service Pack.*/ }
            return cp;
        }
    }
}

截图

注:

  • 我可以使用 Spy++ 看到写字板 RichTextBox 的 class 多亏了这个古老的有用 visual studio 工具。

  • 如果您对 os 中的 RICHEDIT50W 有任何问题,您可以打开 Spy++WordPad 然后 select它的 RichTextBox 并查看 class 名称是什么。

  • 当我搜索有关将 RICHEDIT50W class 应用到我的控件时,我找到了 @Elmue 的 this 伟大的 post,感谢他。

对于 Hunar 评论中提到的 Visual Studio 2019 和异常“Class 已经存在”有问题的任何人,我稍微修改了代码以仅加载一次库,这为我解决了问题。

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[DesignerCategory("Code")]
public class RichTextBox5 : RichTextBox
{
    [DllImport("kernel32.dll", EntryPoint = "LoadLibraryW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr LoadLibraryW(string s_File);

    private static readonly object libraryLoadLock = new object();
    private static bool libraryLoadFlag;

    public static IntPtr LoadLibrary(string s_File)
    {
        var module = LoadLibraryW(s_File);
        if (module != IntPtr.Zero)
        {
            return module;
        }
        var error = Marshal.GetLastWin32Error();
        throw new Win32Exception(error);
    }

    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            try
            {
                lock (libraryLoadLock)
                {
                    if (!libraryLoadFlag)
                    {
                        LoadLibrary("MsftEdit.dll"); // Available since XP SP1
                        libraryLoadFlag = true;
                    }
                }
                cp.ClassName = "RichEdit50W";
            }
            catch { /* Windows XP without any Service Pack.*/ }
            return cp;
        }
    }
}

很抱歉以这种方式回答,但由于声誉点数不足,我只能post回答。