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

发表于:2007-07-01来源:作者:点击数: 标签:
No MFC,Only API——菜单的创建和使用: 在使用菜单之前,值得一提的是,包含菜单的窗口必须是POPUP-UP或OVERLAPPED风格,才可能拥有菜单。 菜单的创建有三种方法:1,在WINDOWCLASS中指定菜单资源的标识符;2,在CreateWindowEx函数参数中指定菜单句柄;3,先
 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.clearcase/" target="_blank" >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

有任何意见,建议请 .


原文转自:http://www.ltesting.net