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);  
   }  
}
}
}
//====================================================================


posted @ 2009-03-11 10:05  南守拥  阅读(232)  评论(0编辑  收藏  举报