发新话题
打印

如何在指定矩形框内水平/垂直显示多行文字(修订)

本主题由 admin 于 2008-5-16 00:41 提升

如何在指定矩形框内水平/垂直显示多行文字(修订)

///////////////////////////////////////////////////////
, e. O" G2 ~. u0 t9 e1 O// 说明(映射方式MM_LOMETRIC下):" e  l1 \7 Z3 }$ u" U! Q+ b
//
; ]& T  B2 O. }* z9 {//       在矩形框中水平或垂直显示多行文字
4 [3 A' L% c4 Z$ F  v//+ S; y1 c' q2 Q
// 编写:5 V/ b5 v  Q0 {# n- Q
//       徐景周(jingzhou_xu@163.net)
; z1 L3 H- ~+ i1 z5 L0 j8 @. P//
( k  ?  ]$ u* `4 C// 参数:3 r* E! M0 P# O& ~" y0 |2 d+ [
//       pDC: 绘制DC
  I: C- p" j8 \) K  g4 F//
. J2 }/ m, V$ E. ]- ?$ G. T# j; J//  szString: 绘制的字符串
' g# j& A- U* }2 N  V% _$ Y//* S3 D+ c+ B' M0 `6 {, \
//    lpRect: 绘制的矩形范围7 Y7 S6 P3 L2 \8 c4 N+ a; m
//
: Y+ t+ u0 [- K4 R6 j6 \" O//     lMode: 排列方式,0:水平方式; 1:垂直对齐 & |2 X8 W+ a2 X" A: n2 J
//; f, |8 k8 D8 u; ~6 A- s
//     lHori: 水平对齐方式, 0:左对齐; 1:居中; 2:右对齐; 3:自定义% B; T+ {# w  _+ j+ \5 |' ~) A
//
/ Q3 I! ?( I# N- d0 y//     lVert: 垂直对齐方式, 0:顶对齐; 1:居中; 2:底对齐; 3:自定义
0 \, J5 b1 L1 N9 j, {2 B3 I$ @' C0 E7 Y///////////////////////////////////////////////////////" n' s9 a9 I& m8 u0 O
CRect DrawTitleInRect(CDC *pDC, CString szString, LPRECT lpRect, long lMode, long lHori, long lVert)
# f4 Y, g8 D4 [) I' R; d{
+ |+ d7 L  @1 t6 c* P# ACRect rcInner(lpRect);: W6 _& O+ t% n( U
if(rcInner.Width() ==0)3 X7 X1 S1 |* Q! u1 M
  return rcInner;
; K' u* B/ ]7 L  n; RTEXTMETRIC tm;* y% e8 X5 y% E$ i6 V( Q' H
pDC->GetTextMetrics(&tm);" }& J* ~7 R0 u: K8 N! H5 C& G0 q
int tmpWidth=tm.tmAveCharWidth, tmpHeight=tm.tmHeight;9 f8 |0 H/ [' T7 k
if(lMode==0)) x3 r# l4 B4 k& q! o' E/ z$ G
{) e' z8 B" g& R, z  u% f
     rcInner.left+=tmpWidth;
5 k7 u7 q9 C9 X8 y/ ~     rcInner.right-=tmpWidth;
% D# X& S( |6 g     rcInner.top-=tmpWidth;
9 B  s. @. w6 g! ~% b2 M* M* }    rcInner.bottom+=tmpWidth;
+ Z$ J, Q1 }% z8 Z% c4 m}" J1 t, }7 N* \- i; ~; i) ~+ J
if(lMode==1)1 Z* ?2 q0 [& `! D
{
& b. G7 T' M; l4 B9 B) p    rcInner.left+=tmpWidth;7 J5 i" s  Z6 x* \
    rcInner.right=rcInner.left+tmpWidth;" k" d. e2 _6 K3 w& G5 e/ V" {
    rcInner.top-=tmpWidth;
8 ~6 t3 h6 l4 Q, Z     rcInner.bottom+=tmpWidth;
. B' o* g& ~' g1 G  g; ?}9 l+ W' r( f/ B  R; l- `
//---------------------------------------------------------------------------------------------
6 g8 i5 `  |. U% f* `//功能:根据新、老矩形,重新计算行数,使文字多行显示,jingzhou xu
: {; P3 \- H2 }& Z- }* ]: [% X//---------------------------------------------------------------------------------------------" C  F% X# V( K/ o7 L
//一行中最大字符数
3 u* T% D; D- m, Xint nMaxLineChar = abs(lpRect->right - lpRect->left) / tmpWidth;
  v9 z$ _0 y  B* uif(nMaxLineChar < 2)               //应该至少能显示一个汉字
+ c5 B7 x" h1 E  return rcInner;, f0 |" n/ v  p0 s
//记录当前行的宽度
0 _) `9 n4 @+ B1 \) E: L) Oshort theLineLength=0;
% \. N# w5 l# S. \" \9 e8 S8 I//记录当前行中汉字字节数,以防止将一半汉字分为两行: {# y! l. \* C. z8 M
unsigned short halfChinese=0;
8 B1 r: o3 S3 P, J+ L  p5 e+ rfor(int i=0; i<=szString.GetLength()-1; i++)$ v$ W2 E! a+ v% l5 C& E. n
{
! d1 z: h# ?. C$ S. K  if(((unsigned char)szString.GetAt(i) == 0x0d) && ((unsigned char)szString.GetAt(i+1) == 0x0a))
; ]' ^) d* H; \  y! n9 I  u* `      theLineLength=0;
, @8 u1 t+ F8 I) C8 m. a  //大于0xa1的字节为汉字字节
: E% a3 A% Z8 S) _# Z4 R2 l  if((unsigned char)szString.GetAt(i) >= 0xA1)4 b+ c. Y; D! p% h$ R3 {" X
      halfChinese++;2 c4 M& s  U5 q8 U
  theLineLength++;
+ U  _( Y' q( K" Z5 d1 h" }( K5 L  //如果行宽大于每行最大宽度,进行特殊处理) \# A+ N/ h/ r. h
  if(theLineLength > nMaxLineChar)# t  N4 |  p) M; Y7 ~0 U1 v
  {3 O, r; }' V# L( J; r
   //防止将一个汉字分为两行,回溯) n- i7 c' m: `: z, I: H
   if(!(halfChinese%2) && (unsigned char)szString.GetAt(i) >= 0xA1)0 {2 _" x; Y, k) l
   {
9 |# p+ }2 E# {% S+ {( s, ^8 Q       szString.Insert(i-1,(unsigned char)0x0a);* A9 v/ {. I) P& ~& u
       szString.Insert(i-1,(unsigned char)0x0d);
. |) I& N" H4 F. B( X    //注:此处不加一跳过,是由于它是在i-1处添加,只需跳到<i+1>处,故只需在循环处加一次既可。
9 \+ B0 l7 I) O, u3 h4 Z* B, Y   }
3 X" D' P0 W! e. w  H+ s8 y, d7 a' j3 D   else
& T: J9 e/ ^# U, E+ P( C   {
9 g  M3 v0 {0 l" k       szString.Insert(i,(unsigned char)0x0a);
( e& \# g3 I& u! Y% K    szString.Insert(i,(unsigned char)0x0d);5 v/ Z) N# u# Q5 D4 g7 k' D! L
       i++;       //跳过新增的换行符,应跳到<i+2>处(循环中加一次,故这里只加一次)
% F" b5 G+ d! _! ^9 D" j4 x% t   }
2 g1 q6 ?! o3 A) v   5 q' ~4 b. B: y* u: b
       theLineLength = 0;8 n; g- w7 J: D, o0 Q" \
       halfChinese=0;# ~, D/ Q/ E- x5 v8 T
  }
- T3 m7 k5 e$ _' B0 j7 S9 l6 ]}7 Y6 z& ]; t* b. `& W
//重新计算矩形边界范围
" A0 F7 x$ k6 ]& B+ Y/ \9 Q" e; ~pDC->DrawText(szString, rcInner,DT_CALCRECT);) Z: u: R6 O5 h' x6 u
switch(lHori)
; G2 w$ v! z' C: c6 G{  }5 q# o7 ~8 x  L. c) z1 N  j
case 0:
. x5 {+ w5 O2 Q  break;
1 L, \/ ~* _$ t8 {* i. ?$ Dcase 1:
6 E5 |3 k& g1 W# q1 z& A7 u% u- h  {
! M* f9 A: c9 A9 ^9 D      long xOutCent=(lpRect->right+lpRect->left)/2;
% L/ U  b( I' X) X5 R$ @& u      long xInnCent=(rcInner.right+rcInner.left)/2;; K; O1 j$ s( y; u, |( ]. _& f
      rcInner.left+=(xOutCent-xInnCent);
7 _* {, Q, E. {      rcInner.right+=(xOutCent-xInnCent);
" p2 k% h* v2 H4 }! U  }
  d( @# ?$ ]8 y( e; _3 Y# _$ Q" H     break;
8 G0 X8 ]. U3 o) K' a0 _2 _1 xcase 2:( l6 B# Z" o; J' l' X2 }
  {  Z/ _0 n0 v* w, R' T& u: {
      long lInWidth=rcInner.right-rcInner.left;
% a. L2 a! f; Y6 P, i      rcInner.right=lpRect->right-tmpWidth;
" \+ z/ b0 [& v  p; R      rcInner.left=rcInner.right-lInWidth;6 X; i, X* C$ C$ e3 ?# g
  }/ r$ Y3 w" \3 O
     break;0 \7 N' G& d0 M' S3 _$ d
default:
. a: y0 h1 Z1 z$ V  M" D     break;
/ I  q1 i& q( q$ \}
: e! N8 O7 h& `, d. M
, d' }: h8 g" N8 @' u8 c* B7 Dswitch(lVert)4 \" M" g6 k* s) Z+ V
{
4 T" a* G3 ]/ @case 0:. I, |% R" H' D2 Q! b1 O
     break;0 M8 z" n- o7 \7 g/ G0 W
case 1:
. f& r. i, p& r, ^  {
: c) d. T- J  {      long yOutCent=(lpRect->bottom+lpRect->top)/2;
8 w% b. V9 c* t1 @5 ~) ]$ E# M. p  B      long yInnCent=(rcInner.bottom+rcInner.top)/2;
# g* K5 P- ~, ^: S% r      rcInner.top-=(yInnCent-yOutCent);- ?! R; S4 Q8 m* j2 ?( @6 Q% T
      rcInner.bottom-=(yInnCent-yOutCent);
" Y! i# G9 E" d  }/ Z* D( ~4 L2 Z% ^% P, E
     break;
& y+ |) u% g8 m% ]6 m, E( M0 _case 2:
, M* a/ O, g0 V0 E; m/ O# {. G  {
1 D* v' A: S% A/ J      long lInHeigh=rcInner.top-rcInner.bottom;( M( m# Q4 b( G/ v7 K% r
      rcInner.bottom=lpRect->bottom+tmpWidth;
' r9 p4 G' x* n      rcInner.top=rcInner.bottom+lInHeigh;0 R% G8 D& X. s  Y- n- a7 ~( R/ X
  }
* @: p4 K& N9 t* t     break;
% m. H* k) L, e7 Adefault:4 ]* |, E1 v+ p% R+ P; r
     break;
' g, W5 L3 n$ ~  `7 g  E* A}
5 I  l0 [8 A5 F0 Q; Q, _9 uif(rcInner.bottom < lpRect->bottom)) y1 \6 {0 F0 T: p* g- `5 o; n
     rcInner.bottom = lpRect->bottom;+ {" |, F" c1 ^4 g' O
if(rcInner.top > lpRect->top)
2 v0 g* _$ Y, E  v) @     rcInner.top = lpRect->top;9 `9 x2 _+ q9 H" J/ G
//---------------------------------------------------------------------------------------------
4 s+ _5 a4 P5 }2 K- W5 m& W# gif(lHori==0)
# Z9 i1 b% n7 k% ^" C- ^7 `, X     pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_LEFT);0 k7 J. V4 U- w. K0 |- v2 y
else if(lHori==1)+ s, ]3 d5 j  U
     pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_CENTER);: @$ ], ~% O, P# F) u. c
else if(lHori==2)7 R2 t  b! ]4 u' z- r! q
     pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_RIGHT);
  u7 E- m- [- t$ f& Hreturn rcInner;. ]7 W# Z6 e: s8 [2 Y! j
}
- M: K( |# c+ h) N4 x' m, z* D* N1 @4 K( ?7 \& Z1 [
用法:* y/ H- C" k5 V# p2 G3 p2 N: {
   DrawTitleInRect(pDC,"VC知识库",CRect(100,100,300,300),0,1,0);

TOP

好資料,支持一下,樓主

TOP

支持

TOP

发新话题
手机号码所在地查询:
Google
IP地址: