No MFC,Only API——菜單的創(chuàng)建和使用
在使用菜單之前,值得一提的是,包含菜單的窗口必須是POPUP-UP或OVERLAPPED風(fēng)格,才可能擁有菜單。
菜單的創(chuàng)建有三種方法:1,在WINDOWCLASS中指定菜單資源的標(biāo)識(shí)符;2,在CreateWindowEx函數(shù)參數(shù)中指定菜單句柄;3,先用LoadMenu函數(shù)
載入菜單資源,再用SetMenu函數(shù)把菜單加載到應(yīng)用程序的菜單欄。
菜單的操作包含:向已存在菜單添加新的菜單項(xiàng),刪除菜單中的某一項(xiàng),使菜單項(xiàng)呈現(xiàn)被選中狀態(tài),使菜單項(xiàng)無(wú)效,創(chuàng)建浮動(dòng)式菜單,向
Windows系統(tǒng)菜單中添加,刪除選項(xiàng)等等。
定位菜單項(xiàng)有兩種途徑:1,用菜單項(xiàng)的唯一標(biāo)識(shí)符;2,用菜單項(xiàng)的邏輯索引。
菜單項(xiàng)的邏輯索引是這樣規(guī)定的,菜單欄中的項(xiàng)從左到右的索引依次是0,1,2...,彈出菜單中的項(xiàng)從上到下的索引依次是0,1,2...。
如果想獲得菜單某一項(xiàng)的句柄,因先獲得菜單條的句柄,在用該菜單項(xiàng)的索引取得句柄。例如:
hMenu=GetMenu(hWnd); //hWnd是窗口句柄
hPopupMenu=GetSubMenu(hMenu,0); //0表示菜單的第一個(gè)選項(xiàng)
范例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 //定義新菜單項(xiàng)的標(biāo)識(shí)符
#define ID_NEWSYSITEM 60441 //定義新系統(tǒng)菜單項(xiàng)標(biāo)識(shí)符
LRESULT CALLBACK MainProc(HWND,UINT,WPARAM,LPARAM); //主窗口函數(shù)
BOOL WINAPI DoDispPopupMenu(HWND,int,int); //創(chuàng)建彈出式菜單
VOID WINAPI DoDispMessage(int); //顯示相關(guān)信息
VOID WINAPI DoInsertMenuItem(void); //向已有菜單中插入新項(xiàng)
VOID WINAPI DoDeleteMenuItem(void); //刪除菜單中的選項(xiàng)
VOID WINAPI DoCheckMenuItem(void); //設(shè)置菜單項(xiàng)為選中標(biāo)志
VOID WINAPI DoCheckRadio(void); //設(shè)置菜單項(xiàng)為單選標(biāo)志
VOID WINAPI DoInsertSysMenu(void); //向系統(tǒng)菜單中插入新項(xiàng)
char szAppName[]="Begin";
HINSTANCE hIns;
HWND hMainWnd;
BOOL isInsert; //插入菜單標(biāo)志
BOOL isCheck; //選中標(biāo)志
int idRadio=2; //單選標(biāo)志
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;
//在此處向系統(tǒng)菜單中插入菜單項(xiàng)
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:
//鼠標(biāo)在窗口中右鍵被按下時(shí),彈出浮動(dòng)式菜單
if(DoDispPopupMenu(hWnd,LOWORD(lParam),HIWORD(lParam)))
return 0; //函數(shù)調(diào)用成功
else
break; //函數(shù)調(diào)用失敗
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_INSERT:
if(isInsert==0)
{
//插入新的菜單項(xiàng)
DoInsertMenuItem();
//顯示相關(guān)信息
DoDispMessage(4);
}
break;
case ID_NEWITEM:
DoDispMessage(3);
break;
case ID_DELETE:
if(isInsert!=0)
{
//刪除菜單項(xiàng)
DoDeleteMenuItem();
DoDispMessage(5);
}
break;
case IDEXIT:
PostQuitMessage(0);
break;
case ID_CHECK:
//在菜單選項(xiàng)前打鉤
DoCheckMenuItem();
break;
case ID_RADIO1:
//在菜單選項(xiàng)前做一圓形標(biāo)志,表明此項(xiàng)被選中,并清除舊的標(biāo)志
idRadio=2;
DoCheckRadio();
break;
case ID_RADIO2: //同上
idRadio=3;
DoCheckRadio();
break;
case ID_RADIO3: //同上
idRadio=4;
DoCheckRadio();
break;
case ID_FLOAT1: //浮動(dòng)菜單的選項(xiàng)被選中時(shí)的處理
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);
//窗口坐標(biāo)轉(zhuǎn)化到屏幕坐標(biāo)
ClientToScreen(hMainWnd,&pt);
//創(chuàng)建浮動(dòng)菜單
if(TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL)==FALSE)
return FALSE;
//使用完畢,回收內(nèi)存
DestroyMenu(hMenu);
return TRUE;
}
VOID WINAPI DoDispMessage(int id)
{
//在菜單事件發(fā)生時(shí),輸出相應(yīng)的字符串
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()
{
//插入菜單項(xiàng)
HMENU hMenu;
HMENU hPopupMenu;
MENUITEMINFO info;
//每一個(gè)新插入的菜單項(xiàng)都必須填寫(xiě)MENUITEMINFO結(jié)構(gòu)
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);
//插入菜單項(xiàng)
InsertMenuItem(hPopupMenu,1,TRUE,&info);
//置插入標(biāo)志為1
isInsert=1;
}
VOID WINAPI DoDeleteMenuItem()
{
//刪除菜單項(xiàng)
HMENU hMenu;
HMENU hPopupMenu;
hMenu=GetMenu(hMainWnd);
hPopupMenu=GetSubMenu(hMenu,0);
RemoveMenu(hPopupMenu,ID_NEWITEM,MF_BYCOMMAND);
isInsert=0;
}
VOID WINAPI DoCheckMenuItem()
{
//此函數(shù)先判斷菜單項(xiàng)是否被打鉤,若沒(méi)有,則做打鉤標(biāo)記
//若已有,則刪除打鉤標(biāo)記
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;
}
}
聯(lián)系客服