開発環境Delphi7
表題の件ですが文字数に対するEdit.Widthの値を算出したいですが
なにかよい方法はないでしょうか、
VBの場合はLableにBorderを設定して算出していたのですが
Delphi7では無理みたいです。
文字数に対するEdit.Widthの算出式を導く方法はないのでしょうか
尚,Font:MSゴシック,Size:9,Pitch:Default,BorderStyle:single,Ctl3d:true
です。
Canvasのフォントを指定してTextHeight,TextWidthで判定出来ませんか。
めじなさんご回答ありがとうございます。
>Canvasのフォントを指定してTextHeight,TextWidthで判定出来ませんか
方法がわかりません
Canvasてなんですか、プロパティorオブジェクトなんでしょうか
フォームのプロパティ
Helpに書いてない?
真琴:「Canvas知らないナンて、ホントに初心者なんだね、このヒト」
春子:「Delphiは初心者、でもVBはケッコウ出来るみたいじゃない?」
真琴:「だけどハルコさん、TextWidthを使うにもぉ、EditにはCanvasないでしょ?」
春子:「Canvasならナンでもイイんだから仮に自分で作るのよ、マコト」
真琴:「え?そうなの?でもEditのFont変えてもそれで大丈夫?」
春子:「作ったCanvasのFontと、EditのFontを同じにしとけばOKよ」
真琴:「そっか、じゃぁ、これでイイかな?」
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Font.Size := 12;
Edit1.Font.Name := 'MS ゴシック';
with TCanvas.Create do try
Font.Assign(Edit1.Font);
Edit1.Width := TextWidth(Edit1.Text)+7;
finally
Free;
end;
end;
真琴:「あれ? 実行したら'Canvasに対する描画ができません'てエラー、ナンで?」
春子:「HDCがナイんだもん、仮のHDCでもCanvasのHandleに入れとかなきゃ」
真琴:「また、仮のモノ入れるの?」
広海:「マコトも仮のモノ入れてオッパイ膨らませばもっとモテルんじゃないの〜?」
真琴:「バァ〜ッカ」
春子:「それは、ホンモノで勝負しなきゃネェ〜」
procedure TForm1.Button1Click(Sender: TObject);
var
Dummy: HWND; // 追加
begin
Edit1.Font.Size := 12;
Edit1.Font.Name := 'MS ゴシック';
with TCanvas.Create do try
Handle := GetDeviceContext(Dummy); // 追加
Font.Assign(Edit1.Font);
Edit1.Width := TextWidth(Edit1.Text)+7;
finally
Free;
end;
end;
真琴:「カイトさんは、もう病院に着いたかなぁ…」
広海:「クルマの調子が悪くなけりゃ、オレが病院まで送ってやれたんだけどね」
真琴:「サクラさん大丈夫だよね…、きっと病気軽いよね」
春子:「次の日曜に皆でサクラさんのお見舞いに行こ…ね? マコト」
真琴:「うん」
理論的に算出式はないのでしょうか
上の回答の方法が理論的でなくて、「LableにBorderを設定して算出」する方法が理論的であると言う理屈が分からないけど、等幅の"MS ゴシック"FONTに限って言うならば、
文字幅は ((Round(Font.Size * Font.PixelsPerInch / 72) + 1) and $FFFE) div 2
これはDelphiもVBも関係ない。もちろん、この計算式は等幅でないプロポーショナルFONTでは無意味。
ちゃんとやろうとすると面倒です。
しかもTCanvas使わないとなるとWin32APIの直叩きですよ。
やってることは同じですがこんな感じになります。
procedure TForm1.Button1Click(Sender: TObject);
var
wRect,cRect:TRect;
wmgn,hmgn:Integer;
aSize:TSize;
fString:String;
fhBuffer,fhdc:HWND;
apos:TPoint;
begin
fString:=Edit1.Text;
Windows.GetWindowRect(Edit1.Handle,wRect);
Windows.GetClientRect(Edit1.Handle,cRect);
wmgn:= (wRect.Right-wRect.Left)-(cRect.Right-cRect.Left);
hmgn:= (wRect.Bottom-wRect.Top)-(cRect.Bottom-cRect.Top);
fhdc:= GetDC(Handle);
fhBuffer := CreateCompatibleDC(fhdc);
SelectObject(fhBuffer, Edit1.Font.Handle);
Windows.GetTextExtentPoint32(fhBuffer, PChar(fString), Length(fString), aSize);
DeleteDC(fhdc);
DeleteDC(fhBuffer);
apos:=Point(wRect.Left,wRect.Top);
apos:=ScreenToClient(apos);
SetWindowPos(Edit1.Handle,0,apos.X,apos.Y,aSize.cx+wmgn,aSize.cy+hmgn,
SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOZORDER);
Caption:=IntToStr(aSize.cx+wmgn);
end;
GSXR750さんの質問内容は,等倍フォントで,
「文字数に対する」とあります.したがって,2008/06/11(水) 22:50:17のレスの
方法で可能でしょう.これが理論といえば理論です.
「ビーチボーイズ」の仲間と他の方のレスでTCanvasを使用した例は,
通常,「文字の数」から文字列全体の幅を求めるということはしないからでしょう.
それよりも,文字列全体の長さ(幅)の情報を何かに利用することが考えられるからです.
この方法なら,プロポーショナルフォントにも適用可能です.
つまり,文字の数(が必要なときもありますが)よりも,文字列の幅が重要ということです.
釈迦に説法となりますが,プロポーショナルフォントでこの文字列の幅を,
1つ1つの文字幅から算出するのは,非常に困難です.
TCanavsを使用した手順なら,自動的にやってくれます.利用しない手はありません.
フォントの幅の算出が面倒な理由の参考
http://www.winapi-database.com/Graphics/Font/
これはDelphiに限ったことではありません.他の言語でも同じです.
そんなことはない!!
VBならと言いたいですか〜! (アントニオ猪木の「元気ですか〜」調で)
>VBの場合はLableにBorderを設定して算出していたのですが
>Delphi7では無理みたいです。
Borderが設定できるって事は TLabel じゃなくて
TStaticText じゃないのかな?(自前で描画してるかもしれんけど)
そうなの?さんの式だと出てくるのは文字の幅じゃなくて高さじゃないでしょうか。
質問者さんがやりたいことは、N文字入力した時に文字がはみ出さない
最小のEditの幅を求めること、だと思われます。
だとすると「理論的に」求めるとしたら、TEXTMETRICを取得して
MaxCharWidthを使うという手もありそうですね。
単純に・・・・
TStaticText(AutoSize)を非表示で持たせて、editと同じフォントにして
値をTStaticTextにセットした後でWidthを取ればいいのでは?
ツイート | ![]() |