RichEditのタブ幅を設定
プログラムのソースコードを見るときにタブ幅を変えられないとちょっと困るのでリッチエディットのタブ幅を設定してみようというページ。
表形式のデータを桁を揃えてレイアウトするような目的ではなく、単純にテキストのタブ幅を揃えて表示させたいわけです。
参考サイト
EM_SETPARAFORMATメッセージ
もっとちゃんとしたやり方があるのかも知れませんが、リッチエディットのテキストを全選択してからEM_SETPARAFORMATメッセージを送る方法を取ります。
CreateWindowW APIで作成したUnicode対応のRichEditではEM_SETTABSTOPSメッセージを送ることで実現できたのですがD6のVCLのTRichEditではだめなようです。
procedure TForm1.MenuItem_Tab8Click(Sender: TObject);
var
l_Tab: Integer;
begin
l_Tab := TMenuItem(Sender).Tag * 4;
SendMessage(RichEdit1.Handle, EM_SETTABSTOPS, WPARAM(1), LPARAM(@l_Tab)); //VCLのTRichEditでは変化なし
end;
RichEditには色々なバージョンがあるようでそのへんの問題なのかなぁというところです。
それではというのでEM_SETPARAFORMATメッセージを送るやり方でやってみたところ単純にメッセージを送っただけではだめなようです。
タブ幅をセットしてメッセージを送った後に入力したテキストのタブ幅はセット後のタブ幅なのですが、タブ幅をセットする以前のテキストは元のタブ幅のままでした。
表形式のデータを桁を揃えて表示させる場合等であればそれもいいのでしょうが、単純にプログラムのソースコードのタブ幅を揃えたい場合にはこれでは困ります。
ということで色々やってみた結果RichEditのテキストを全選択状態にしてからEM_SETPARAFORMATメッセージを送ることで実現できました。
procedure TForm1.MenuItem_Tab8Click(Sender: TObject);
//タブの設定
//http://www13.plala.or.jp/kmaeda/winc/rich_tab.htm
//http://ja.wikipedia.org/wiki/Twip
var
l_MenuItem : TMenuItem;
li_Tab : Integer;
l_Param : TParaFormat;
li_Pos : Integer;
i : Integer;
begin
l_MenuItem := TMenuItem(Sender);
l_MenuItem.Checked := True;
FillChar(l_Param, SizeOf(l_Param), 0);
l_Param.cbSize := SizeOf(l_Param);
l_Param.dwMask := PFM_TABSTOPS;
l_Param.cTabCount := High(l_Param.rgxTabs) +1;
//TParaFormatのタブ幅は単位はtwipsなので画面表示用に計算。
li_Tab := l_MenuItem.Tag * Abs(RichEdit1.Font.Size) * 20 div 2; //半角スペースの幅をFont.Sizeの半分とするので2で割る
for i := 0 to High(l_Param.rgxTabs) do
begin
l_Param.rgxTabs[i] := li_Tab * (i+1);
end;
//カーソル位置を保存。
li_Pos := RichEdit1.SelStart;
RichEdit1.SelectAll;
//タブ幅セット。
SendMessage(RichEdit1.Handle, EM_SETPARAFORMAT, 0, LPARAM(@l_Param));
//カーソル位置を復元。
RichEdit1.SelStart := li_Pos;
end;
ファイルを読み込み
タブ幅をセットしてファイルを読み込む場合は一旦テキストをクリアしてタブ幅をセットしてから読み込まないとうまく行きません。
procedure TForm1.Button1Click(Sender: TObject);
begin
if (OpenDialog1.Execute) then
begin
try
RichEdit1.Clear;
MenuItem_Tab8Click(nil);
RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
except
ShowMessage(Format('%s'#13'読み込みエラー', [OpenDialog1.FileName]));
end;
end;
end;
procedure TForm1.MenuItem_Tab8Click(Sender: TObject);
//タブの設定
//http://www13.plala.or.jp/kmaeda/winc/rich_tab.htm
//http://ja.wikipedia.org/wiki/Twip
var
l_MenuItem : TMenuItem;
li_Tab : Integer;
l_Param : TParaFormat;
li_Pos : Integer;
i : Integer;
begin
if not(Sender is TMenuItem) then
begin
l_MenuItem := nil;
for i := 0 to MenuItem_Tab.Count -1 do
begin
if (MenuItem_Tab.Items[i].Checked) then
begin
l_MenuItem := MenuItem_Tab.Items[i];
Break;
end;
end;
if (l_MenuItem = nil) then
begin
Exit;
end;
end else
begin
l_MenuItem := TMenuItem(Sender);
l_MenuItem.Checked := True;
end;
FillChar(l_Param, SizeOf(l_Param), 0);
l_Param.cbSize := SizeOf(l_Param);
l_Param.dwMask := PFM_TABSTOPS;
l_Param.cTabCount := High(l_Param.rgxTabs) +1;
//TParaFormatのタブ幅は単位はtwipsなので画面表示用に計算。
li_Tab := l_MenuItem.Tag * Abs(RichEdit1.Font.Size) * 20 div 2; //半角スペースの幅をFont.Sizeの半分とするので2で割っている
for i := 0 to High(l_Param.rgxTabs) do
begin
l_Param.rgxTabs[i] := li_Tab * (i+1);
end;
//カーソル位置を保存。
li_Pos := RichEdit1.SelStart;
RichEdit1.SelectAll;
//タブ幅セット。
SendMessage(RichEdit1.Handle, EM_SETPARAFORMAT, 0, LPARAM(@l_Param));
//カーソル位置を復元。
RichEdit1.SelStart := li_Pos;
end;
2011-11-26: