📄 uimenu.c
字号:
guiPopFont();
menuHeight=itemHeight*(pMenu->countItem)+(MENUITEM_TOP_GAP<<1); // 菜单高度
menuWidth=itemWidth+6; // 菜单宽度
left=pMenu->base.left;
top=pMenu->base.bottom+2;
right=left+menuWidth-1;
bottom=top+menuHeight-1;
pBuffer=(BYTE *)kernelMalloc(guiGetImageSize(left, top, right, bottom));
if(!pBuffer)
{
guiExitWCS();
return STATUS_ERR; // 没有足够的空间来保存背景
}
guiMenu_Shrink(); // 收回已展开的菜单
guiGetImage(pMenu->base.container, left, top, right, bottom, pBuffer);
guiClearBlock(pMenu->base.container, left, top, right, bottom, GUI_WHITE, 0);
guiDrawRect(pMenu->base.container, left, top, right, bottom, GUI_BLACK, GUI_SOLID);
pMenuList = pMenu->pMenuList;
guiPushFont(pMenu->base.font);
while(pMenuList) // 显示所有菜单项
{
guiShowString(pMenu->base.container, pMenuList->caption, left+3,top+i*itemHeight+4,GUI_BLACK, 0);
pMenuList = pMenuList->next;
i++;
}
guiPopFont();
pMenu->popup_left = left; // 展开的位置
pMenu->popup_top = top;
pMenu->popup_right = right;
pMenu->popup_bottom = bottom;
pMenu->popupFlag = MENU_POPUP; // 展开标志
pMenu->activeItem=-1;
ghPopupMenu=hMenu; // 当前展开的菜单句柄
gpMenuBuffer=pBuffer; // 当前展开菜单所保存的背景
guiExitWCS();
return STATUS_OK;
}
/****************************************************************
// 收回展开菜单
// 参数:
// hMenu 菜单句柄
// 返回值:
// 成功 STATUS_OK
// 失败 STATUS_ERR
*****************************************************************/
DLL_EXP(void) guiMenu_Shrink()
{
TGuiMenu *pMenu;
HNDL hMenu;
guiEnterWCS();
if( !ghPopupMenu )
{
guiExitWCS();
return; // 没有有效的展开菜单
}
pMenu=(TGuiMenu *)ghPopupMenu;
if(pMenu->base.checkFlag != GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS();
return; // 没有有效的展开菜单
}
if(gpMenuBuffer) // 如果有背景被保存
{
if(pMenu->base.container==(HNDL)gpTopWindow)
guiPutImage(pMenu->base.container, pMenu->popup_left, pMenu->popup_top,
pMenu->popup_right, pMenu->popup_bottom, gpMenuBuffer);
kernelFree(gpMenuBuffer);
gpMenuBuffer=NULL;
}
pMenu->popupFlag = MENU_SHRINK;
pMenu->activeItem = -1;
ghPopupMenu=NULL;
guiExitWCS();
return;
}
/****************************************************************
// 删除菜单
// 参数:
// hMenu 菜单句柄
// 返回值:
// 成功 STATUS_OK
// 失败 STATUS_ERR
*****************************************************************/
STATUS _guiMenu_Delete(HNDL hMenu)
{
TGuiMenu *pMenu;
TGuiWindow *pWnd;
guiEnterWCS();
pMenu=(TGuiMenu *)hMenu;
if(pMenu->base.checkFlag != GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS();
return STATUS_ERR; // 菜单无效
}
if(hMenu==ghPopupMenu)
guiMenu_Shrink(); // 如果菜单已展开,则收回它
while(guiMenu_DeleteItem(hMenu, 0)==STATUS_OK); // 逐个删除其中的菜单项
pWnd=(TGuiWindow *)pMenu->base.container;
if(pWnd)
{
if(pWnd->tWinSysCtr.hMenu == hMenu)
pWnd->tWinSysCtr.hMenu=NULL;
}
kernelFree(pMenu);
guiExitWCS();
return STATUS_OK;
}
/****************************************************************
// 显示菜单
// 参数:
// hMenu 菜单句柄
// 返回值:
// 成功 STATUS_OK
// 失败 STATUS_ERR
*****************************************************************/
STATUS _guiMenu_Show(HNDL hMenu)
{
TGuiMenu *pMenu;
char szCaption[GUI_MENU_CAPTION_SIZE+3];
WORD style;
short height;
guiEnterWCS() ;
if(guiControl_IsVisible(hMenu) == FALSE)
{
guiExitWCS() ;
return STATUS_ERR; // 控件不可见
}
pMenu=(TGuiMenu *)hMenu;
if(pMenu->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS() ;
return STATUS_ERR; // 控件无效
}
style=pMenu->base.style;
if( (style&MENU_TYPEMASK)==MENU_SYSTEM )
{
guiExitWCS() ;
return STATUS_ERR; // 系统菜单,由窗口负责显示
}
guiClearBlock(hMenu,0,0,pMenu->base.right,pMenu->base.bottom,pMenu->backColor,0);
switch( style&MENU_FLAGMASK )
{
case MENU_FLAG_LEFT: // 菜单标志在标题的左边
strcpy(szCaption,RES_STR_MENUFLAG[gLanguage]);
strcpy(szCaption,pMenu->caption);
break;
case MENU_FLAG_NONE: // 不显示菜单标志
strcpy(szCaption,pMenu->caption);
break;
default: // 菜单标志在标题的左边
strcpy(szCaption,pMenu->caption);
strcat(szCaption,RES_STR_MENUFLAG[gLanguage]);
break;
}
guiPushFont(pMenu->base.font) ;
height=guiGetStringHeight();
guiShowString(hMenu,szCaption,0,(pMenu->base.bottom+1-height)>>1,pMenu->color,0);
guiPopFont();
guiExitWCS();
return STATUS_OK;
}
/****************************************************************
// 设置菜单标题
// 参数:
// hMenu 菜单句柄
// caption 菜单标题
// 返回值:
// 成功 STATUS_OK
// 失败 STATUS_ERR
*****************************************************************/
DLL_EXP(STATUS) guiMenu_SetCaption(HNDL hMenu,const char *caption)
{
TGuiMenu *pMenu;
guiEnterWCS() ;
pMenu=(TGuiMenu *)hMenu;
if(pMenu->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS() ;
return STATUS_ERR; // 控件无效
}
if(caption) // 标题
{
strncpy(pMenu->caption, caption, GUI_MENU_CAPTION_SIZE);
pMenu->caption[GUI_MENU_CAPTION_SIZE]=0;
}
else
pMenu->caption[0]=0;
guiExitWCS() ;
guiControl_Show(hMenu); // 更新显示
return STATUS_OK;
}
/****************************************************************
// 获取菜单标题
// 参数:
// hMenu 菜单句柄
// 返回值:
// 成功 菜单标题指针
// 失败 NULL
*****************************************************************/
DLL_EXP(char *) guiMenu_GetCaption(HNDL hMenu)
{
TGuiMenu *pMenu;
guiEnterWCS() ;
pMenu=(TGuiMenu *)hMenu;
if(pMenu->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS() ;
return NULL; // 控件无效
}
guiExitWCS();
return pMenu->caption;
}
/****************************************************************
// 菜单对消息的响应
// 参数:
// hMenu 菜单句柄
// message 消息类型
// x,y 相关的消息参数
// 返回值:
// 成功 菜单标题指针
// 失败 NULL
*****************************************************************/
void _guiMenu_Action(HNDL hMenu, WORD message, short x , short y)
{
TGuiMenu *pMenu;
TGuiMessage tMessage;
pMenu=(TGuiMenu *)hMenu;
if( pMenu->base.checkFlag != GUI_CONTROL_CHECK_FLAG)
return; // 句柄无效
if( pMenu->base.status & CONTROL_NOT_ACTIVE)
return; // 菜单不活动
if(message == PENUP)
{
guiMenu_Popup(hMenu);
guiPenSound();
}
return;
}
/****************************************************************
// 菜单处理
// 参数:
// message 消息类型
// x,y 相关的消息参数
// 返回值:
// 对菜单进行了处理 TRUE
// 对菜单没有进行处理 FALSE
*****************************************************************/
BOOL _guiMenuHandler( WORD type, short x, short y )
{
TMenuItem *pMenuItem;
TGuiMessage message;
TGuiMenu *pMenu;
TMenuItem *pCurNode;
short left, top, right, bottom;
short height;
short pos,i;
if( !ghPopupMenu )
return FALSE; // 没有展开的菜单
pMenu=(TGuiMenu *)ghPopupMenu;
left=pMenu->popup_left;
top=pMenu->popup_top;
right=pMenu->popup_right;
bottom=pMenu->popup_bottom;
if((x>left)&&(x<right)&&(y>top)&&(y<bottom)) // 笔点在弹出菜单范围之内
{
guiPushFont(pMenu->base.font);
height=guiGetStringHeight()+4; // 菜单项高度
guiPopFont();
if(y<top+2)
pos=0;
else if(y>bottom-2)
pos=pMenu->countItem-1;
else
pos=(y-top-2)/height; // 菜单项序号
switch(type)
{
case PENUP:
i=0;
pCurNode=pMenu->pMenuList; // 查找被选择的菜单项
while(i!=pos)
{
pCurNode=pCurNode->next;
i++;
}
pMenu->activeItem = -1;
message.handle = (HNDL)gpTopWindow;
message.messageType = MENUITEM_CLICK;
message.x = pCurNode->command;
message.y = pos;
guiEnqueue(gpTopWindow->messageQueue,&message);
guiMenu_Shrink();
guiPenSound();
break;
case PENMOVE:
if( pMenu->activeItem==pos) // 笔在原有选项上移动
break;
if(pMenu->activeItem!=-1) // 取消以前的显示
{
guiInvertRect(0, left+1, top+2+pMenu->activeItem*height,right-1,
top+1+(pMenu->activeItem+1)*height);
}
case PENDOWN:
guiInvertRect(0, left+1, top+2+pos*height,right-1,top+1+(pos+1)*height); // 新选中的位置
pMenu->activeItem=pos;
break;
}
return TRUE;
}
// 笔点在弹出菜单范围之外
if(type==PENDOWN || type==PENUP) // 提笔或抬笔时收回菜单
guiMenu_Shrink();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -