hd 6305 借用
主要思想:
载入文本根据,每行最大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);
}
}
}
}
//====================================================================