お世話になっております。
XP,Delphi2007です。
Memoで、縦位置を中央揃えすることはできますか?
例えば、縦サイズが大きいMemoに文字を入力する場合、Memoの縦位置の中央で入力できるようにしたいです。
よろしくお願いします。
Memoって書きましたが、RichEditでも同じように縦位置を中央揃えしたいです。
よろしくお願いします。
コントロールにEM_SETRECTを送ると編集領域の位置や大きさを設定できるので
文字列が中央にくるように変更してやればよいかと。
と言っても文字列のサイズを求めるのがちょっと面倒そうですけれど、とりあえずやっつけで……
type
TDummyMemo = class(TCustomMemo); // TCustomMemoのprotectedプロパティにアクセスするのに使う
procedure TForm1.vcenter_memo(memo: TCustomMemo);
var
rc: TRect;
tmp_canvas: TCanvas;
line_count, char_index: Integer;
y_start, y_end: Integer;
hi: Integer;
begin
// 現在の文字列の高さを計算
tmp_canvas := Canvas; // 文字サイズを求めるためTForm.Canvasを借りる
tmp_canvas.Font.Assign(TDummyMemo(memo).Font);
if memo is TRichEdit then
begin
// 段落ごとにフォントが異なっていたりすると単純には計算できないので
// 文字の座標を問い合わせ、そこから全体の高さを求める
line_count := memo.Perform(EM_GETLINECOUNT, 0, 0);
char_index := memo.Perform(EM_LINEINDEX, line_count - 1, 0);
y_start := HIWORD(memo.Perform(EM_POSFROMCHAR, 0, 0)); // 最初の行のY座標を...
y_end := HIWORD(memo.Perform(EM_POSFROMCHAR, char_index, 0)); // 最後の行のY座標から引いて...
hi := y_end - y_start + tmp_canvas.TextHeight(' '); // さらに最後の行の高さを足す
end
else // TMemoの場合
begin
// memo.Lines.Countだと最後の行が空白の時に正しく計算できないので
// EM_GETLINECOUNTで問い合わせる
hi := tmp_canvas.TextHeight(' ') * memo.Perform(EM_GETLINECOUNT, 0, 0);
end;
// テキストが中央にくるよう、編集領域の範囲を計算
rc := memo.ClientRect;
rc.Top := (rc.Top + rc.Bottom - hi) div 2;
rc.Bottom := rc.Top + hi;
// 境界線の分を引いておく
// TRichEditだと、BorderStyleにかかわらず引いておかないといけないみたい
InflateRect(rc, 0, GetSystemMetrics(SM_CYEDGE));
// 領域を設定する
memo.Perform(EM_SETRECT, 0, LParam(@rc));
end;
こんな感じのメソッドを作って、OnChangeとかOnResizeのタイミングで呼んでみてはどうでしょう。
ありがとうございます。
OnChangeから、教えていただいたメソッドを呼び出して、思い通りになりました。
ありがとうございました。
ツイート | ![]() |