打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Delphi

In Delphi i wish to draw text inside a TRect. I am hoping for the following functionality:

  1. Draw the text centred vertically within the TRect
  2. Draw the text centred horizontally within the TRect
  3. If there is space for more than 1 line of text (using TRect's height), draw the text multiline
  4. If the text does not fit in the TRect (either on a single or mult line) then append ellipsis to the text.

I can see the Windows.DrawText() function almost covers this functionality, however when writing text, multiline and vertically centred are mutually exclusive.

I was wondering if this functionality is built into windows (2000+)? If not is there a way to do this without writing my own function?

asked Aug 10 '11 at 7:30
Simon
3,47811351

2  
Can't you use TLabel? I think it has all the functionality required. –  Andriy M Aug 10 '11 at 7:36
1  
Yes it probably does, but i do not want to use a label, i have a canvas to draw on. –  Simon Aug 10 '11 at 7:41

2 Answers

up vote 10 down vote accepted

Sorry, this is a combination of all previous answers and comments. But it seems OP needs more assistance.

function DrawTextCentered(Canvas: TCanvas; const R: TRect; S: String): Integer;var  DrawRect: TRect;  DrawFlags: Cardinal;  DrawParams: TDrawTextParams;begin  DrawRect := R;  DrawFlags := DT_END_ELLIPSIS or DT_NOPREFIX or DT_WORDBREAK or    DT_EDITCONTROL or DT_CENTER;  DrawText(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags or DT_CALCRECT);  DrawRect.Right := R.Right;  if DrawRect.Bottom < R.Bottom then    OffsetRect(DrawRect, 0, (R.Bottom - DrawRect.Bottom) div 2)  else    DrawRect.Bottom := R.Bottom;  ZeroMemory(@DrawParams, SizeOf(DrawParams));  DrawParams.cbSize := SizeOf(DrawParams);  DrawTextEx(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags, @DrawParams);  Result := DrawParams.uiLengthDrawn;end;procedure TForm1.FormPaint(Sender: TObject);const  S = 'This is a very long text as test case for my paint routine.';var  R: TRect;begin  SetRect(R, 100, 100, 200, 140);  Canvas.Rectangle(R);  InflateRect(R, -1, -1);  Caption := Format('%d characters drawn', [DrawTextCentered(Canvas, R, S)]);end;
answered Aug 10 '11 at 11:41
NGLN
21.6k33387


 
I cant see the difference between deamon_x's and this version but this works!!!! Thanks :) –  Simon Aug 10 '11 at 11:49

 
This line is the key: DT_END_ELLIPSIS or DT_NOPREFIX or DT_WORDBREAK or DT_EDITCONTROL or DT_CENTER; –  Simon Aug 10 '11 at 11:57
2  
i know turned out to be something simple, but any other combination of the flags didnt work! Woul split the points if i could :) –  Simon Aug 10 '11 at 12:00
3  
+1 Well done, thanks for closing this out –  David Heffernan Aug 10 '11 at 12:22

Measure the text first using DT_CALCRECT. Pass DT_WORDBREAK to specify that word wrapping is enabled. This will allow you to find the required height for your text. Then you can, in your code, calculate the vertical offset that gives you vertically centred text, and draw to that offset.

answered Aug 10 '11 at 7:35
David Heffernan
222k16275474


I tried this method, but it appears for some reason the DT_WORD_ELLIPSIS is ignored when DT_WORDBREAK is specified. This routine currently does not paint text outside of the rect (and doesnt show the '...') – Simon Aug 10 '11 at 9:57

Is there a way i can get exactly which text (or length) was drawn? – Simon Aug 10 '11 at 9:59

@Simon With DT_WORDBREAK all the text is drawn. You aren't seeing it presumably due to clipping. – David Heffernan Aug 10 '11 at 10:13

@David, Simon - you need to specify also the DT_MODIFYSTRING flag – user532231 Aug 10 '11 at 10:27

Its very close to what i want, however if i shrink the TRect, the text therefore cannot fit in the TRect and i would expect an ellipsis to be shown. However this is not the case, the last word(s) are simply not drawn. I dont think DT_NOCLIP is what i am after – Simon Aug 10 '11 at 10:28

I have also looked at the DrawTextParams data structure of DrawTextEx, however the uiLengthDrawn which i beleive should return the number of chars drawn always returns the length of the string? – Simon Aug 10 '11 at 10:31

@Simon As I said I think all the text is drawn and what you can't see is due to clipping. – David Heffernan Aug 10 '11 at 10:35
1 
@Simon DrawTextParams.uiLengthDrawn returns the number of characters drawn, including the 3 points due to DT_WORD_ELLIPSIS. – NGLN Aug 10 '11 at 10:48
2 
@Simon - I think you're looking for DT_CENTER or DT_WORDBREAK or DT_END_ELLIPSIS or DT_MODIFYSTRING this will wrap your text, center it horizontally and display ellipsis at the end of the text in case the last line cannot be displayed entirely. – user532231 Aug 10 '11 at 10:49
1 
You do not need DT_MODIFYSTRING, that's only needed for text handling after painting. Use DT_EDITCONTROL to display only full visible lines. Without, there are partial lines drawn which may be the reason for not seeing the ellipsis. – NGLN Aug 10 '11 at 10:53

@NGLN - feel free to copy the code I've posted. Better will be to show the example than discuss here. – user532231 Aug 10 '11 at 10:56
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
DrawText如何使多行文字居中
「Drawn On」
css控制列不换行,IE将隐藏部分用省略号表示
使文字只显示一行并且超出之后用.....显示
LAYUI -下拉多选效果
多行文本溢出显示省略号(...)的方法 | 小影志
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服