pDC->TextOut(xx,xx,ss)多行显示汉字时,出现乱码的问题。。。。。。

chen_pin 2002-03-25 10:09:30
我用程序读一个文本文件,内容中主要是汉字,也有 单字符(例如,单字符空格,'1','2'等等)。
当我想在程序中显示这些内容的时候,由于读取的字符串很长,所以分行显示。截取每行为固定长度的 子字符串。但是显示的时候,有时会出现乱码。
我知道这是因为汉字占两个单字符。由于分割不当,导致错误的两两组合。这在早期的中文编辑软件中也有出现。
不知道怎么简单的解决它。请高手指导一下!谢谢!!!
...全文
367 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
villa 2002-03-25
  • 打赏
  • 举报
回复
#include <mbctype.h>
BOOL CCadText::IsDoubleBit(LPCTSTR pString)
{
LPCTSTR pStr = pString;
if ( _ismbblead ( *(UINT*)pStr))
return TRUE;
else if( !(_getmbcp()) &&((0x81 <= *(unsigned char *) pStr && *(unsigned char *)pStr <= 0x9F) ||
(0xE0 <= *(unsigned char *)pStr && *(unsigned char *)pStr <= 0xFC)))
return TRUE;
return FALSE;
}
试试这个,我们一直用的
VC_LOADING 2002-03-25
  • 打赏
  • 举报
回复
中中中中中
中1中中中
中中中中中

中中中中中
中 1中中中
中中中中中

要第二种
prometheusphinx 2002-03-25
  • 打赏
  • 举报
回复
SORRY,我刚刚是在DELPHI中测试的,结果把DELPHI的代码贴上来了。
myfriendhome 2002-03-25
  • 打赏
  • 举报
回复
你可以将你的字符串转换成uicode编码再输出就不会有你所说的乱码问题。
prometheusphinx 2002-03-25
  • 打赏
  • 举报
回复
它只有左对齐和右对齐,我不知道你所指的字与字之间对齐具体是什么意思,
你试试下面的代码。
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
r: TRect;
begin
s := '我的客户要求字与字之间要对齐,不知道DrawText能不能对齐?';
r.Left := 10;
r.Top := 10;
r.Right := 300;
r.Bottom := 300;
DrawText(Canvas.Handle, PChar(s), Length(s), r, DT_WORDBREAK);
end;
VC_LOADING 2002-03-25
  • 打赏
  • 举报
回复
DrawText 我也试过!
我的客户要求字与字之间要对齐,不知道DrawText能不能对齐?
VC_LOADING 2002-03-25
  • 打赏
  • 举报
回复
哈。。。
记得给分!
prometheusphinx 2002-03-25
  • 打赏
  • 举报
回复
用一个最简单的方法,根本不用你自己去判断,系统自己搞掂,DrawText
VC_LOADING 2002-03-25
  • 打赏
  • 举报
回复
void CMyPrint::MyDrawText(CDC *pDC,CString str,CRect &rect,int space_x,int space_y,bool bPrint,bool bBlank)
{
long x=rect.left ;
long y=rect.top ;
int space=space_x;
BOOL CRLFBEGIN=bBlank;
BOOL BEGIN=!bBlank;
CString str_1;
str_1.Empty ();

CSize chinese_size=pDC->GetTextExtent ("中");

chinese_size.cx +=space_x;
chinese_size.cy +=space_y;

for(long i=0;i<str.GetLength ();)
{
while(i<str.GetLength ()&&(unsigned int)str.GetAt (i)<0xa1)
{
if(GetCRLF(i,str))
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
if(bPrint)
pDC->TextOut (x ,y ,str_1);
if(bBlank)
CRLFBEGIN=TRUE;
else
BEGIN=TRUE;
str_1.Empty ();
i+=2;
if( i < str.GetLength())
y+=chinese_size.cy ;
x=rect.left ;
}
else if(!GetCRLF(i,str))
{
if(str.GetAt (i)==' ')
str_1+=_T(" ");
else
str_1+=str.GetAt (i);

if(i+1<str.GetLength ())
{
if((i+2)<str.GetLength ())
{
BYTE bit1=str.GetAt (i+1);
BYTE bit2=str.GetAt (i+2);
if((bit1==0xa3&&bit2==0xac)||(bit1==0xa1&&bit2==0xa3)||(bit1==0xa3&&bit2==0xbb))
{
str_1+=bit1;
str_1+=bit2;
i+=2;
}
else if(bit1==0x2c||bit1==0x2e||bit1==0x3b)
{
str_1+=bit1;
i++;
}
}
else
{
BYTE bit1=str.GetAt (i+1);
if(bit1==0x2c||bit1==0x2e||bit1==0x3b)
{
str_1+=bit1;
i++;
}
}
}

int width=rect.Width ();
CSize size=pDC->GetTextExtent (str_1);
long num=size.cx /chinese_size.cx ;
if(size.cx %chinese_size.cx )
num++;
int crlf_length=0;
if(bBlank&&CRLFBEGIN)
crlf_length=2*chinese_size.cx ;

if(IsChinese(i+1,str))
{
if(CRLFBEGIN||BEGIN)
{
if(((BEGIN||(!bBlank&&CRLFBEGIN))&&x+(num+1)*chinese_size.cx>rect.left +(width/chinese_size.cx) *chinese_size.cx )||
((bBlank&&CRLFBEGIN)&&x+(num+3)*chinese_size.cx>rect.left +(width/chinese_size.cx) *chinese_size.cx ))
{
int temp=(num*chinese_size.cx-space-pDC->GetTextExtent (str_1.Right (1)).cx )/(str_1.GetLength ()-1);
int temp1=(num*chinese_size.cx-space-pDC->GetTextExtent (str_1.Right (1)).cx )%(str_1.GetLength ()-1);
for(int j=0;j<str_1.GetLength ();j++)
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
if(bPrint)
pDC->TextOut (x,y,str_1.GetAt (j));
x+=temp+(temp1>0);
temp1--;
}
}
else
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
if(bPrint)
pDC->TextOut (x,y,str_1);
}
str_1.Empty ();
}
else
{
if(x+num*chinese_size.cx>rect.left +(width/chinese_size.cx) *chinese_size.cx )
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
if(bPrint)
{
long pos=rect.left +(width/chinese_size.cx) *chinese_size.cx-size.cx;
if(pos<x)
pos=x;
pDC->TextOut (pos,y,str_1);
}
}
else
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
if(bPrint)
{
long pos=rect.left +(num*chinese_size.cx -size.cx )/2-space/2;
if(pos<x)
pos=x;
pDC->TextOut (pos,y,str_1);
}
}
str_1.Empty ();
}
x+=num*chinese_size.cx ;
CRLFBEGIN=FALSE;
BEGIN=FALSE;
}
else if(((i+1)<str.GetLength ()&&x+size.cx+pDC->GetTextExtent (str.GetAt (i+1)).cx+space+crlf_length >
rect.left +(width/chinese_size.cx) *chinese_size.cx )||
((i+1)>=str.GetLength ()&&x+size.cx+space >
rect.left +(width/chinese_size.cx) *chinese_size.cx ))
{
if(bPrint)
{
long pos=rect.left +(width/chinese_size.cx) *chinese_size.cx-space -size.cx;
if(pos<x)
pos=x;
pDC->TextOut (pos,y,str_1);
}
str_1.Empty ();

if(i+1 < str.GetLength()&&!GetCRLF(i+1,str))
y+=chinese_size.cy ;
x=rect.left ;
CRLFBEGIN=FALSE;
BEGIN=TRUE;
}
i++;
}
}
if(!str_1.IsEmpty ())
{
if(bPrint)
{
if(bBlank&&CRLFBEGIN)
x+=2*chinese_size.cx ;
CRLFBEGIN=FALSE;
pDC->TextOut (x,y,str_1);
}
rect.bottom =x+pDC->GetTextExtent (str_1).cx ;

str_1.Empty ();
if(i+1 < str.GetLength()&&!GetCRLF(i+1,str))
y+=chinese_size.cy ;

x=rect.left ;
CRLFBEGIN=FALSE;
BEGIN=FALSE;
}
while(i<str.GetLength ()&&(unsigned int)str.GetAt (i)>=0xa1)
{
if(x+chinese_size.cx >rect.right)
{
if(i+1 < str.GetLength()&&!GetCRLF(i,str))
y+=chinese_size.cy ;
x=rect.left ;
}

if(GetCRLF(i,str))
{
if(bBlank)
CRLFBEGIN=TRUE;
else
BEGIN=TRUE;
str_1.Empty ();
i+=2;
if( i < str.GetLength())
y+=chinese_size.cy ;
x=rect.left ;
}

str_1.Format ("%c%c",str.GetAt (i),str.GetAt (i+1));
if(CRLFBEGIN)
x=rect.left+2*chinese_size.cx ;
if(bPrint)
pDC->TextOut (x,y,str_1);
rect.bottom =x+pDC->GetTextExtent (str_1).cx;
x+=chinese_size.cx ;
i+=2;
str_1.Empty ();
CRLFBEGIN=FALSE;
BEGIN=FALSE;

if(GetCRLF(i,str))
{
if(bBlank)
CRLFBEGIN=TRUE;
else
BEGIN=TRUE;
i+=2;
if( i < str.GetLength())
y+=chinese_size.cy ;
x=rect.left ;
}

if(x+chinese_size.cx >rect.right)
{
if(i<str.GetLength ())
{
if((i+1)<str.GetLength ())
{
BYTE bit1=str.GetAt (i);
BYTE bit2=str.GetAt (i+1);
if((bit1==0xa3&&bit2==0xac)||(bit1==0xa1&&bit2==0xa3)||(bit1==0xa3&&bit2==0xbb))
{
str_1+=bit1;
str_1+=bit2;
i+=2;
}
else if(bit1==0x2c||bit1==0x2e||bit1==0x3b)
{
str_1+=bit1;
i++;
}
}
else
{
BYTE bit1=str.GetAt (i);
if(bit1==0x2c||bit1==0x2e||bit1==0x3b)
{
str_1+=bit1;
i++;
}
}
}
pDC->TextOut (x,y,str_1);
str_1.Empty ();

if(i+1 < str.GetLength()&&!GetCRLF(i,str))
y+=chinese_size.cy ;
x=rect.left ;
BEGIN=TRUE;
}
}
}
rect.top =y+chinese_size.cy ;
}

BOOL CMyPrint::GetCRLF(int i, CString str)
{
if(i<str.GetLength ()-1&&str.GetAt (i)==13&&str.GetAt (i+1)==10)
return TRUE;
else
return FALSE;
}
不是很理想,可以参看一下!
lancexu 2002-03-25
  • 打赏
  • 举报
回复
对!全角的符号有这个问题.
关注!
chen_pin 2002-03-25
  • 打赏
  • 举报
回复
不是太好解决,比如全角的符号。判断出来不是汉字,但是,必须连续输出才能正常显示。。还有,我分行的时候,判断条件不是很简单。
不知道,有没有直接可以进行多行显示的同时支持汉字的函数。如果那位高手做过。可否帖一下代码行。谢谢了!!!
dy_paradise 2002-03-25
  • 打赏
  • 举报
回复
可以解决:你可以在读入每两个字符的时候,先判断是不是汉字,因为,汉字编码是双字节,而且两个字节是从 0xA1~0xFE,所以,但你判断不为汉字的时候,就只读一个字符,下面是判断是否为汉字的函数,供参考:

BOOL IsHZCode(BYTE bC1,BYTE bC2)
{
if((bC1>=0xa1&&bC1<=0xfe)&&
(bC2>=0xa1)&&bC2<=0xfe))
return TRUE;

return FALSE;
}

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧