Win32开拓入门(4) 建设菜单
当前位置:以往代写 > C/C++ 教程 >Win32开拓入门(4) 建设菜单
2019-06-13

Win32开拓入门(4) 建设菜单

Win32开拓入门(4) 建设菜单

副标题#e#

我们虽然知道 ,此刻,在实际开拓中必定不会像我这样写Win32措施的,你看,连个WinMain都要N行代码。但许多人 不大白什么叫进修,什么叫摸索。实际上,凡是能用于实际开拓中的能力只是占我们对客观世界的认识 总和不到20%,所以,假如你有乐趣计较一下,预计有80%的常识你不知道用到那边去了。就算我们此后 不会把Win32措施投入到实际操纵中,然而假如你相识过这对象,你会发明许多时候对我们是有辅佐的 。

哪怕只是简朴认识一下Win32的一些道理,相信对付日后编程的进修和生长,是有益处的。

为了提高误人后辈的结果,上面我说了几段F话,下面开始本日的正题。

要在窗口上添 加菜单,虽然你大概会研究出N种要领,不外,这里我说两种,一种相当巨大,另一种稍微简朴。

要领一,用代码添加菜单

这种要领的思路是:首先在全局范畴内界说一个HMENU的变量 ,用来生存窗口中菜单栏的句柄,根菜单(菜单栏)可以CreateMenu函数来建设,接着可以利用 AppendMenu函数可能InsertMenuItem函数来建设菜单项。

句柄就是内存中各类资源的ID,好比 图标,图片,字符串等。我们的菜单也是一种资源。

下面我写了一个函数,用来动态建设菜单 。

void CreateMyMenu()     
{     
    hRoot = CreateMenu();     
    if(!hRoot)     
        return;     
    HMENU pop1 = CreatePopupMenu();     
    AppendMenu(hRoot,     
        MF_POPUP,     
        (UINT_PTR)pop1,     
        L"操纵");     
    // 一种要领是利用AppendMenu函数     
    AppendMenu(pop1,     
        MF_STRING,     
        IDM_OPT1,     
        L"飞机");     
         
    // 另一种要领是利用InsertMenuItem函数     
    MENUITEMINFO mif;     
    mif.cbSize = sizeof(MENUITEMINFO);     
    mif.cch = 100;     
    mif.dwItemData  = NULL;     
    mif.dwTypeData = L"构造枪";     
    mif.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE;     
    mif.fState = MFS_ENABLED;     
    mif.fType = MIIM_STRING;     
    mif.wID = IDM_OPT2;     
         
    InsertMenuItem(pop1,IDM_OPT2,FALSE,&mif);     
         
}


#p#副标题#e#

hRoot是在外部界说的全局变量,生存菜单栏的标识。完整的代码如下:

#include 

<Windows.h>     
         
#define IDM_OPT1     301     
#define IDM_OPT2     302     
         
HMENU hRoot;     
void CreateMyMenu();//建设菜单     
         
LRESULT CALLBACK MyWinProce(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     
         
         
int CALLBACK WinMain(HINSTANCE hInstance,     
                    HINSTANCE hPrevInstance,     
                    LPSTR cmdLine,     
                    int nShow)     
{     
    CreateMyMenu();//建设菜单     
    WCHAR* cn = L"Myapp";     
    WNDCLASS wc={   };     
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;     
    wc.lpszClassName = cn;     
    wc.style = CS_HREDRAW | CS_VREDRAW;     
    wc.hInstance = hInstance;     
    wc.lpfnWndProc = (WNDPROC)MyWinProce;     
    RegisterClass(&wc);     
    HWND hm = CreateWindow(cn,     
        L"我的应用措施",     
        WS_OVERLAPPEDWINDOW,     
        20,     
        15,     
        420,     
        360,     
        NULL,     
        hRoot,     
        hInstance,     
        NULL);     
    if( hm == NULL )     
        return 0;     
    ShowWindow(hm,nShow);     
    MSG msg;     
    while(GetMessage(&msg,NULL,0,0))     
    {     
        TranslateMessage(&msg);     
        DispatchMessage(&msg);     
    }     
         
    return 0;     
}     
         
         
LRESULT CALLBACK MyWinProce(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)     
{     
    switch(msg)     
    {     
    case WM_DESTROY:     
        //DestroyMenu(hRoot);     
        PostQuitMessage(0);     
        return 0;     
    default:     
        return DefWindowProc(hwnd, msg, wParam,lParam);     
    }     
}     
         
void CreateMyMenu()     
{     
    hRoot = CreateMenu();     
    if(!hRoot)     
        return;     
    HMENU pop1 = CreatePopupMenu();     
    AppendMenu(hRoot,     
        MF_POPUP,     
        (UINT_PTR)pop1,     
        L"操纵");     
    // 一种要领是利用AppendMenu函数     
    AppendMenu(pop1,     
        MF_STRING,     
        IDM_OPT1,     
        L"飞机");     
         
    // 另一种要领是利用InsertMenuItem函数     
    MENUITEMINFO mif;     
    mif.cbSize = sizeof(MENUITEMINFO);     
    mif.cch = 100;     
    mif.dwItemData  = NULL;     
    mif.dwTypeData = L"构造枪";     
    mif.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE;     
    mif.fState = MFS_ENABLED;     
    mif.fType = MIIM_STRING;     
    mif.wID = IDM_OPT2;     
         
    InsertMenuItem(pop1,IDM_OPT2,FALSE,&mif);     
         
}

Win32开辟入门(4) 建树菜单

#p#副标题#e#

要领二,通过编辑资源来添加菜单

上面的要领固然建设了菜单,但你 也看到了,是相内地不利便,所以,下面我重点先容一下用资源编辑器来建设菜单资源。

在你 的开拓东西上,依次找到菜单项【视图】【资源视图】。

Win32开辟入门(4) 建树菜单

在资源视图中,右击项目根节点,从弹出的菜单中选择【添加】【资源】。

Win32开辟入门(4) 建树菜单

在随后弹出的对话框中,选择Menu,单击右边的“新建”按钮。

Win32开辟入门(4) 建树菜单

可以通过属性窗口来重定名菜单的ID。

Win32开辟入门(4) 建树菜单

#p#副标题#e#

#p#分页标题#e#

我们可以利用可视化视图来成立菜单,为了可以在代码中利用,给需要的菜单一个ID,这个 名字你可以本身喜欢,只是习用的是以IDM_开头,意思是Menu ID,好比IDC开头的,意思是Control ID 等等。

Win32开辟入门(4) 建树菜单

编辑好之后,生存,在【办理方案资源打点器】中你会看到一个resource.h 文件,其实我们为资源界说的ID都以宏的形式声明的,不信你打开看看。

Win32开辟入门(4) 建树菜单

资源ID都是数字,只是为它界说个名字,利便识别而已,就仿佛人们平时只叫你的名字可能 奶名,你见过谁会叫你的身份证号码的?

开拓东西生成的ID有时候会有问题,可能有些ID我们 在措施中没用上,假如你以为它们留在代码文件中会影响市容的话,你可以这样:

1、在【资源 视图】窗口中,右击,从弹出的快捷菜单中选择【资源标记…】,弹出一个窗口,这里可以看到应用 措施中的资源ID列表,以及哪些ID已被利用,可是,这个窗口中显示的内容,有时候禁绝确,有些ID明 明没有被利用,它右边却打上了勾。

这里可以修改ID的值,也可以新建资源ID,所以,你也可 以在这里预先为资源分派ID,然后在属性窗口配置资源的标识时,从下拉列表中选择指定的ID。资源ID 的名字和数值不能反复,可是,差异的资源是可以利用同一个资源ID的。譬喻,凡是在应用措施中,某 些菜单项的成果和东西栏上的按钮是一一对应的,成果沟通,这种环境下,我们可以思量让它们共用一 个ID。

2、你可以直接打开resource.h头文件,直接在上面修改。

响应菜单呼吁

当用户单击某个菜单项后,窗口处理惩罚措施(WindowProc)会收到一条WM_COMMAND动静,它的两个附加参 数如下:

Win32开辟入门(4) 建树菜单

#p#副标题#e#

在收到WM_COMMAND后,我们可以用LOWORD取得它的低数位, 上表中已经说明,wParam的低位值暗示菜单的资源ID,我们通过它的值与哪个菜单的ID相等,就知道用 户点击了哪个菜单项。

所以,我们的措施代码此刻应为:

#include 

<Windows.h>     
#include "resource.h"     
         
LRESULT CALLBACK MyWinProce(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     
         
         
int CALLBACK WinMain(HINSTANCE hInstance,     
                    HINSTANCE hPrevInstance,     
                    LPSTR cmdLine,     
                    int nShow)     
{     
    WCHAR* cn = L"Myapp";     
    WNDCLASS wc={   };     
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;     
    wc.lpszClassName = cn;     
    wc.style = CS_HREDRAW | CS_VREDRAW;     
    wc.hInstance = hInstance;     
    wc.lpfnWndProc = (WNDPROC)MyWinProce;     
    RegisterClass(&wc);     
    HWND hm = CreateWindow(cn,     
        L"我的应用措施",     
        WS_OVERLAPPEDWINDOW,     
        20,     
        15,     
        420,     
        360,     
        NULL,     
        // 加载菜单资源     
        LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAIN)),     
        hInstance,     
        NULL);     
    if( hm == NULL )     
        return 0;     
    ShowWindow(hm,nShow);     
    MSG msg;     
    while(GetMessage(&msg,NULL,0,0))     
    {     
        TranslateMessage(&msg);     
        DispatchMessage(&msg);     
    }     
         
    return 0;     
}     
         
         
LRESULT CALLBACK MyWinProce(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)     
{     
    switch(msg)     
    {     
    case WM_COMMAND:     
        {     
            // 取出资源Id值     
            // 并判定用户选择了哪个菜单项     
            switch(LOWORD(wParam))     
            {     
            case IDM_PLANE:     
                MessageBox(hwnd,L"灰机来了。",L"提示",MB_OK);     
                break;     
            case IDM_GUN:     
                MessageBox(hwnd,L"让炮弹飞。",L"提示",MB_OK);     
                break;     
            case IDM_MT_GUN:     
                MessageBox(hwnd,L"山炮欲来风满楼。",L"提示",MB_OK);     
                break;     
            default:     
                break;     
            }     
        }     
        return 0;     
    case WM_DESTROY:     
        PostQuitMessage(0);     
        return 0;     
    default:     
        return DefWindowProc(hwnd, msg, wParam,lParam);     
    }     
}

#p#副标题#e#

#p#分页标题#e#

在注册窗口类时,如要配置菜单,挪用LoadMenu函数,第一个参数是当前措施实例的句柄, 从WinMain的参数中得到,第二个参数是菜单的ID,因为这里要名字,字符串,而我们的ID都是数值, 可通过MAKEINTRESOURCE宏转换。至于MessageBox函数就不消我先容了。

Win32开辟入门(4) 建树菜单

好了,我们的应用措施已经建设了菜单了。

呵,有人说我的编程进修要领很怪异,其 实,我们何苦要墨守陈规呢,范围在定势思维中呢?枯躁无味的对象,你可以工钱地让它变得布满兴趣 ,要害是你的心态而已。这让我想起,以前某同学A跟我接头两个问题:

1、我的措施只想生存 用户的一些利用配置,用数据库没须要,写注册不环保;

2、我有一个dll类库,我但愿最后我 的措施既可以引用它,但同时只生成一个exe文件,能做到吧。

我就说了,问题一好办,你界说 一个存放配置项的类,把它直接举办XML序列化和反序列化就完事了,这既能生存数据,又可以封装对 象。假如不想让别人看到XML文件中的内容,就把它用DES算法加密/解密;而第二个问题,你把dll文件 当成资源嵌入到措施的资源文件中,运行时假如要用到类库的类,那就把它反射出来,动态挪用就行了 。

然后他说,这仿佛没有人这样做,老师也没教过。

我说:靠,你老爸小时候教过你泡 妞吗?你一上大学怎么就学会了泡妞?四年大学还换了N个妞,我一个都没换成,你的恋爱事业如此成 功。再说了,吕不韦临死前有教过秦始皇怎么统一中华吗?莫非秦始皇会说:以前没人统一过中原,我 怎么统一?最后他老人家照旧把六国给干掉了。

    关键字:

在线提交作业