看流星社区

 找回密码
 注册账号
查看: 1621|回复: 1

CreateMenu与CreatePopupMenu的区别

[复制链接]

该用户从未签到

发表于 2013-5-16 08:43:04 | 显示全部楼层 |阅读模式
很多人都弄不清楚这CreateMenu与CreatePopupMenu的区别,继而发生很多莫名其妙的菜单行为。虽然极少数情况下,Windows能检测出来是你混淆了这两个函数,并且会在合适的时候把错误的函数调换过来,但我们不能总是指望Windows能够正确的判断出我们想要的操作,所以还是得弄清楚这两个函数到底有什么不同。

CreateMenu是创建水平菜单,通常是放置在顶级窗口中,同时也是作为顶级菜单的,就像我们经常看到的“文件”,“编辑”等菜单。而CreatePopupMenu则是创建一个竖立的弹出菜单,通常被用来做另一个菜单的子菜单,或者右键菜单的顶级菜单。
菜单资源总是以菜单栏的形式出现,然而,当你想从资源中加载一个弹出菜单时,就应该将弹出菜单放到一个空的水平菜单栏中。下面通过这个函数来说明如何在水平菜单中内嵌一个弹出菜单。

void UsePopUpMenu(HWND hwnd, HINSTANCE hinst, LPCTSTR pszMenu)
{
    HMENU hmenu = LoadMenu(hinst, pszMenu);
    if(hmenu)
    {
        HMENU hpopMenu = GetSubMenu(hmenu, 0);
        TrackPopupMenu(hpopMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), 0, hwnd, NULL);
    }
}

我们首先加载水平菜单,然后通过GetSubMenu函数提取到子菜单,然后使用TrackPopupMenu函数来显示这个弹出菜单(子菜单)。当不需要这个弹出菜单时,就用DestroyMenu函数来销毁水平菜单。
如果我们在每次需要显示弹出菜单的时候都要先加载水平菜单,然后在来提取并显示弹出菜单,这样以来步骤就显得很麻烦。而一种更为简单的办法就是:首先将弹出菜单从水平菜单中分离出来,然后销毁水平菜单并返回弹出菜单的句柄。

HMENU LoadPopupMenu(HINSTANCE hinst, LPCTSTR pszMenu)
{
    HMENU hpopMenu = NULL;
    HMENU hmenu = LoadMenu(hinst, pszMenu);
    if(hmenu)
    {
        hpopMenu = GetSubMenu(hmenu, 0);
        RemoveMenu(hmenu, 0, MF_BYPOSITION);
       DestroyMenu(hmenu);
    }
    return hpopMenu;
}

void Function(HWND hwnd)
{
    HMENU hpopMenu = LoadPopupMenu(hwnd, MAKEINTRESOURCE(1));
    if(hpopMenu)
    {
        TrackPopupMenu(hpopMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), 0, hwnd, NULL);
        DestroyMenu(hpopMenu);
    }
}

这样一来,LoadPopupMenu可以看作是LoadMenu专门针对弹出菜单的版本。

该用户从未签到

发表于 2013-9-23 09:45:41 | 显示全部楼层
支持一下、还用不着 。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-5-14 16:22

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表