2013-09-07 16 views
13

C#のコントロールRichEditBox(私はVS 2005を使用しています)のパフォーマンスが悪いです。 45.000色のテキスト行を含む2.5 MBのRTFファイルをコントロールに読み込み、4分かかります。私は同じRTFをWindows XPのワードパッドのRTFコントロールにロードし、2秒でロードします。C#RichEditBoxのパフォーマンスが極端に遅い(読み込み時間が4分)

ワードパッドは私のアプリケーションよりも120倍高速です。

理由は何ですか。どのように修正できますか?

答えて

20

ワードパッドのソースコード(http://download.microsoft.com/download/4/0/9/40946FEC-EE5C-48C2-8750-B0F8DA1C99A8/MFC/ole/wordpad.zip.exe)をダウンロードしたところ、最悪のパフォーマンス(4分)は同じでした。しかし、このサンプルは古いバージョンのワードパッドです。

マイクロソフトでは、.NETフレームワークにない最後の年にワードパッドで何かを改善しました。

は最後に、私は解決策を見つけた:

古いワードパッドがないとしても、.NETフレームワークは、リッチエディットコントロールのためのRichEdit20Wクラスを使用しています。しかし、Windows XPのワードパッドは、Microsoftによって大幅に改良された新しいRichEdit50Wを使用しています。

.NET FrameworkにRichEdit20Wの代わりにRichEdit50Wを使用するように指示するにはどうすればよいですか?

これは非常に簡単です:RichTextBoxからクラスを派生させ、LoadLibaryのマネージラッパーを記述します。

RichEdit50Wクラスは、Windows XP SP1以降で使用可能なMsftEdit.dllによって作成されます。非常にまれなケースのためにRichEdit20Wにフォールバックを実装しましたが、サービスパックなしでXPを使用する必要があります。

これは機能します。

/// <summary> 
/// The framework uses by default "Richedit20W" in RICHED20.DLL. 
/// This needs 4 minutes to load a 2,5MB RTF file with 45000 lines. 
/// Richedit50W needs only 2 seconds for the same RTF document !!! 
/// </summary> 
protected override CreateParams CreateParams 
{ 
    get 
    { 
     CreateParams i_Params = base.CreateParams; 
     try 
     { 
      // Available since XP SP1 
      Win32.LoadLibrary("MsftEdit.dll"); // throws 

      // Replace "RichEdit20W" with "RichEdit50W" 
      i_Params.ClassName = "RichEdit50W"; 
     } 
     catch 
     { 
      // Windows XP without any Service Pack. 
     } 
     return i_Params; 
    } 
} 

注:またhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb787873%28v=vs.85%29.aspx

public class Win32 
{ 
    [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 Win32Exception(s32_Error); 
    } 
} 
+0

あなたは20Wの上にRichEdit50Wで他に何が改善されている知っていますか?自分のプログラムにコードを使用しようとしましたが、違いは気付きません。 –

+0

これをテストするために、何千もの行を含む大きなRTFテキストを読み込みましたか? SysInternals ProcessExplorerを使用して、コードに変更を加えた場合としない場合のどちらのDLLがプロセスに読み込まれているか確認しましたか?私はそれが常に同じDLLをロードすると思います。大きな違いがあるはずです。コードが実行されたかどうかを確認するためにブレークポイントを設定しましたか? – Elmue

+0

はい、4000行以上の4MBファイルです。どちらも20Wと50Wのバージョンでどちらも0.3秒未満でロードされました。一般的なスクロールと操作はすばやく表示されます。私はMessageBox.Show()を使って '' RichEdit50W 'になる前に 'i_Params.ClassName'のバージョンを表示し、期待通りに" RichEdit20W "でした。 –

関連する問題