我曾尝试在C#上使用RichTextBox,但发现它太慢了,无法处理数千行长的文本。经过谷歌搜索,我发现这是因为.net默认使用RichEdit 2.0,而解决方案是使用RichEdit 5.0。
C#RichEditBox的性能非常慢(加载4分钟)SOLVED
它工作得很好,文本显示的时间是几秒钟而不是几分钟。然而,作为一个不关心个人项目兼容性的人,我想找到更高版本的RichEdit。我发现最新版本是8.0,全部以riched20.dll的形式提供,部分以msftedit.dll的形式提供。
http://blogs.msdn.com/b/murrays/archive/2006/10/14/richedit-versions.aspx
http://blogs.msdn.com/b/murrays/archive/2012/03/03/richedit-8-0-preview.aspx
然而,msdn的文档以4.1结尾,项目的开发人员(我认为他是)声称他们不再在上面的博客中做公共文档。
https://msdn.microsoft.com/en-us/library/windows/desktop/bb787873(v=vs.85).aspx
到目前为止,我已经能够显式运行msftedit.dll的RichEdit 2.0和5.0,但所有其他版本都无法运行。例如,尽管John Crenshaw的评论声称RichEdit 6.0运行良好,但我一直无法使用它。除了上面提到的msftedit-2.0和5.0组合之外的任何尝试都会在Application.Run()中导致"Window类名无效"错误
class Textbox : 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)
{
IntPtr h_Module = LoadLibraryW(s_File);
if (h_Module != IntPtr.Zero)
return h_Module;
int s32_Error = Marshal.GetLastWin32Error();
throw new Exception("LoadLibrary Failed with: "+s32_Error);
}
protected override CreateParams CreateParams
{
get
{
CreateParams i_Params = base.CreateParams;
try
{
// Available since XP SP1
LoadLibrary("MsftEdit.dll"); // throws
i_Params.ClassName = "RichEdit50W";
}
catch
{
// Windows XP without any Service Pack.
}
return i_Params;
}
}
我所做的是将ClassName字符串更改为不同的数字,例如RichEdit60W。
我使用的是Windows 8.1,所以msftedit.dll的RichEdit 7.0或8.0版本(博客文章中给出的措辞不清楚),但我无法联系到它们。有什么方法可以纠正这一点吗?或者新版本是保密的吗?
我的机器上有RichEdit 8.0版本,类名为RICHEDIT60W。它存储在C:\Program Files(x86)\Common Files\Microsoft Shared\OFFICE15\RICHED20.DLL中。当我为它编写包装器时,它工作得很好:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.ComponentModel;
class RichEdit80 : RichTextBox {
protected override CreateParams CreateParams {
get {
if (moduleHandle == IntPtr.Zero) {
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFilesX86);
path = System.IO.Path.Combine(path, @"Microsoft SharedOFFICE15RICHED20.DLL");
moduleHandle = LoadLibrary(path);
if ((long)moduleHandle < 0x20) throw new Win32Exception(Marshal.GetLastWin32Error(), "RichEdit control appears to be missing");
}
CreateParams createParams = base.CreateParams;
createParams.ClassName = "RichEdit60W";
if (this.Multiline) {
if (((this.ScrollBars & RichTextBoxScrollBars.Horizontal) != RichTextBoxScrollBars.None) && !base.WordWrap) {
createParams.Style |= 0x100000;
if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
createParams.Style |= 0x2000;
}
}
if ((this.ScrollBars & RichTextBoxScrollBars.Vertical) != RichTextBoxScrollBars.None) {
createParams.Style |= 0x200000;
if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
createParams.Style |= 0x2000;
}
}
}
if ((BorderStyle.FixedSingle == base.BorderStyle) && ((createParams.Style & 0x800000) != 0)) {
createParams.Style &= -8388609;
createParams.ExStyle |= 0x200;
}
return createParams;
}
}
private static IntPtr moduleHandle;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr LoadLibrary(string lpFileName);
}
未彻底测试。希望您对这段代码感到非常不舒服,它实际上只足以用于测试目的,看看您是否领先。DLL的路径当然是大红旗,当你的机器上没有Office 2013时,你必须更改它。要求用户在其计算机上安装正确的Office版本,只有当您对要运行程序的计算机有良好的控制时,才能正常工作。在LoadLibrary()失败时使用回退路径在技术上是可行的。
这个特定版本的功能以及它可能与工具箱中默认的RichTextBox不兼容的方式很难进行逆向工程。粗略的猜测是"与Word更兼容"。例如,后来的RichEdit版本更好地支持数学方程式。唯一能找到答案的方法就是彻底测试。最好使用msftedit.dll
RichEdit似乎主要是在微软作为Office的一部分开发的,在不同的时间,Windows中只包含1.0、2.0、3.0和4.1版本。
其他更高版本的RichEdit可以在Microsoft Office安装中找到:如果安装了Office,则必须从"程序文件"下的位置显式地加载库()。如果没有安装Office,你就倒霉了:这些其他版本在裸Windows中不存在,而且没有重新分发许可证允许你用你写的任何合适的软件来分发它们。
所以,基本上,你运气不好。很抱歉