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

    技术2022-05-11  117

    ///// 说明(映射方式MM_LOMETRIC下):////     在矩形框中水平或垂直显示多行文字//// 编写://     徐景周(jingzhou_xu@163.net)//// 参数://       pDC: 绘制DC////  szString: 绘制的字符串////    lpRect: 绘制的矩形范围////     lMode: 排列方式,0:水平方式; 1:垂直方式 ////     lHori: 水平对齐方式, 0:左对齐; 1:居中; 2:右对齐; 3:自定义////     lVert: 垂直对齐方式, 0:顶对齐; 1:居中; 2:底对齐; 3:自定义///CRect DrawTitleInRect(CDC *pDC, CString szString, LPRECT lpRect, long lMode, long lHori, long lVert){ CRect rcInner(lpRect);

     if(rcInner.Width() ==0)  return rcInner;

     TEXTMETRIC tm; pDC->GetTextMetrics(&tm); int tmpWidth=tm.tmAveCharWidth, tmpHeight=tm.tmHeight;

     //--------------------------------------------------------------------------------------------- //功能:根据新、老矩形,重新计算行数,使文字多行显示,jingzhou xu //--------------------------------------------------------------------------------------------- //一行中最大字符数 int nMaxLineChar = abs(lpRect->right - lpRect->left) / tmpWidth;  if(nMaxLineChar < 2)               //应该至少能显示一个汉字  return rcInner;

     //记录当前行的宽度 short theLineLength=0;  //记录当前行中汉字字节数,以防止将一半汉字分为两行 unsigned short halfChinese=0;

     for(int i=0; i<=szString.GetLength()-1; i++) {  if(((unsigned char)szString.GetAt(i) == 0x0d) && ((unsigned char)szString.GetAt(i+1) == 0x0a))   theLineLength=0;

      // 在此加入"||"字符为换行标志字符,输入时可根据此字符串来自动换行  if(((unsigned char)szString.GetAt(i) == '|') && ((unsigned char)szString.GetAt(i+1) == '|'))  {   szString.SetAt(i,(unsigned char)0x0d);   szString.SetAt(i+1,(unsigned char)0x0a);  }

      //大于0xa1的字节为汉字字节  if((unsigned char)szString.GetAt(i) >= 0xA1)   halfChinese++;  theLineLength++;

      //如果行宽大于每行最大宽度,进行特殊处理  if(theLineLength > nMaxLineChar)  {   //防止将一个汉字分为两行,回溯   if(!(halfChinese%2) && (unsigned char)szString.GetAt(i) >= 0xA1)   {    szString.Insert(i-1,(unsigned char)0x0a);    szString.Insert(i-1,(unsigned char)0x0d);    //注:此处不加一跳过,是由于它是在i-1处添加,只需跳到<i+1>处,故只需在循环处加一次既可。   }   else   {    szString.Insert(i,(unsigned char)0x0a);    szString.Insert(i,(unsigned char)0x0d);

        i++;       //跳过新增的换行符,应跳到<i+2>处(循环中加一次,故这里只加一次)   }      theLineLength = 0;   halfChinese=0;  } }

     if(lMode==0)        //水平排列  {  rcInner.left+=tmpWidth;  rcInner.right-=tmpWidth;  rcInner.top-=tmpWidth;  rcInner.bottom+=tmpWidth; } if(lMode==1)        //垂直排列 {  rcInner.left+=tmpWidth;  rcInner.right=rcInner.left+tmpWidth;  rcInner.top-=tmpWidth;  rcInner.bottom+=tmpWidth; }

     //重新计算矩形边界范围 pDC->DrawText(szString, rcInner,DT_WORDBREAK|DT_LEFT|DT_CALCRECT);

     switch(lHori) { case 0:  break; case 1:  {   long xOutCent=(lpRect->right+lpRect->left)/2;   long xInnCent=(rcInner.right+rcInner.left)/2;   rcInner.left+=(xOutCent-xInnCent);   rcInner.right+=(xOutCent-xInnCent);  }  break; case 2:  {   long lInWidth=rcInner.right-rcInner.left;   rcInner.right=lpRect->right-tmpWidth;   rcInner.left=rcInner.right-lInWidth;  }  break; default:  break; }  switch(lVert) { case 0:  break; case 1:  {   long yOutCent=(lpRect->bottom+lpRect->top)/2;   long yInnCent=(rcInner.bottom+rcInner.top)/2;   rcInner.top-=(yInnCent-yOutCent);   rcInner.bottom-=(yInnCent-yOutCent);  }  break; case 2:  {   long lInHeigh=rcInner.top-rcInner.bottom;   rcInner.bottom=lpRect->bottom+tmpWidth;   rcInner.top=rcInner.bottom+lInHeigh;  }  break; default:  break; }

     if(rcInner.bottom < lpRect->bottom)  rcInner.bottom = lpRect->bottom; if(rcInner.top > lpRect->top)  rcInner.top = lpRect->top;

     //---------------------------------------------------------------------------------------------

     if(lHori==0)  pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_LEFT); else if(lHori==1)  pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_CENTER); else if(lHori==2)  pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_RIGHT);

     return rcInner;}


    最新回复(0)