当前位置:天才代写 > tutorial > C语言/C++ 教程 > Win32开拓入门(5) 具有单选标志的菜单

Win32开拓入门(5) 具有单选标志的菜单

2017-11-03 08:00 星期五 所属: C语言/C++ 教程 浏览:399

副标题#e#

帅哥们,美男们,下午好,我又来误人后辈,请做好筹备。

本日,我们的目标是,想要实现 下图中的这种菜单结果。

Win32开辟入门(5) 具有单选符号的菜单

就是一种雷同单选按钮的菜单,多个菜单项中,同时只有一个会被选中。

首先,我们 在资源编辑器中,设计一个菜单资源。这个资源编辑器在打点资源ID的时候,有些问题,有时候差异步 更新,有时候会生存不到,横竖就会杂乱。假如碰着问题,你可以先把菜单设计好,接着打开 resource.h,手动把这些ID和它的值改一下。为了使这三个菜单项能形成一个组,必需让它们的ID值是 持续的,好比我这里让它们别离为501,502,503。

Win32开辟入门(5) 具有单选符号的菜单

Win32开辟入门(5) 具有单选符号的菜单

101指的是整个菜单资源,后三个都是子菜单项。假如想更保险的话,可以在【 办理方案资源打点器】中右击资源文件(.rc末了),选择【查察代码】,然后查抄一下是否正确就可 以了。

Win32开辟入门(5) 具有单选符号的菜单


#p#副标题#e#

此刻菜单弄好了,下面我们来相识一下把菜单添加到窗口的两个范例。

第一种是类级此外, 也就是我们在设计窗口类时,直接指定给WNDCLASS布局的lpszMenuName成员,这样做意味着,在挪用 CreateWindow函数建设窗口时,无论你是否为窗口指定菜单,最终显示的窗口上城市有菜单,因为它是 基于整个窗口类的。

// 在这里把菜单附加上,成为类级别     
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN);//整个菜单资源的ID,不是菜单项
HWND 

hm = CreateWindow(     
    L"MainWd",     
    L"我的应用措施",     
    WS_OVERLAPPEDWINDOW,     
    25,     
    18,     
    380,     
    280,     
    NULL,     
    NULL,     
    hthisInstance,     
    NULL);

这样在我们建设窗口时,哪怕你把hMenu参数设为NULL,最后显示的窗口城市有菜 单,因为菜单是属于窗口类自己的。

另一种方法,就是不配置为类级此外菜单,而是在挪用 CreateWindow时指定给hMenu参数。

HWND hm = CreateWindow(     
    L"MainWd",     
    L"我的应用措施",     
    WS_OVERLAPPEDWINDOW,     
    25,     
    18,     
    380,     
    280,     
    NULL,     
    LoadMenu(hthisInstance,MAKEINTRESOURCE(IDR_MAIN)),     
    hthisInstance,     
    NULL);

同时我们把设计窗口类时配置菜单的代码注释掉。

// 在这里把菜单附

加上,成为类级别     
//wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN);//整个菜单资源的ID,不是菜单项

然后, 我们运行这个措施,它照旧有菜单的。

Win32开辟入门(5) 具有单选符号的菜单

接着,我们把CreateWindow的hMenu参数配置为NULL,

HWND hm = CreateWindow(   

  
    L"MainWd",     
    L"我的应用措施",     
    WS_OVERLAPPEDWINDOW,     
    25,     
    18,     
    380,     
    280,     
    NULL,     
    /*LoadMenu(hthisInstance,MAKEINTRESOURCE(IDR_MAIN))*/ 
    NULL,     
    hthisInstance,     
    NULL);

#p#副标题#e#

看看这时候运行措施,还能不能看到菜单。

Win32开辟入门(5) 具有单选符号的菜单

此刻就看不到菜单了,这两种加载菜单的方法,就区别在这里。

要为菜单实现单选标 记,挪用CheckMenuRadioItem函数,第一个参数是要在其子项中配置的单选的菜单的句柄,第二个参数 和第三个参数指定归并为一个组的ID范畴,在这个范畴内的菜单项被看工钱同一组,这一组中,每一次 只能有一项被checked,第四个参数就指定在这组项中哪一个被选中,最后一个参数抉择是用ID来标识 还用从0开始的索引。

可是,我们在改变菜单项单选状态前,必需得到【水果】弹出菜单的句柄 。

我们先来看一下,一般菜单栏的条理布局。

Win32开辟入门(5) 具有单选符号的菜单

它就像一个树形布局,一层一层往下展开,上图中,赤色矩形画的部门是菜单的根,即整个 菜单栏,蓝色矩形标注的是菜单栏的下一级,弹出菜单,如【文件】、【编辑】、【视图】这些,它们 一般只认真弹出子项列表,自身不响应用户选择呼吁,这也是我们在资源编辑器中设计菜单时,不需要 给它们ID号的原因。

在【文件】下面又有了项,如图中黄色矩形标注的处所,如【新建】、【 打开】。

知道这个后,我们的思路就有了。

1、挪用GetMenu( 窗口句柄 )获取窗口中菜 单栏的句柄;

#p#分页标题#e#

2、挪用GetSubMenu(  菜单栏句柄,0 )得到【水果】弹出菜单的句柄,0表 示菜单栏中的第一个元素,假如第二个就是1,我们的弹出菜只有【水果】一项;

3、挪用 CheckMenuRadioItem函来来Check菜单。

因为我们是在响应WM_COMMAND动静时作出响应的,所以 这些代码应写在WindowProc中。

LRESULT CALLBACK WindowMainProc(HWND hwnd, UINT msg, 

WPARAM wParam, LPARAM lParam)     
{     
    // 获取窗口上的整个菜单栏的句柄     
    HMENU hmm = GetMenu(hwnd);     
    // 获取第一个弹出菜单,即[水果]菜单     
    HMENU hfmn = GetSubMenu(hmm, 0);     
    switch(msg)     
    {     
    case WM_COMMAND:     
        {     
        .......

菜单句柄是HMENU范例,所以GetMenu和GetSubMenu函数都返回HMENU范例的 值。其实,这里我给各人推荐一个能力,就是利用auto要害字,我们无需管它函数什么,统一用auto关 键字,它会按照代码上下文揣度数据范例,就像C#内里的var声明变量一样。所以,我们上面的代码可 以改为:

LRESULT CALLBACK WindowMainProc(HWND hwnd, UINT msg, WPARAM wParam, 

LPARAM lParam)     
{     
    // 获取窗口上的整个菜单栏的句柄     
    auto hmm = GetMenu(hwnd);     
    // 获取第一个弹出菜单,即[水果]菜单     
    auto hfmn = GetSubMenu(hmm, 0);     
    switch(msg)     
    {     
    case WM_COMMAND:     
        {     
         ........

#p#副标题#e#

然后,我们响应呼吁动静。

switch(msg)     
{     
case WM_COMMAND:     
    {     
        //判定用户选了哪个菜单     
        switch(LOWORD(wParam))     
        {     
        case IDM_APPLE:     
            CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_APPLE, MF_BYCOMMAND);     
            MessageBox(hwnd,L"你选择了苹果。",L"提示",MB_OK);     
            break;     
        case IDM_PEAR:     
            CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_PEAR, MF_BYCOMMAND);     
            MessageBox(hwnd,L"你选择了梨子。", L"提示", MB_OK);     
            break;     
        case IDM_BANANA:     
            CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_BANANA, MF_BYCOMMAND);     
            MessageBox(hwnd, L"你选择了香蕉。", L"提示", MB_OK);     
            break;     
        }     
    }     
    return 0;

这样就获得单选菜单的结果了。下面是完整的代码清单。

#include 

<Windows.h>     
#include "resource.h"     
         
// 声明动静处理惩罚函数     
LRESULT CALLBACK WindowMainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     
         
//进口点     
int WINAPI WinMain(     
    HINSTANCE hthisInstance,//当前实例句柄     
    HINSTANCE hPrevInstance,//钱一个实例句柄,一般不利用     
    LPSTR cmdline,//呼吁行参数     
    int nShow)//窗口的显示方法     
{     
    // 设计窗口类     
    WNDCLASS wc = { };     
    wc.lpszClassName = L"MainWd";     
    wc.hInstance  = hthisInstance;     
    wc.lpfnWndProc = WindowMainProc;     
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     
    // 在这里把菜单附加上,成为类级别     
    //wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN);//整个菜单资源的ID,不是菜单项     
    // 让窗口自动重绘     
    wc.style = CS_HREDRAW | CS_VREDRAW;     
    // 注册窗口类     
    RegisterClass(&wc);     
    // 建设窗口     
    HWND hm = CreateWindow(     
        L"MainWd",     
        L"我的应用措施",     
        WS_OVERLAPPEDWINDOW,     
        25,     
        18,     
        380,     
        280,     
        NULL,     
        LoadMenu(hthisInstance,MAKEINTRESOURCE(IDR_MAIN)),     
        hthisInstance,     
        NULL);     
    if(hm == NULL)     
        return 0;     
    // 显示窗口     
    ShowWindow(hm, SW_SHOW);     
    // 动静轮回     
    MSG msg;     
    while(GetMessage(&msg, NULL, 0, 0))     
    {     
        TranslateMessage(&msg);     
        DispatchMessage(&msg);     
    }     
    return 0;     
}     
         
LRESULT CALLBACK WindowMainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)     
{     
    // 获取窗口上的整个菜单栏的句柄     
    auto hmm = GetMenu(hwnd);     
    // 获取第一个弹出菜单,即[水果]菜单     
    auto hfmn = GetSubMenu(hmm, 0);     
    switch(msg)     
    {     
    case WM_COMMAND:     
        {     
            //判定用户选了哪个菜单     
            switch(LOWORD(wParam))     
            {     
            case IDM_APPLE:     
                CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_APPLE, MF_BYCOMMAND);  

   
                MessageBox(hwnd,L"你选择了苹果。",L"提示",MB_OK);     
                break;     
            case IDM_PEAR:     
                CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_PEAR, MF_BYCOMMAND);   

  
                MessageBox(hwnd,L"你选择了梨子。", L"提示", MB_OK);     
                break;     
            case IDM_BANANA:     
                CheckMenuRadioItem(hfmn, IDM_APPLE, IDM_BANANA, IDM_BANANA, MF_BYCOMMAND); 

    
                MessageBox(hwnd, L"你选择了香蕉。", L"提示", MB_OK);     
                break;     
            }     
        }     
        return 0;     
    case WM_DESTROY:     
        PostQuitMessage(0);     
        return 0;     
    default:     
        return DefWindowProc(hwnd, msg, wParam, lParam);     
    }     
}

 

    关键字:

天才代写-代写联系方式