2015-04-06 4 views
4

Я пробовал использовать RichTextBox на C# и нашел, что он слишком медленный, чтобы работать с текстом тысяч строк длинного. После некоторого googling я нашел это потому, что .net по умолчанию использует RichEdit 2.0, а решение - использовать RichEdit 5.0.Использование новых версий RichEdit?

C# RichEditBox has extremely slow performance (4 minutes loading) 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 в явном виде, но и все другие версии ускользать от меня. Например, несмотря на то, что комментарий Джона Креншоу, согласно которому RichEdit 6.0 работает отлично, я не смог его использовать. Любая попытка, отличная от упомянутой выше комбинации msftedit-2.0 и 5.0, приводит к ошибке «Имя класса окна недействительно» в Application.Run(). (Программа находится на C#, но я не отмечал ее как таковой, поскольку я боялся, что эта проблема может не быть проблемой C#.) Код является почти точной копией решения в первой ссылке и выглядит следующим образом:

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 (формулировка, приведенная в сообщении в блоге, неясно), но я не могу связаться с ними. Есть ли способ исправить это, или более поздние версии confidencial?

ответ

3

У меня есть версия 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 Shared\OFFICE15\RICHED20.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 - это, конечно, флаг Big Red, вам придется изменить его, если у вас нет Office 2013 на вашем компьютере.Требование, что пользователь имеет правильную версию Office, установленную на его машине, работает только хорошо, когда у вас есть достойный контроль над машинами, на которых будет запущена ваша программа. Технически возможно использование обратного пути при сбое LoadLibrary().

Что делает эта конкретная версия и как она может быть несовместима с RichTextBox по умолчанию в панели инструментов, довольно сложно перепроектировать. Грубое предположение «более совместимо с Word». Later RichEdit versions более подходящие математические уравнения поддержки, например. Только так вы можете узнать, тщательно проверив. Лучше всего придерживаться msftedit.dll

+0

Похоже, что я получал ошибки, так как у меня не было совместимой версии MSO. Это MSO2013, но riched20.dll хранится в System32, а не в каталоге, который вы описали, и система не может найти в нем RichEdit60W. (Может быть, потому, что у меня есть восточноазиатская версия? Или, может быть, потому, что это была корпоративная покупка? Кто знает?) Угадайте, что я буду придерживаться msftedit.dll. Спасибо за подробный ввод. – dare0021

+0

Я получаю «Имя класса окна недействительно». ошибка. Не могли бы вы дать мне знать, как получить название класса? благодаря – Jerry

3

Как правило, RichEdit разрабатывается в Microsoft как часть Office, и только версии 1.0, 2.0, 3.0 и 4.1 включены в Windows в разное время.

Другие версии более поздних версий RichEdit можно найти в установках Microsoft Office: при установке Office вы должны будете явно загрузить их с места в разделе «Файлы программы». Если Office не установлен, вам не повезло: эти другие версии не присутствуют в голых Windows, и нет лицензии на перераспределение, чтобы вы могли распространять их с помощью любого подходящего для вас письма.

Итак, в основном, вам не повезло. Сожалею.