如何得到RichEdit中某一行字符的总宽度?(100分)

  • 主题发起人 主题发起人 面条
  • 开始时间 开始时间

面条

Unregistered / Unconfirmed
GUEST, unregistred user!
RichEdit不自动换行,求文字的实际宽度。
这一行中可能包含多种字体
 
用leadbyte判断是否为汉字, 汉字和西文字母分别计数,遇到回车换行停止计数
不就行了吗
 
to Nutty:面条问的是该行占多少像素。:-)
 
可否这样,
LineIndex 为你的行号,
charIndex :=
SendMessage(aRichEdit.Handle, EM_LINEINDEX, LineIndex, 0);
i := SendMessage(aRichEdit.Handle, EM_POSFROMCHAR, charIndex, 0);
j := SendMessage(aRichEdit.Handle, EM_POSFROMCHAR,
charIndex + Length(aRichEdit.Lines[LineIndex]), 0);
Result := Lo(j) - Lo(i);
可能还差最后一个字符的宽度,好办了。
 
怕麻烦??
procedure TForm1.Button1Click(Sender: TObject);
begin
with RichEdit1.SelAttributesdo
begin
Size:=64;
Color:=clred;
end;
end;
//下面过程返回第3行的宽度
procedure TForm1.Button2Click(Sender: TObject);
var myrect:TRect;
a,i,sumwidth:Integer;
begin
i:=0;
sumwidth:=0;
with RichEdit1do
begin
a:=FindText(Lines[2],0,length(text),[]);//在前几行有重复时这句会有问题,不要用这个查找,我是为了方便,精确的方法还是找#13#10。
SelStart:=a;
if a<>0 then
for i:=1 to Length(Lines[2])do
begin
SelLength:=1;
sumwidth:=sumwidth+SelAttributes.Size;
SelStart:=selstart+1;
end;
end;
ShowMessage(Format('The Width is :%d',[sumwidth]));
end;

 
我没试过supermmx的方法, 我可以用caretpos取得最后一个字符之前的client纵坐标.
只要在目标行的最后加上一个字符, 使原来的最后一个变成倒数第二个, 做完计算后删掉它.这样应该可以吧? ^ ^
 

sumwidth:=sumwidth+SelAttributes.Size
不对吧?
 
caretpos 的得到是 行列, 不是象素
 
Nutty:
呵呵,累计总宽度,有什么不对?
 
使用TCanvas的方法TextHeight,TextWidth,TextExtent可以获得文本在特定环境下的属性。
TRichText好像没有Canvas属性,不过不要紧。把TRichText的Font赋给
某个Canvas对象(随便去哪里找一个不显示的),再调用就可以了。。
 
对不起,原来我的例子是用creatfont创建字体,sigh,于是它就有width属性,于是可以通过caretpos计算...但是如果supermmx的语句work,那么添字的方法应该可以的,只是比较烦...~ ~
to menxin:
size属性和height一样指的是字体高度, 而不是宽度
 
var dc:HDC;
CSize:Size;
s:PChar;
....
dc:=getDC(RichEdit1.Handle);
GetTextExtentPoint(dc,s,Strlen(s),CSize);
//获得以象素为单位的字符串的长度,长度=CSize.cx ,高度=CSize.cy
 
因为“一行中可能有不同的字体”
有点难度

关注。
 
这是从前的帖子, 也许有帮助
**********************************************************************
问题的标题是: 如何获取Memo/RichEdit控件中字体的宽度? (100分 )
来自 :FlyBeckham 时间 :1999-11-09 12:33:26
应该如何调用那个Win Api?


--------------------------------------------------------------------------------
来自 :Jams 时间 :1999-11-09 12:35:44
>>


--------------------------------------------------------------------------------
来自 :DreamTiger 时间 :1999-11-09 12:37:44
好像有得到某个字符的宽度的函数,没有某种字体的宽度,
因为一种字体的字符宽度可能不同。


--------------------------------------------------------------------------------
来自 :Keyes 时间 :1999-11-09 12:39:13
这个不行?
memo1.font.size


--------------------------------------------------------------------------------
来自 :cAkk 时间 :1999-11-09 12:39:58
将form字体设成和memo/richedit一样,然后通过form.canvas.TextWidth
可以得到.


--------------------------------------------------------------------------------
来自 :Another_eYes 时间 :1999-11-09 13:21:55
设置form字体有问题的. 很多控件的parentfont默认是true. 一设form字体,
那些控件字体就都变掉了. 也许会影响界面效果.
取得memo的字体宽度不难, 因为它的字体是固定的, richedit 只能取得当前
默认字体的宽度.
var
dc: HDC;
sz: TSize;
begin
dc := getdc(memo.handle);
gettextextentpoint32(dc, pchar('W'), 1, sz);
sz.cx 就是字体的宽度.
sz.cy 是高度.


--------------------------------------------------------------------------------
来自 :Liu JZX 时间 :1999-11-10 15:41:22
tagTEXTMETRICA = record
tmHeight: Longint;
tmAscent: Longint;
tmDescent: Longint;
tmInternalLeading: Longint;
tmExternalLeading: Longint;
tmAveCharWidth: Longint;
tmMaxCharWidth: Longint;
tmWeight: Longint;
tmOverhang: Longint;
tmDigitizedAspectX: Longint;
tmDigitizedAspectY: Longint;
tmFirstChar: AnsiChar;
tmLastChar: AnsiChar;
tmDefaultChar: AnsiChar;
tmBreakChar: AnsiChar;
tmItalic: Byte;
tmUnderlined: Byte;
tmStruckOut: Byte;
tmPitchAndFamily: Byte;
tmCharSet: Byte;
end;

tagTEXTMETRICA在Windows中声明
procedure TForm1.Button2Click(Sender: TObject);
var
dc:hdc;
tm:tagTextMetrica;
begin
dc:=getdc(memo1.Handle);
gettextmetrics(dc,tm);
showmessage(inttostr(tm.tmAveCharWidth));
releasedc(memo1.handle,dc);
end;



--------------------------------------------------------------------------------
来自 :FlyBeckham 时间 :1999-11-10 19:02:26
多人接受答案了。

**********************************************************************
 
关键是有不同字体,一个一个得到加起来应该可以,
我那个没试过,呵呵, windows 好了,可以用 delphi 了,
只要回去不忘了就行。
 
完整解决方案:
1::
function SumWidth(aRichEdit: TRichEdit;aIndex: Integer): Integer;
var
p, q: TPoint;
i: Integer;
s, t: string;
begin
//aIndex 是要求的行 index
with aRichEditdo
begin
s := Lines[aIndex];
Lines[aIndex] := s + ' ';
i := SendMessage(Handle, EM_LINEINDEX, aIndex, 0);
SendMessage(Handle, EM_POSFROMCHAR, LongInt(@p), i);
SendMessage(Handle, EM_POSFROMCHAR, LongInt(@q),
i + Length(Lines[aIndex]) - 1);
Result := q.x - p.x;
Lines[aIndex] := s;
end;
end;

2::
function SumWidth(aRichEdit: TRichEdit;
aIndex: Integer): Integer;
var
i, j: Integer;

aCanvas: TCanvas;
begin
aCanvas := TCanvas.Create;
j := SendMessage(aRichEdit.Handle, EM_LINEINDEX, aIndex, 0);
Result := 0;
with aRichEditdo
i := 1 to Lines[aIndex]do
begin
SelStart := j + i - 1;
SelLength := 1;
aCanvas.Assign(SelAttributes);
Result := Result + aCanvas.TextWidth(SelText);
end;
SelLength := 0;
end;
 
忘写了, aCanvas.Free;
我的代码已经测试过了,这里写的是凭着记忆写的,
有可能会错,如果错了,请自行修改。
 
后退
顶部