如何获得窗口主菜单的可用宽度?

时间:2016-10-24 05:09:30

标签: c++ windows winapi win32gui

说,我有一个Win32应用程序,通过CreateWindowEx方法将主菜单添加到主窗口,我需要知道它的可用宽度。说明我要求的宽度的最佳方法是使用此图表:

enter image description here

那我该怎么计算呢?

当我尝试执行以下操作时,它会为我提供客户区的宽度:

MENUBARINFO mbi = {0};
mbi.cbSize = sizeof(mbi);
if(::GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi))
{
    int nUsableWifth = mbi.rcBar.right - mbi.rcBar.left;
}

1 个答案:

答案 0 :(得分:1)

如果您想知道用于菜单项的宽度,您可以:

  1. 使用GetMenuItemRect()获取最后一个菜单项的屏幕坐标,然后将它们转换为父窗口中的客户端坐标。转换后的右边缘坐标将为您提供宽度:

    HMENU hMenu = ::GetMenu(hWnd);
    int count = ::GetMenuItemCount(hMenu);
    RECT r;
    if (::GetMenuItemRect(hWnd, hMenu, count-1, &r))
    {
        ::MapWindowPoints(NULL, hWnd, (LPPOINT)&r, 2);
        int nUsedWidth = r.right;
        ...
    }
    
  2. 以上假设菜单在窗口客户区内的偏移0处开始。如果您不想依赖它,您可以改为获取第一个菜单项的屏幕坐标并从右边屏幕坐标中减去它最后一个菜单项:

    HMENU hMenu = ::GetMenu(hWnd);
    int count = ::GetMenuItemCount(hMenu);
    RECT rFirst, rLast;
    if (::GetMenuItemRect(hWnd, hMenu, 0, &rFirst) &&
        ::GetMenuItemRect(hWnd, hMenu, count-1, &rLast))
    {
        int nUsedWidth = rLast.right - rFirst.left;
        ...
    }
    
  3. 无论哪种方式,如果您想知道未用于菜单项的宽度,只需获取菜单的总宽度并减去上面计算的宽度:

    MENUBARINFO mbi = {0};
    mbi.cbSize = sizeof(mbi);
    if (::GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi))
    {
        int nUsableWidth = (mbi.rcBar.right - mbi.rcBar.left) - nUsedWidth;
        ...
    }
    

    更新:我没有意识到如果客户区太小而无法在一条线上全部显示,则窗口的菜单可以垂直包裹其项目。在这种情况下,您可能需要执行更类似的操作来计算nUsedWidth

    HMENU hMenu = ::GetMenu(hWnd);
    int count = ::GetMenuItemCount(hMenu);
    int nUsedWidth = 0;
    RECT r;
    
    for(int idx = 0; idx < count; ++idx)
    {
        if (::GetMenuItemRect(hWnd, hMenu, idx, &r))
        {
            ::MapWindowPoints(NULL, hWnd, (LPPOINT)&r, 2);
            if (r.right > nUsedWidth)
                nUsedWidth = r.right;
        }
    }
    ...
    

    或者:

    HMENU hMenu = ::GetMenu(hWnd);
    int count = ::GetMenuItemCount(hMenu);
    int nUsedWidth = 0;
    RECT rFirst, r;
    
    if (::GetMenuItemRect(hWnd, hMenu, 0, &rFirst))
    {
        nUsedWidth = rFirst.right - rFirst.left;
        for (int idx = 1; idx < count; ++idx)
        {
            if (::GetMenuItemRect(hWnd, hMenu, idx, &r))
            {
                int nWidth = r.right - rFirst.left;
                if (nWidth > nUsedWidth)
                    nUsedWidth = nWidth;
            }
        }
    }
    ...