主要思想: 载入文本根据,每行最大len个英文字符分行。 当第len个字符占前半个汉字的时候,此行仅显示len-1个字符。 需要支持13的换行。
//分行器的数据结构 typedef struct { unsigned short int offset; //行起始位置 unsigned short int len; //行长度 }TLineDescript;
int ViewForm(unsigned char *memo, //要显示的内容 unsigned char *title, //要显示的标题(最多16个英文字符) unsigned char width, //显示内容的宽度,2~14 unsigned char GBK) //GBK编码,主要用于汉字分行的算法 { TLineDescript *memoLines, *tempLines; TScrollBar vertialScrollBar; unsigned short int count; short int lineLen; unsigned long int total; int i,j; int ret; BROWINFO bi2; if (0==width) width = 2; if (width > 14) width = 14; DispStr_CE(0,0,title,DISP_CENTER|DISP_CLRSCR); draw_rect(0,0,127,15); //=================================汉字分行算法================================= count = 0; lineLen = 0; total = strlen(memo); if (total==0) {memo=" ";total =1;} tempLines = (TLineDescript*)malloc(sizeof(TLineDescript)*65535/15); for (i = 0; i < total; i++) { lineLen++; if (memo[i]==13) { tempLines[count].len = lineLen; tempLines[count].offset = i - lineLen + 1; count = count + 1; lineLen = 0; } else if (GBK) { //C1区间:[129,254] C2区间:[64, 254](127) if ((memo[i]>128)&&(memo[i]<255)) { if (i < (total-1)) { if ((memo[i+1]>63)&&(memo[i+1]<255)&&(memo[i+1]!=0x7F)) { if (width==lineLen) { tempLines[count].len = lineLen - 1; tempLines[count].offset = i - lineLen + 1; count = count + 1; lineLen = 0; i=i--; continue; } else { i++; lineLen++; } }//C2 }//TOTAL-1 }//C1 }//GBK else { //C1区间:[160,255] C2区间:[160, 255] if ((memo[i]>159)&&(memo[i]<=255)) { if (i < (total-1)) { if ((memo[i+1]>159)&&(memo[i+1]<=255)) { if (width ==lineLen) { tempLines[count].len = lineLen - 1; tempLines[count].offset = i - lineLen + 1; count = count + 1; lineLen = 0; i=i--; continue; } else { i++; lineLen++; } }//C2 }//TOTAL-1 }//C1 }//GBK if (lineLen == width) { tempLines[count].len = lineLen; tempLines[count].offset = i - lineLen + 1; count = count + 1; lineLen = 0; } } if (lineLen > 0) { tempLines[count].offset = i - lineLen; tempLines[count].len = lineLen; count = count + 1; lineLen = 0; } //*********以下这个函数可能冲击内存********* memoLines = (TLineDescript*)malloc(count*sizeof(TLineDescript)); memcpy(memoLines, tempLines, count*sizeof(TLineDescript)); free(tempLines); //=================================汉字分行算法==结束=========================== bi2.startLine = 1; bi2.dispLines = 3; bi2.iStr = memo; bi2.mInt = count; bi2.lineMax = width; bi2.sFont = 0; bi2.numEnable = 1; bi2.qEvent = EXIT_KEY_F1|EXIT_CARD_GONE; init_scrollBar(&vertialScrollBar, 111,16, 47, 16, 3, count, 8); ret = brow_info_x(&bi2, memoLines, &vertialScrollBar); free(memoLines); return ret; }
滚动条能够反映出当前页面在整个文件中的位置,以及当前页面在这个文件中所占的比重。一旦文件太长,滚动块要有一个最小的高度。
参考:
//垂直滚动条的数据结构 typedef struct { short int atomPos; //[变量]当前位置 unsigned short int unitSize; //[给定]滚动快表示的大小 unsigned short int atomCount; //[给定]位置元素总数 unsigned short int scroll_Height;//[给定]滚动条的长度 unsigned short int scroll_Width; //[给定]滚动条的宽度 unsigned short int bar_Width; //[内部]滚动块的宽度 unsigned short int bar_DefMin; //[预设]最小滚动块的高度 unsigned short int bar_Height; //[首次计算]滚动块的高度 unsigned short int bar_Top; //[显示计算]滚动块的坐标 unsigned char scroll_X; //[给定]滚动条的X unsigned char scroll_Y; //[给定]滚动条的Y }TScrollBar;
//内部函数:初始化垂直滚动条 //这个函数的功能主要是计算滚动块的高度 void init_scrollBar(TScrollBar *pSB,//垂直滚动条(Vertial Scroll Bar) unsigned char x, //滚动条的x坐标 unsigned char y, //滚动条的y坐标 unsigned short int scroll_Height, //滚动条的高度 unsigned short int scroll_Width, //滚动条的宽度 unsigned short int unitSize, //每个页面的行数 unsigned short int atomCount, //总行数 unsigned short int bar_DefMin) //默认滚动块高度 { //这个函数代码中的2理解为scroll的边宽x2 pSB->scroll_X = x; pSB->scroll_Y = y; pSB->scroll_Height = scroll_Height; if (scroll_Width < 4) pSB->scroll_Width = 4; else pSB->scroll_Width = scroll_Width; pSB->bar_Width = pSB->scroll_Width - 2; pSB->unitSize = unitSize; if (0==atomCount) pSB->atomCount = 1; else pSB->atomCount = atomCount; pSB->bar_DefMin = bar_DefMin; pSB->atomPos = -1; if (pSB->unitSize < pSB->atomCount) { //下面的公式计算滚动块的高度 pSB->bar_Height = pSB->scroll_Height * pSB->unitSize / pSB->atomCount; if (pSB->bar_Height < pSB->bar_DefMin) { pSB->bar_Height = pSB->bar_DefMin; } if (pSB->bar_Height%2==1) pSB->bar_Height++;//让滚动块的高度保持偶数 } else pSB->bar_Height = 0;//如果文本的行不大于一页,那么不显示滚动条 } //内部函数:显示垂直滚动条 //这个函数主要用于显示垂直滚动条 void draw_scrollBar(TScrollBar *pSB, short int iValue) { //这个函数代码中的1理解为scroll的边宽 if (pSB->bar_Height > 0)//如果显示滚动条 { if (iValue > pSB->atomCount) //如果给定值超出总行数限制 { pSB->atomPos = pSB->atomCount; } else { if (pSB->atomPos != iValue)//如果给定行的值发生变化 { //画滚动条框 draw_rect(pSB->scroll_X, pSB->scroll_Y, pSB->scroll_X+pSB->scroll_Width, pSB->scroll_Y+pSB->scroll_Height); if (pSB->atomPos>=0) clear_Bar(pSB->scroll_X+1, pSB->scroll_Y+pSB->bar_Top, pSB->scroll_X+pSB->bar_Width+1, pSB->scroll_Y+pSB->bar_Top+pSB->bar_Height); pSB->atomPos = iValue; pSB->bar_Top = (pSB->atomPos * (pSB->scroll_Height - pSB->bar_Height + 1) / pSB->atomCount); if (pSB->bar_Top > (pSB->scroll_Height - pSB->bar_Height + 1)) pSB->bar_Top = pSB->scroll_Height - pSB->bar_Height + 1; draw_Bar(pSB->scroll_X+1, pSB->scroll_Y+pSB->bar_Top, pSB->scroll_X+pSB->bar_Width+1, pSB->scroll_Y+pSB->bar_Top+pSB->bar_Height); } } } }
以上是20080315版本,以下是20080409版本:
// //垂直滚动条的数据结构 typedef struct { short int atomPos; //[变量]当前位置 unsigned short int unitSize; //[给定]滚动快表示的大小 unsigned short int atomCount; //[给定]位置元素总数 unsigned short int rangeLength; //[首次计算]滚动区间长度 unsigned short int scroll_Height;//[给定]滚动条的长度 unsigned short int scroll_Width; //[给定]滚动条的宽度 unsigned short int bar_Width; //[内部]滚动块的宽度 unsigned short int bar_DefMin; //[预设]最小滚动块的高度 unsigned short int bar_Height; //[首次计算]滚动块的高度 unsigned short int bar_Top; //[显示计算]滚动块的坐标 unsigned char scroll_X; //[给定]滚动条的X unsigned char scroll_Y; //[给定]滚动条的Y }TScrollBar; //==================================================================== // //内部函数:初始化垂直滚动条 //这个函数的功能主要是计算滚动块的高度 void init_scrollBar( TScrollBar *pSB,//垂直滚动条(Vertial Scroll Bar) unsigned char x, //滚动条的x坐标 unsigned char y, //滚动条的y坐标 unsigned short int scroll_Height, //滚动条的高度 unsigned short int scroll_Width, //滚动条的宽度 unsigned short int unitSize, //每个页面的行数 unsigned short int atomCount, //总行数 unsigned short int bar_DefMin) //默认滚动块高度 { //这个函数代码中的2理解为scroll的边宽x2 pSB->scroll_X = x; pSB->scroll_Y = y; pSB->scroll_Height = scroll_Height; if (scroll_Width < 4) pSB->scroll_Width = 4; else pSB->scroll_Width = scroll_Width; pSB->bar_Width = pSB->scroll_Width - 2; pSB->unitSize = unitSize; if (0==atomCount) pSB->atomCount = 1; else pSB->atomCount = atomCount; pSB->bar_DefMin = bar_DefMin; pSB->atomPos = -1; if (pSB->unitSize < pSB->atomCount) { //下面的公式计算滚动块的高度 pSB->bar_Height = pSB->scroll_Height * pSB->unitSize / pSB->atomCount; if (pSB->bar_Height < pSB->bar_DefMin) { pSB->bar_Height = pSB->bar_DefMin; } // if (pSB->bar_Height%2==1) pSB->bar_Height++;//让滚动块的高度保持偶数 pSB->rangeLength=pSB->scroll_Height - pSB->bar_Height - 1; } else pSB->bar_Height = 0;//如果文本的行不大于一页,那么不显示滚动条 } //==================================================================== // //内部函数:显示垂直滚动条 //这个函数主要用于显示垂直滚动条 void draw_scrollBar(TScrollBar *pSB, short int iValue) { //这个函数代码中的1理解为scroll的边宽 if (pSB->bar_Height > 0)//如果显示滚动条 { if (iValue > pSB->atomCount) //如果给定值超出总行数限制 { pSB->atomPos = pSB->atomCount; } else { if (pSB->atomPos != iValue)//如果给定行的值发生变化 { //画滚动条框 draw_rect( pSB->scroll_X, pSB->scroll_Y, pSB->scroll_X+pSB->scroll_Width, pSB->scroll_Y+pSB->scroll_Height); if (pSB->atomPos>=0) clear_Bar(pSB->scroll_X+1, pSB->scroll_Y+pSB->bar_Top, pSB->scroll_X+pSB->bar_Width+1, pSB->scroll_Y+pSB->bar_Top+pSB->bar_Height); pSB->atomPos = iValue; pSB->bar_Top = (pSB->atomPos * pSB->rangeLength) / (pSB->atomCount-1) + 1; if (pSB->bar_Top > pSB->rangeLength) pSB->bar_Top = pSB->rangeLength; draw_Bar(pSB->scroll_X+1, pSB->scroll_Y+pSB->bar_Top, pSB->scroll_X+pSB->bar_Width+1, pSB->scroll_Y+pSB->bar_Top+pSB->bar_Height); } } } } //====================================================================
转载于:https://www.cnblogs.com/nanshouyong326/archive/2009/03/11/1408433.html
