分享
 
 
 

No MFC,Only API——菜单的创建和使用

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

No MFC,Only API——菜单的创建和使用:

在使用菜单之前,值得一提的是,包含菜单的窗口必须是POPUP-UP或OVERLAPPED风格,才可能拥有菜单。

菜单的创建有三种方法:1,在WINDOWCLASS中指定菜单资源的标识符;2,在CreateWindowEx函数参数中指定菜单句柄;3,先用LoadMenu函数载入菜单资源,再用SetMenu函数把菜单加载到应用程序的菜单栏。

菜单的操作包含:向已存在菜单添加新的菜单项,删除菜单中的某一项,使菜单项呈现被选中状态,使菜单项无效,创建浮动式菜单,向Windows系统菜单中添加,删除选项等等。

定位菜单项有两种途径:1,用菜单项的唯一标识符;2,用菜单项的逻辑索引。

菜单项的逻辑索引是这样规定的,菜单栏中的项从左到右的索引依次是0,1,2...,弹出菜单中的项从上到下的索引依次是0,1,2...。

如果想获得菜单某一项的句柄,因先获得菜单条的句柄,在用该菜单项的索引取得句柄。例如:

hMenu=GetMenu(hWnd); //hWnd是窗口句柄

hPopupMenu=GetSubMenu(hMenu,0); //0表示菜单的第一个选项

范例1:演示菜单的各种操作

// begin.cpp : Defines the entry point for the application.

//

#define WIN32_LEAN_AND_MEAN

#include "stdafx.h"

#include "resource.h"

#define ID_NEWITEM 1013 //定义新菜单项的标识符

#define ID_NEWSYSITEM 60441 //定义新系统菜单项标识符

LRESULT CALLBACK MainProc(HWND,UINT,WPARAM,LPARAM); //主窗口函数

BOOL WINAPI DoDispPopupMenu(HWND,int,int); //创建弹出式菜单

VOID WINAPI DoDispMessage(int); //显示相关信息

VOID WINAPI DoInsertMenuItem(void); //向已有菜单中插入新项

VOID WINAPI DoDeleteMenuItem(void); //删除菜单中的选项

VOID WINAPI DoCheckMenuItem(void); //设置菜单项为选中标志

VOID WINAPI DoCheckRadio(void); //设置菜单项为单选标志

VOID WINAPI DoInsertSysMenu(void); //向系统菜单中插入新项

char szAppName[]="Begin";

HINSTANCE hIns;

HWND hMainWnd;

BOOL isInsert; //插入菜单标志

BOOL isCheck; //选中标志

int idRadio=2; //单选标志

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

MSG msg;

HWND hWnd;

WNDCLASSEX wc;

wc.cbClsExtra =0;

wc.cbSize =sizeof(WNDCLASSEX);

wc.cbWndExtra =0;

wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);

wc.hCursor =LoadCursor(NULL,IDC_ARROW);

wc.hIcon =LoadIcon(NULL,IDI_APPLICATION);

wc.hIconSm =0;

wc.hInstance =hInstance;

wc.lpfnWndProc =(WNDPROC)MainProc;

wc.lpszClassName =szAppName;

wc.lpszMenuName =MAKEINTRESOURCE(IDR_MENU1);

wc.style =CS_HREDRAW | CS_VREDRAW |

CS_DBLCLKS | CS_OWNDC;

RegisterClassEx(&wc);

hWnd=CreateWindowEx(0,szAppName,szAppName,WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

NULL,NULL,hInstance,NULL);

hMainWnd=hWnd;

hIns=hInstance;

//在此处向系统菜单中插入菜单项

DoInsertSysMenu();

ShowWindow(hWnd,nCmdShow);

UpdateWindow(hWnd);

while(GetMessage(&msg,NULL,0,0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

LRESULT CALLBACK MainProc(HWND hWnd,UINT message,

WPARAM wParam,LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT ps;

switch(message)

{

case WM_CREATE:

return 0;

case WM_PAINT:

hdc=BeginPaint(hWnd,&ps);

//do drawing

EndPaint(hWnd,&ps);

return 0;

case WM_RBUTTONDOWN:

//鼠标在窗口中右键被按下时,弹出浮动式菜单

if(DoDispPopupMenu(hWnd,LOWORD(lParam),HIWORD(lParam)))

return 0; //函数调用成功

else

break; //函数调用失败

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_INSERT:

if(isInsert==0)

{//插入新的菜单项

DoInsertMenuItem();

//显示相关信息

DoDispMessage(4);

}

break;

case ID_NEWITEM:

DoDispMessage(3);

break;

case ID_DELETE:

if(isInsert!=0)

{//删除菜单项

DoDeleteMenuItem();

DoDispMessage(5);

}

break;

case IDEXIT:

PostQuitMessage(0);

break;

case ID_CHECK: //在菜单选项前打钩

DoCheckMenuItem();

break;

case ID_RADIO1: //在菜单选项前做一圆形标志,表明此项被选中,

//并清除旧的标志

idRadio=2;

DoCheckRadio();

break;

case ID_RADIO2: //同上

idRadio=3;

DoCheckRadio();

break;

case ID_RADIO3: //同上

idRadio=4;

DoCheckRadio();

break;

case ID_FLOAT1: //浮动菜单的选项被选中时的处理

DoDispMessage(0);

break;

case ID_FLOAT2: //同上

DoDispMessage(1);

break;

case ID_FLOAT3: //同上

DoDispMessage(2);

break;

}

return 0;

case WM_CLOSE:

PostQuitMessage(0);

return 0;

}

return DefWindowProc(hWnd,message,wParam,lParam);

}

BOOL WINAPI DoDispPopupMenu(HWND hWnd,int x,int y)

{

HMENU hMenu;

HMENU hPopupMenu;

POINT pt={x,y};

//从资源文件中载入菜单资源

hMenu=LoadMenu(hIns,MAKEINTRESOURCE(IDR_MENU2));

//获得子菜单的句柄

hPopupMenu=GetSubMenu(hMenu,0);

//窗口坐标转化到屏幕坐标

ClientToScreen(hMainWnd,&pt);

//创建浮动菜单

if(TrackPopupMenu(hPopupMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,

pt.x,pt.y,0,hMainWnd,NULL)==FALSE)

return FALSE;

//使用完毕,回收内存

DestroyMenu(hMenu);

return TRUE;

}

VOID WINAPI DoDispMessage(int id)

{//在菜单事件发生时,输出相应的字符串

HDC hdc;

char *mess[]={"Command Floating Menuitem 1 ",

"Command Floating Menuitem 2 ",

"Command Floating Menuitem 3 ",

"Command New Menu Item ",

"New Item Have Been Inserted ",

"New Item Have Been Deleted "};

InvalidateRect(hMainWnd,NULL,FALSE);

hdc=GetDC(hMainWnd);

TextOut(hdc,0,0,mess[id],strlen(mess[id]));

ReleaseDC(hMainWnd,hdc);

}

VOID WINAPI DoInsertMenuItem()

{//插入菜单项

HMENU hMenu;

HMENU hPopupMenu;

MENUITEMINFO info;

//每一个新插入的菜单项都必须填写MENUITEMINFO结构

info.cbSize =sizeof(MENUITEMINFO);

info.fMask =MFT_STRING | MIIM_DATA | MIIM_ID | MIIM_TYPE;

info.fType =MFT_STRING;

info.fState =0;

info.wID =ID_NEWITEM;

info.hSubMenu =NULL;

info.hbmpChecked =NULL;

info.hbmpUnchecked =NULL;

info.dwItemData =ID_NEWITEM;

info.dwTypeData ="New Item";

info.cch =8;

//获得已存在菜单的句柄

hMenu=GetMenu(hMainWnd);

//获得子菜单的句柄

hPopupMenu=GetSubMenu(hMenu,0);

//插入菜单项

InsertMenuItem(hPopupMenu,1,TRUE,&info);

//置插入标志为1

isInsert=1;

}

VOID WINAPI DoDeleteMenuItem()

{//删除菜单项

HMENU hMenu;

HMENU hPopupMenu;

hMenu=GetMenu(hMainWnd);

hPopupMenu=GetSubMenu(hMenu,0);

RemoveMenu(hPopupMenu,ID_NEWITEM,MF_BYCOMMAND);

isInsert=0;

}

VOID WINAPI DoCheckMenuItem()

{//此函数先判断菜单项是否被打钩,若没有,则做打钩标记

//若已有,则删除打钩标记

HMENU hMenu;

HMENU hPopupMenu;

hMenu=GetMenu(hMainWnd);

hPopupMenu=GetSubMenu(hMenu,1);

if(isCheck)

{

CheckMenuItem(hPopupMenu,0,MF_BYPOSITION | MF_UNCHECKED);

isCheck=0;

}

else

{

CheckMenuItem(hPopupMenu,0,MF_BYPOSITION | MF_CHECKED);

isCheck=1;

}

}

VOID WINAPI DoCheckRadio()

{

HMENU hMenu;

HMENU hPopupMenu;

hMenu=GetMenu(hMainWnd);

hPopupMenu=GetSubMenu(hMenu,1);

CheckMenuRadioItem(hPopupMenu,2,4,idRadio,MF_BYPOSITION);

}

VOID WINAPI DoInsertSysMenu()

{//在系统菜单中插入菜单项

HMENU hSysMenu;

MENUITEMINFO info;

//获得系统菜单的句柄

hSysMenu=GetSystemMenu(hMainWnd,FALSE);

info.cbSize =sizeof(MENUITEMINFO);

info.fMask =MFT_STRING | MIIM_DATA | MIIM_ID | MIIM_TYPE;

info.fType =MFT_STRING;

info.fState =MFS_DEFAULT;

info.wID =ID_NEWSYSITEM;

info.hSubMenu =NULL;

info.hbmpChecked =NULL;

info.hbmpUnchecked =NULL;

info.dwItemData =15;

info.dwTypeData ="New system Item";

info.cch =15;

InsertMenuItem(hSysMenu,6,TRUE,&info);

}

资源文件中有以下定义

IDR_MENU1 MENU DISCARDABLE

BEGIN

POPUP "Menu&1"

BEGIN

MENUITEM "InsertItem\t[I]", ID_INSERT

MENUITEM "DeleteItem\t[D]", ID_DELETE

MENUITEM "&Exit\tAlt+F4", IDEXIT

END

POPUP "Menu&2"

BEGIN

MENUITEM "CheckText", ID_CHECK

MENUITEM SEPARATOR

MENUITEM "Radio1", ID_RADIO1

MENUITEM "Radio2", ID_RADIO2

MENUITEM "Radio3", ID_RADIO3

MENUITEM SEPARATOR

MENUITEM "About", ID_ABOUT

END

END

IDR_MENU2 MENU DISCARDABLE

BEGIN

POPUP "Test"

BEGIN

MENUITEM "Floating Menu Item1", ID_FLOAT1, MENUBREAK

MENUITEM "Floating Menu Item2", ID_FLOAT2

MENUITEM "Floating Menu Item3", ID_FLOAT3

END

END

有任何意见,建议请 email:y_h_zhang@sohu.com.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有