当前位置:C++技术网 > 精选软件 > Windows零基础入门:3.5 菜单使用2-Win32菜单事件响应详细分析

Windows零基础入门:3.5 菜单使用2-Win32菜单事件响应详细分析

更新时间:2015-10-01 11:40:59浏览次数:1+次

    上一节我们详细解释了菜单的基础知识,以及添加菜单的方法,见《Windows零基础入门:3.4 菜单使用1-Win32菜单添加详细分析》。
    菜单为大量的功能和便捷操作带来了折衷。如果功能点太多,界面上必然放不下,如果功能点太少,软件不够强大。菜单就可以按照分类来容纳大量的功能,所以,是非常不错的东西哦。
    而菜单始终都是用来提供功能执行的,不然也就失去了意义。那么现在我们来讲讲在Win32中如何响应菜单吧。

    Windows零基础入门,菜单事件响应

    Windows零基础入门,菜单事件响应
    当然,因为现在还是课程的前面部分,详细的菜单介绍,在后面的专题讲。这里只是将基本的流程和编码介绍一下,不会太深入,但是一定会很基础。
    菜单事件响应,涉及到消息处理。消息处理的后面很快就会讲,不过在此针对菜单的部分,稍作讲解。
    不管是实现什么功能,按钮,窗口还是菜单,还是工具栏,都是处理消息。消息是窗口的运转的血液,消息处理就是促使血液流动的心脏。
    而所有的菜单,只对应一个消息,就是WM_COMMAND。不要觉得很惊讶,确实如此。那你可能会郁闷了。一个消息如何知道那么多菜单呢?我还可以告诉你,不仅是菜单,还有很多都是通过这个消息来处理的呢。后面慢慢就会知道了的。
    那么系统如何分辨不同的菜单呢?还记得吗?我们之前给菜单项设置ID了哦。不过在这里说明一下。上节课说了,在RC资源定义文件中,如果没有找到定义的标识符,则会当做字符串。不过,对于菜单项,如果定义为字符串,就会很麻烦哦。甚至几乎不可行,因为消息响应要根据菜单项的ID来区分不同的菜单项哦。在消息处理中,通过swtich来分流,而switch语法上,不能直接对字符串进行处理哦。而且,如果不定义为宏,那么菜单的ID那个标识符无法识别。对于菜单项ID,直接使用数字宏即可。
    在上一节中,我们已经添加好菜单了。那么现在要处理的就是WM_COMMAND消息了。也就是在消息处理中加一个case来处理即可。然后在这个消息中,再使用switch来分流菜单的ID,从而可以对不同的菜单项做不同的响应。我们这里就演示弹出一个消息框。
    菜单消息处理的代码如下:

LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_COMMAND:
    {
        switch (wParam)
        {
        case IDM_1:
            MessageBox(NULL, L"菜单1点击了!", L"提示", 0);
            return 0;
        case ID_40003:
            MessageBox(NULL, L"菜单2点击了!", L"提示", 0);
            return 0;
        }
    }
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
     从代码上可以看出,我们只处理了两个消息。一个是WM_DESTROY窗口销毁消息,一个就是菜单处理消息WM_COMMAND。在WM_COMMAND消息处理中,又使用了switch对参数进行判断,从而识别出是哪一个菜单的点击。
    在WM_COMMAND下识别菜单的ID,是通过wParam参数。在前面讲过,hwnd是窗口句柄,message是消息ID,wParam是附加参数,lParam是额外参数数据。很多消息只有左边两个参数,这是必不可少的。有些消息有左边三个参数,有的消息有四个参数。我们如何来确定不同的消息对应多少参数呢?你可以查阅MSDN,输入消息的ID,如WM_DESTROY,就可以查询这个消息的参数情况。通常查阅MSDN是最可靠的。
    不过我有一点经验,不妨分享给大家来快速熟悉。前面两个参数都是必须的,哪个消息都跑不了。第三个就是额外的参数,比如控件的通知码、菜单的ID,说白了,就是额外传递一个唯一标识,因为WM_COMMAND实在是太泛了,底下的类别太多,需要区分,就用上每一个的唯一ID。不管是控件还是菜单还是工具栏等,每一个元素都会带有一个ID,这样就可以通过ID来区分。那么第一个参数就是窗口句柄,第二个就是WM_COMMAND消息ID,那么自然要第三个放菜单ID等了,不能空着第三个参数不用,直接放在第四个吧。
    那么,如果在消息中还想传递参数的话,就要用上第四个参数。比如要设置窗口的标题文字,你就要传递一个字符串的指针过去。具体的我们在消息部分讲解。
    而菜单的ID定义了数字宏,所以IDM_1其实就是一个整数而已。然后在对应的下面处理即可实现对不同菜单不同响应了。