怎么在窗口中显示多行文本?

winstonch 2004-11-02 03:57:21
想在一个窗口中显示一个字符串,当字符串长度超过窗口宽度时换行,
怎么实现?
...全文
241 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
nunu8890 2004-11-03
  • 打赏
  • 举报
回复
没有什么现成的方法。总的来说,需要使用::GetTextExtentPoint32函数来多次尝试计算出符合窗口宽度的字符长度,然后将这些长度的字符用TextOut函数显示出来。
见下面的例子:

BOOL IsRightSideChineseChar(char *Buffer,char *str)
{
//测试str指向的那个字符是否是汉字的右半边
//虽然笨了点,但管用。
//Buffer是一行的开头

if(*str>=0) return FALSE;
char *pChr=Buffer;
int c=0;
while(pChr<=str)
{
int ch=*pChr;
if(*pChr<0)
{
c++;
}
pChr++;
}
if(c & 1) return FALSE;
return TRUE;
}
int GetChars(HDC dc,char *pChar,char *pEnd,int width,char **ppNext)
{
//pChar指向将要显示的字符的开头
//pEnd指向将要显示的全部字符的最后一个字符之后的那个字符
//width是显示区域的宽度
//ppNext送出下一行的开头
//本函数计算需要多少个字符才能正好显示完给定宽度,考虑了回车换行符号的作用

char *str1=pChar;
char *str2=str1+1;
if(str1>=pEnd)
{
*ppNext=NULL;
return 0;//没有字符可以显示了
}

int retv=0;
SIZE size;
if(str2>=pEnd)
{
//只有一个字符
retv=1;
*ppNext=NULL;
}
else
{
//有两个以上的字符
do
{
if(*(str2-1)=='\r' && *str2=='\n')
{
//遇到了回车换行
retv=str2-str1-1;
*ppNext=(char *)str2+1;
return retv;
}
::GetTextExtentPoint32(dc,str1,str2-str1,&size);
if(size.cx>width) break;
str2++;
}while(str2<pEnd);
retv=str2-str1;
*ppNext=(char *)str2;
//还没有完。如果显示的字符里有汉字,由于汉字是用
//两个字节表示的,还要考虑str2所指的那个字符是汉
//字的左半边还是右半边。如果是左半边,ok,但如果
//是右半边,则要将retv减去1,否则一个汉字就要被拆
//成两半分两行显示了。
if(IsRightSideChineseChar(pChar,str2))
{
retv--;
(*ppNext)--;
}
//如果下一行开头已经是全部字符的结尾,说明没有下一行了
if(*ppNext>=pEnd) *ppNext=NULL;
}
return retv;
}
//显示多行字符
int DrawMultLineText(HDC dc,int x0,int y0,int dy,char *Buffer,int count,int width)
{
//x0和y0是显示位置左上角坐标
//dy是每行高度
//Buffer里放的是全部文本字符
//count是想显示的行数
//width是显示区域宽度

//返回实际显示的行数

//本函数将Buffer里的字符串按行显示在指定位置,
//直到显示完指定行数或者全部字符显示完。


int len=strlen(Buffer);
char *pEnd=Buffer+len;
char *pStr=Buffer;
int y=y0;
int ct=0;
while(pStr && ct<count)
{
char *pNext=NULL;
int n=GetChars(dc,pStr,pEnd,width,&pNext);
::TextOut(dc,x0,y,pStr,n);
if(n || pNext)
{
ct++;
}
else
{
if(ct) ct++;
}
pStr=pNext;
y+=dy;
}
return ct;
}

//下面是一个例子
void DrawMyText(HDC dc)
{
char Buffer[]=
" 昨天,金山反病毒中心向本报通报,\
近日接连接到一些盗版微软操作系统WindowsXP\
用户求助,反映自己的计算机出现死机、蓝屏,\
提示使用期限还有30天(并逐日缩短期限)等异常情况。\
反病毒专家纷纷猜测此举不像病毒作怪,\
而更像微软打击盗版的一种措施。昨天晚上,\
微软中国证实此举确实与反盗版有关,但表示\
这一机制在WindowsXP发布时就已存在,用户只\
要采用正版产品代替,便可以正常使用。\
\r\n\r\n盗版用户纷纷求助\r\n\r\n\
据了解,计世网在对多名求助网友进行实地调查后发现,\
这几个网友在几天前均因为操作系统不完善而将系统Update(升级),\
升级之后,系统会提示电脑需要重新启动,无论是选择\
“现在重启”还是“稍后重启”,系统都会提示需要激活,\
其中有三个选项:在线激活、电话激活或者日后提醒,\
当选择日后提醒时,就会出现文前的一幕:系统只能使用三十天,\
且每日递减。值得注意的是,这些网友都是盗版WindowsXP用户。\
金山在昨天给本报发来的通报也显示,这些情况都出现在盗版XP用户中。";

int dy=20;//每行高度
int c=DrawMultLineText(dc,50,30,dy,Buffer,80,200);
char buf[125];
wsprintf(buf,"总共%d行",c);
TextOut(dc,50,(c+1)*dy+30,buf,strlen(buf));
}

菜牛 2004-11-02
  • 打赏
  • 举报
回复
DrawText(),或者用TextOut()自己控制换行。
winstonch 2004-11-02
  • 打赏
  • 举报
回复
就是CWnd窗口
chlchen 2004-11-02
  • 打赏
  • 举报
回复
好像CEdit自己就有自动换行功能哦!!!!
dropingleaf 2004-11-02
  • 打赏
  • 举报
回复
嗯,楼上说得对
WooSir 2004-11-02
  • 打赏
  • 举报
回复
你是什么类型的窗口啊?是CRichEdit控件或CEditView的话本身支持自动换行

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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