Example #1
0
/**
  * @brief  画矩形并填充.
  * @param  x0:矩形左上角
			y0:矩形左上角
			x1:矩形右下角
			y1:矩形右下角
			color:显示的颜色.
  * @retval None.
  * @verify .
  */
void GUI_RectangleFill(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, TCOLOR color)
{  
	uint32_t  i;
	/* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */
	if(x0>x1){  
		i = x0;
		x0 = x1;
		x1 = i;
	}
	if(y0>y1){  
		i = y0;
		y0 = y1;
		y1 = i;
	}
	/* 判断是否只是直线 */
	if(y0==y1){  
		GUI_HLine(x0, y0, x1, color);
		return;
	}
	if(x0==x1) 
	{  
		GUI_RLine(x0, y0, y1, color);
		return;
	}
	while(y0<=y1){  
		GUI_HLine(x0, y0, x1, color);	// 当前画水平线
		y0++;							// 下一行
	}
}
Example #2
0
/**
  * @brief  画矩形.
  * @param  x0:矩形左上角
			y0:矩形左上角
			x1:矩形右下角
			y1:矩形右下角
			color:显示的颜色.
  * @retval None.
  * @verify .
  */
void GUI_Rectangle(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, TCOLOR color)
{  
	GUI_HLine(x0, y0, x1, color);
	GUI_HLine(x0, y1, x1, color);
	GUI_RLine(x0, y0, y1, color);
	GUI_RLine(x1, y0, y1, color);
}
Example #3
0
/****************************************************************************
* 名称:GUI_WindowsDraw()
* 功能:显示窗口。根据提供的窗口参数进行画窗口。
* 入口参数:win		窗口句柄
* 出口参数:返回0表示操作失败,返回1表示操作成功
****************************************************************************/
uint8  GUI_WindowsDraw(WINDOWS *win)
{  uint8  *str;
   int32  bak, bak1, bak2;
   
   /* 参数过滤,若窗口起出范围,则返回0 */
   if( ( (win->with)<20 ) || ( (win->hight)<20 ) ) return(0);		// 宽度、高度检查,限制最小窗口
   if( (win->x + win->with ) > GUI_LCM_XMAX ) return(0);			// 窗口宽度是否溢出
   if( (win->y + win->hight ) > GUI_LCM_YMAX ) return(0);			// 窗口高度是否溢出
    
   /* 开始画窗口 */
   GUI_RectangleFill(win->x, win->y, win->x + win->with - 1, win->y + win->hight - 1, back_color);
   GUI_Rectangle(win->x, win->y, win->x + win->with - 1, win->y + win->hight - 1, disp_color);	// 画窗口
   GUI_HLine(win->x, win->y + 12, win->x + win->with - 1, disp_color);							// 画标题目栏
   GUI_RLine(win->x + 12, win->y, win->y + 12, disp_color);										// 画关闭窗号按钮
   GUI_Line(win->x, win->y, win->x + 12, win->y + 12, disp_color);
   GUI_Line(win->x + 12, win->y, win->x, win->y + 12, disp_color);
   

   /* 写标题 */
   if( win->title != NULL ) 
   {  str = win->title;
      bak = win->x + 15;
      bak1 = win->y + 3;
      bak2 = win->x + win->with -1;
     
      while(1)						
      {  if( (bak+8) > bak2 ) break;								// 判断标题是否溢出
         if(*str=='\0') break;										// 判断字符串是否结束
         
         GUI_PutChar(bak, bak1, *str++);							// 显示标题
         bak += 6;
      }
   }


   /* 写状态栏 */
   if( win->state != NULL )
   {  if( win->hight < 60) return(0);								// 判断是否可以画状态栏
      /* 画状态栏 */
      GUI_HLine(win->x, win->y + win->hight - 11, win->x + win->with - 1, disp_color);
      
      str = win->state;
      bak = win->x + 3;
      bak1 = win->y + win->hight - 9;
      bak2 = win->x + win->with -1;
      
      while(1)						
      {  if( (bak+8) > bak2 ) break;								// 判断标题是否溢出
         if(*str=='\0') break;										// 判断字符串是否结束
         
         GUI_PutChar(bak, bak1, *str++);							// 显示标题
         bak += 6;
      }      
   }
   
   return(1);

}
Example #4
0
/****************************************************************************
* 名称:GUI_MMenuDraw()
* 功能:显示主菜单,加上边框。
* 入口参数:men     主菜单句柄
* 出口参数:返回0表示操作失败,返回1表示操作成功
****************************************************************************/
uint8  GUI_MMenuDraw(MMENU *men)
{
    WINDOWS  *mwin;
    uint8  i;
    uint8  xx;

    /* 参数过滤 */
    if( (men->no)==0 ) return(0);

    mwin = men->win;                     // 取得窗口句柄
    /* 判断是否可以显示主菜单 */
    if( (mwin->hight)<50 ) return(0);
    if( (mwin->with)<50 ) return(0);

    /* 画菜单条,并显示菜主单 */
    GUI_HLine(mwin->x, mwin->y + 22, mwin->x + mwin->with - 1, disp_color);

    xx = mwin->x;
    for(i=0; i<(men->no); i++)
    {
        if( (xx+MMENU_WIDTH) > (mwin->x + mwin->with) ) return(0);

        GUI_PutNoStr(xx+2, mwin->y + 14, men->str[i], 4);         // 书写主菜单文字
        xx += MMENU_WIDTH;
        GUI_RLine(xx, mwin->y + 12, mwin->y + 22, disp_color);    // 显示主菜单分界线
    }

    return(1);
}
Example #5
0
/****************************************************************************
* 名称:GUI_SMenuHide()
* 功能:消隐子菜单项。
* 入口参数:men     子菜单句柄
* 出口参数:返回0表示操作失败,返回1表示操作成功
****************************************************************************/
uint8  GUI_SMenuHide(SMENU *men)
{
    WINDOWS  *mwin;
    uint8    xx, yy;

    mwin = men->win;
    /* 判断是否可以显示主菜单 */
    if( (mwin->hight)<50 ) return(0);
    if( (mwin->with)<50 ) return(0);

    /* 画菜子单项。下拉子菜单,以向左下拉为原则,若右边溢出则以右下拉显示 */
    xx = mwin->x;
    xx +=  (men->mmenu_no)*MMENU_WIDTH;
    yy = mwin->y + 22;
    yy +=  (men->no) * 11 + 2;
    if( (xx+SMENU_WIDTH) <= (mwin->x + mwin->with - 1) )
    {
        /* 以左下拉为原则显示子菜单 */
        if( (men->mmenu_no) == 0 )
        {
            GUI_RectangleFill(xx+1, mwin->y + 22+1, xx+SMENU_WIDTH, yy, back_color);
        }
        else
        {
            GUI_RectangleFill(xx, mwin->y + 22+1, xx+SMENU_WIDTH, yy, back_color);
        }
        GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, disp_color);
    }
    else
    {
        /* 以右下拉为原则 */
        if( (xx+MMENU_WIDTH) == (mwin->x + mwin->with - 1) )
        {
            GUI_RectangleFill(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22+1, xx+MMENU_WIDTH-1, yy, back_color);
        }
        else
        {
            GUI_RectangleFill(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22+1, xx+MMENU_WIDTH, yy, back_color);
        }
        GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, disp_color);
    }

    return(1);
}
Example #6
0
/****************************************************************************
* 名称:GUI_MMenuNSelect()
* 功能:取消当前主菜单,去除下划线。
* 入口参数:men     主菜单句柄
*          no       所选的主菜单项
* 出口参数:无
****************************************************************************/
void  GUI_MMenuNSelect(MMENU *men, uint8 no)
{
    WINDOWS  *mwin;
    uint8  xx;

    /* 参数过滤 */
    if( (men->no)==0 ) return;
    if( no>(men->no) ) return;

    mwin = men->win;                     // 取得窗口句柄
    /* 判断是否可以显示主菜单 */
    if( (mwin->hight)<50 ) return;
    if( (mwin->with)<50 ) return;

    /* 显示下划线 */
    xx = mwin->x + no*MMENU_WIDTH;
    GUI_HLine(xx+1, mwin->y + 22-1, xx+MMENU_WIDTH- 1, back_color);
}
Example #7
0
/****************************************************************************
* 名称:GUI_MenuIcoDraw()
* 功能:显示图标菜单。
* 入口参数:ico     图标菜单句柄
* 出口参数:返回0表示操作失败,返回1表示操作成功
****************************************************************************/
uint8  GUI_MenuIcoDraw(MENUICO *ico)
{
    /* 参数过滤 */
    if( ( (ico->x)<5 ) || ( (ico->x)>(GUI_LCM_XMAX-37 ) ) ) return(0);   // 显示起始地址判断
    if( ( (ico->icodat)==NULL ) || ( (ico->title)==NULL ) ) return(0);   // 显示数据内容判断

    GUI_LoadPic(ico->x, ico->y, (uint8 *) ico->icodat, 32, 32);          // 显示ICO图
    GUI_HLine(ico->x-5, ico->y+32, ico->x+37, back_color);               // 显示一空行
    if( (ico->state)==0 )
    {
        GUI_LoadPic(ico->x-5, ico->y+33, (uint8 *) ico->title, 42, 13);
    }
    else
    {
        GUI_LoadPic1(ico->x-5, ico->y+33, (uint8 *) ico->title, 42, 13);
    }

    return(1);
}
Example #8
0
/****************************************************************************
* 名称:GUI_CircleFill()
* 功能:指定圆心位置及半径,画圆并填充,填充色与边框色一样。
* 入口参数: x0		圆心的x坐标值
*           y0		圆心的y坐标值
*           r       圆的半径
*           color	填充颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void  GUI_CircleFill(uint32_t x0, uint32_t y0, uint32_t r, TCOLOR color)
{  int32_t  draw_x0, draw_y0;			// 刽图点坐标变量
   int32_t  draw_x1, draw_y1;	
   int32_t  draw_x2, draw_y2;	
   int32_t  draw_x3, draw_y3;	
   int32_t  draw_x4, draw_y4;	
   int32_t  draw_x5, draw_y5;	
   int32_t  draw_x6, draw_y6;	
   int32_t  draw_x7, draw_y7;	
   int32_t  fill_x0, fill_y0;			// 填充所需的变量,使用垂直线填充
   int32_t  fill_x1;
   int32_t  xx, yy;					// 画圆控制变量
 
   int32_t  di;						// 决策变量
   
   /* 参数过滤 */
   if(0==r) return;
   
   /* 计算出4个特殊点(0、90、180、270度),进行显示 */
   draw_x0 = draw_x1 = x0;
   draw_y0 = draw_y1 = y0 + r;
   if(draw_y0<GUI_LCM_YMAX)
   {  GUI_Point(draw_x0, draw_y0, color);	// 90度
   }
    	
   draw_x2 = draw_x3 = x0;
   draw_y2 = draw_y3 = y0 - r;
   if(draw_y2>=0)
   {  GUI_Point(draw_x2, draw_y2, color);	// 270度
   }
  	
   draw_x4 = draw_x6 = x0 + r;
   draw_y4 = draw_y6 = y0;
   if(draw_x4<GUI_LCM_XMAX) 
   {  GUI_Point(draw_x4, draw_y4, color);	// 0度
      fill_x1 = draw_x4;
   }
   else
   {  fill_x1 = GUI_LCM_XMAX;
   }
   fill_y0 = y0;							// 设置填充线条起始点fill_x0
   fill_x0 = x0 - r;						// 设置填充线条结束点fill_y1
   if(fill_x0<0) fill_x0 = 0;
   GUI_HLine(fill_x0, fill_y0, fill_x1, color);
   
   draw_x5 = draw_x7 = x0 - r;
   draw_y5 = draw_y7 = y0;
   if(draw_x5>=0) 
   {  GUI_Point(draw_x5, draw_y5, color);	// 180度
   }
   if(1==r) return;
   
   
   /* 使用Bresenham法进行画圆 */
   di = 3 - 2*r;							// 初始化决策变量
   
   xx = 0;
   yy = r;
   while(xx<yy)
   {  if(di<0)
	  {  di += 4*xx + 6;
	  }
	  else
	  {  di += 4*(xx - yy) + 10;
	  
	     yy--;	  
		 draw_y0--;
		 draw_y1--;
		 draw_y2++;
		 draw_y3++;
		 draw_x4--;
		 draw_x5++;
		 draw_x6--;
		 draw_x7++;		 
	  }
	  
	  xx++;   
	  draw_x0++;
	  draw_x1--;
	  draw_x2++;
	  draw_x3--;
	  draw_y4++;
	  draw_y5++;
	  draw_y6--;
	  draw_y7--;
		
	
	  /* 要判断当前点是否在有效范围内 */
	  if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )	
	  {  GUI_Point(draw_x0, draw_y0, color);
	  }	    
	  if( (draw_x1>=0)&&(draw_y1>=0) )	
	  {  GUI_Point(draw_x1, draw_y1, color);
	  }
	  
	  /* 第二点水直线填充(下半圆的点) */
	  if(draw_x1>=0)
	  {  /* 设置填充线条起始点fill_x0 */
	     fill_x0 = draw_x1;
	     /* 设置填充线条起始点fill_y0 */
	     fill_y0 = draw_y1;
         if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
         if(fill_y0<0) fill_y0 = 0; 
         /* 设置填充线条结束点fill_x1 */									
         fill_x1 = x0*2 - draw_x1;				
         if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
         GUI_HLine(fill_x0, fill_y0, fill_x1, color);
      }
	  
	  
	  if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )	
	  {  GUI_Point(draw_x2, draw_y2, color);   
	  }
	    	  
	  if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )	
	  {  GUI_Point(draw_x3, draw_y3, color);
	  }
	  
	  /* 第四点垂直线填充(上半圆的点) */
	  if(draw_x3>=0)
	  {  /* 设置填充线条起始点fill_x0 */
	     fill_x0 = draw_x3;
	     /* 设置填充线条起始点fill_y0 */
	     fill_y0 = draw_y3;
         if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
         if(fill_y0<0) fill_y0 = 0;
         /* 设置填充线条结束点fill_x1 */									
         fill_x1 = x0*2 - draw_x3;				
         if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
         GUI_HLine(fill_x0, fill_y0, fill_x1, color);
      }
	  
	  	  
	  if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )	
	  {  GUI_Point(draw_x4, draw_y4, color);
	  }
	  if( (draw_x5>=0)&&(draw_y5>=0) )	
	  {  GUI_Point(draw_x5, draw_y5, color);
	  }
	  
	  /* 第六点垂直线填充(上半圆的点) */
	  if(draw_x5>=0)
	  {  /* 设置填充线条起始点fill_x0 */
	     fill_x0 = draw_x5;
	     /* 设置填充线条起始点fill_y0 */
	     fill_y0 = draw_y5;
         if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
         if(fill_y0<0) fill_y0 = 0;
         /* 设置填充线条结束点fill_x1 */									
         fill_x1 = x0*2 - draw_x5;				
         if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
         GUI_HLine(fill_x0, fill_y0, fill_x1, color);
      }
	  
	  
	  if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )	
	  {  GUI_Point(draw_x6, draw_y6, color);
	  }
	  
	  if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )	
	  {  GUI_Point(draw_x7, draw_y7, color);
	  }
	  
	  /* 第八点垂直线填充(上半圆的点) */
	  if(draw_x7>=0)
	  {  /* 设置填充线条起始点fill_x0 */
	     fill_x0 = draw_x7;
	     /* 设置填充线条起始点fill_y0 */
	     fill_y0 = draw_y7;
         if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
         if(fill_y0<0) fill_y0 = 0;
         /* 设置填充线条结束点fill_x1 */									
         fill_x1 = x0*2 - draw_x7;				
         if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
         GUI_HLine(fill_x0, fill_y0, fill_x1, color);
      }
	  
   }
}
Example #9
0
/**
  * @brief  画任意两点之间的直线 并可设置线宽.
  * @param  x0:直线起点
			y0:
			x1:
			y1:
			with:
			color:显示的颜色.
  * @retval None.
  * @verify .
  */
void GUI_LineWith(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint8_t with, TCOLOR color)
{  
	int32_t   dx;						// 直线x轴差值变量
	int32_t   dy;          			// 直线y轴差值变量
	int8_t    dx_sym;					// x轴增长方向,为-1时减值方向,为1时增值方向
	int8_t    dy_sym;					// y轴增长方向,为-1时减值方向,为1时增值方向
	int32_t   dx_x2;					// dx*2值变量,用于加快运算速度
	int32_t   dy_x2;					// dy*2值变量,用于加快运算速度
	int32_t   di;						// 决策变量   
	int32_t   wx, wy;					// 线宽变量
	int32_t   draw_a, draw_b;   
	/* 参数过滤 */
	if(with==0) return;
	if(with>50) with = 50;   
	dx = x1-x0;						// 求取两点之间的差值
	dy = y1-y0;   
	wx = with/2;
	wy = with-wx-1;   
   /* 判断增长方向,或是否为水平线、垂直线、点 */
	if(dx>0){							// 判断x轴方向
		dx_sym = 1;					// dx>0,设置dx_sym=1
	}else{
		if(dx<0){
			dx_sym = -1;				// dx<0,设置dx_sym=-1
		}else{  /* dx==0,画垂直线,或一点 */
			wx = x0-wx;
			if(wx<0) wx = 0;
			wy = x0+wy;         
			while(1){  
				x0 = wx;
				GUI_RLine(x0, y0, y1, color);
				if(wx>=wy) break;
				wx++;
			}         
			return;
		}
	}   
	if(dy>0){							// 判断y轴方向
		dy_sym = 1;					// dy>0,设置dy_sym=1
	}else{  
		if(dy<0){
			dy_sym = -1;				// dy<0,设置dy_sym=-1
		}else{  /* dy==0,画水平线,或一点 */
			wx = y0-wx;
			if(wx<0) wx = 0;
			wy = y0+wy;         
			while(1){  
				y0 = wx;
				GUI_HLine(x0, y0, x1, color);
				if(wx>=wy) break;
				wx++;
			}
			return;
		}
	}    
	/* 将dx、dy取绝对值 */
	dx = dx_sym * dx;
	dy = dy_sym * dy;
	/* 计算2倍的dx及dy值 */
	dx_x2 = dx*2;
	dy_x2 = dy*2;
    /* 使用Bresenham法进行画直线 */
	if(dx>=dy){						// 对于dx>=dy,则使用x轴为基准
		di = dy_x2 - dx;
		while(x0!=x1){  /* x轴向增长,则宽度在y方向,即画垂直线 */
			draw_a = y0-wx;
			if(draw_a<0) draw_a = 0;
			draw_b = y0+wy;
			GUI_RLine(x0, draw_a, draw_b, color);
			x0 += dx_sym;				
			if(di<0){  
				di += dy_x2;			// 计算出下一步的决策值
			}else{  
				di += dy_x2 - dx_x2;
				y0 += dy_sym;
			}
		}
		draw_a = y0-wx;
		if(draw_a<0) draw_a = 0;
		draw_b = y0+wy;
		GUI_RLine(x0, draw_a, draw_b, color);
	}else{								// 对于dx<dy,则使用y轴为基准
		di = dx_x2 - dy;
		while(y0!=y1){  /* y轴向增长,则宽度在x方向,即画水平线 */
			draw_a = x0-wx;
			if(draw_a<0) draw_a = 0;
			draw_b = x0+wy;
			GUI_HLine(draw_a, y0, draw_b, color);         
			y0 += dy_sym;
			if(di<0){  
				di += dx_x2;
			}else{  
				di += dx_x2 - dy_x2;
				x0 += dx_sym;
			}
		}
		draw_a = x0-wx;
		if(draw_a<0) draw_a = 0;
		draw_b = x0+wy;
		GUI_HLine(draw_a, y0, draw_b, color);
	}
}
Example #10
0
/**
  * @brief  画任意两点之间的直线.
  * @param  x0:直线起点
			y0:
			x1:
			y1:
			color:显示的颜色.
  * @retval None.
  * @verify .
  */
void GUI_Line(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, TCOLOR color)
{  
	int32_t   dx;			// 直线x轴差值变量
	int32_t   dy;          	// 直线y轴差值变量
	int8_t    dx_sym;		// x轴增长方向,为-1时减值方向,为1时增值方向
	int8_t    dy_sym;		// y轴增长方向,为-1时减值方向,为1时增值方向
	int32_t   dx_x2;		// dx*2值变量,用于加快运算速度
	int32_t   dy_x2;		// dy*2值变量,用于加快运算速度
	int32_t   di;			// 决策变量


	dx = x1-x0;				// 求取两点之间的差值
	dy = y1-y0;

	/* 判断增长方向,或是否为水平线、垂直线、点 */
	if(dx>0){				// 判断x轴方向
		dx_sym = 1;			// dx>0,设置dx_sym=1
	}else{  
		if(dx<0){  
			dx_sym = -1;		// dx<0,设置dx_sym=-1
		}else{  // dx==0,画垂直线,或一点
			GUI_RLine(x0, y0, y1, color);
			return;
		}
	}
	if(dy>0){							// 判断y轴方向
		dy_sym = 1;					// dy>0,设置dy_sym=1
	}else{  
		if(dy<0){  
			dy_sym = -1;				// dy<0,设置dy_sym=-1
		}else{  // dy==0,画水平线,或一点
			GUI_HLine(x0, y0, x1, color);
			return;
		}
	}
	/* 将dx、dy取绝对值 */
	dx = dx_sym * dx;
	dy = dy_sym * dy;
	/* 计算2倍的dx及dy值 */
	dx_x2 = dx*2;
	dy_x2 = dy*2;
	/* 使用Bresenham法进行画直线 */
	if(dx>=dy){						// 对于dx>=dy,则使用x轴为基准
		di = dy_x2 - dx;
		while(x0!=x1){  
			GUI_Point(x0, y0, color);
			x0 += dx_sym;
			if(di<0){
				di += dy_x2;			// 计算出下一步的决策值
			}else{  
				di += dy_x2 - dx_x2;
				y0 += dy_sym;
			}
		}
		GUI_Point(x0, y0, color);		// 显示最后一点
	}else{								// 对于dx<dy,则使用y轴为基准
		di = dx_x2 - dy;
		while(y0!=y1){  
			GUI_Point(x0, y0, color);
			y0 += dy_sym;
			if(di<0){  
				di += dx_x2;
			}else{  
				di += dx_x2 - dy_x2;
				x0 += dx_sym;
			}
		}
		GUI_Point(x0, y0, color);		// 显示最后一点
	}
}
Example #11
0
/****************************************************************************
* 名称:GUI_SMenuDraw()
* 功能:显示子菜单,加上边框。
* 入口参数:men     子菜单句柄
* 出口参数:返回0表示操作失败,返回1表示操作成功
****************************************************************************/
uint8  GUI_SMenuDraw(SMENU *men)
{
    WINDOWS  *mwin;
    uint32   xx, yy;
    uint8    i;

    mwin = men->win;
    /* 判断是否可以显示主菜单 */
    if( (mwin->hight)<50 ) return(0);
    if( (mwin->with)<50 ) return(0);

    /* 画菜子单项。下拉子菜单,以向左下拉为原则,若右边溢出则以右下拉显示 */
    xx = mwin->x;
    xx += (men->mmenu_no)*MMENU_WIDTH;
    yy = mwin->y + 22;
    yy +=  (men->no) * 11 + 2;
    if( (xx+SMENU_WIDTH) <= (mwin->x + mwin->with - 1) )
    {
        /* 以左下拉为原则显示子菜单 */
        if( (men->mmenu_no) == 0 )
        {
            GUI_RLine(xx+SMENU_WIDTH, mwin->y + 22, yy, disp_color);
            GUI_HLine(xx, yy, xx+SMENU_WIDTH, disp_color);
        }
        else
        {
            GUI_Rectangle(xx, mwin->y + 22, xx+SMENU_WIDTH, yy, disp_color);
        }
        GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, back_color);

    }
    else
    {
        /* 以右下拉为原则 */
        if( (xx+MMENU_WIDTH) == (mwin->x + mwin->with - 1) )
        {
            GUI_RLine(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22, yy, disp_color);
            GUI_HLine(xx-(SMENU_WIDTH-MMENU_WIDTH), yy, xx+MMENU_WIDTH, disp_color);

        }
        else
        {
            GUI_Rectangle(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22, xx+MMENU_WIDTH, yy, disp_color);
        }
        GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, back_color);

        xx = xx-(SMENU_WIDTH-MMENU_WIDTH);
    }

    /* 显示菜单文字 */
    xx++;
    yy = mwin->y + 22 + 2;
    for(i=0; i<(men->no); i++)
    {
        if( i == (men->state) )                               // 判断所选择的菜单项
        {
            /* 显示背景色 */
            GUI_RectangleFill(xx, yy, xx+SMENU_WIDTH-2, yy+10, disp_color);
            /* 显示菜单字符 */
            GUI_ExchangeColor();
            GUI_PutNoStr(xx+1, yy+1, men->str[i], 8);          // 书写子菜单文字
            GUI_ExchangeColor();
        }
        else
        {
            /* 显示背景色 */
            GUI_RectangleFill(xx, yy, xx+SMENU_WIDTH-2, yy+10, back_color);
            /* 显示菜单字符 */
            GUI_PutNoStr(xx+1, yy+1, men->str[i], 8);          // 书写子菜单文字
        }

        yy += 11;
    }

    return(1);
}