旧バージョンのTRichEditで一部文字が文字化けする
対象となるバージョン
- Delphi 3 ~ XE7
問題
- IDEを利用しているWindows環境において、システムロケールとユーザーロケールの両方を"日本語"に設定し、アプリケーションをビルドしている
- TRichEditで表示する文字として「申」「貼」など、Shift-JISで下位バイトが$53('\')になっている漢字を含んでいる
- TRichEdit.Font.CharSetプロパティが”DEFAULT_CHARSET”である
- TRichEdit.PlainTextプロパティがFalseである
- アプリケーション実行時に、TRichEditのフォントサイズを変更し、RecreateWndメソッド等を呼び出してウィンドウハンドルの再生成が発生している
上記5つの条件を満たすと、以下の図のようにTRichEditで文字化けが発生します。
上図は、”フォントサイズの変更”というボタンを実行すると、「申」という漢字の後続の文字が化ける例です。
解決
この症状は、XE8以降のバージョンで修正されています。XE8以前のバージョンで本件を解決するためには、以下のいずれかの方法で対処が必要です。
- TRichEdit.Font.CharSetプロパティを"SHIFTJIS_CHARSET"へ変更する
- Vcl.ComCtlsユニットのTCustomRichEdit.CreateWndメソッド内で定義している日本語ロケールの判定コードをコメントアウトし、修正したVcl.ComCtlsユニットを自身のプロジェクトへ組み込む
以下は、2の方法を選択した場合の修正例です。
<<修正前>>
procedure TCustomRichEdit.CreateWnd;
var
DesignMode: Byte;
Plain, WasModified: Boolean;
begin
WasModified := inherited Modified;
inherited CreateWnd;
if (SysLocale.FarEast) and not (SysLocale.PriLangID = LANG_JAPANESE) then
Font.Charset := GetDefFontCharSet;
SendMessage(Handle, EM_SETEVENTMASK, 0,
ENM_CHANGE or ENM_SELCHANGE or ENM_REQUESTRESIZE or
ENM_PROTECTED);
SendMessage(Handle, EM_SETBKGNDCOLOR, 0, ColorToRGB(Color));
…
…
<<修正後>>
procedure TCustomRichEdit.CreateWnd;
var
DesignMode: Byte;
Plain, WasModified: Boolean;
begin
WasModified := inherited Modified;
inherited CreateWnd;
//if (SysLocale.FarEast) and not (SysLocale.PriLangID = LANG_JAPANESE) then
Font.Charset := GetDefFontCharSet;
SendMessage(Handle, EM_SETEVENTMASK, 0,
ENM_CHANGE or ENM_SELCHANGE or ENM_REQUESTRESIZE or
ENM_PROTECTED);
SendMessage(Handle, EM_SETBKGNDCOLOR, 0, ColorToRGB(Color));
…
…