Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获得窗口的可用宽度';什么是主菜单?_C++_Windows_Winapi_Win32gui - Fatal编程技术网

C++ 如何获得窗口的可用宽度';什么是主菜单?

C++ 如何获得窗口的可用宽度';什么是主菜单?,c++,windows,winapi,win32gui,C++,Windows,Winapi,Win32gui,比如说,我有一个Win32应用程序,通过CreateWindowEx方法将菜单添加到主窗口,我需要知道它的可用宽度。说明我要求的宽度的最佳方法是使用以下图表: 那我怎么计算呢 当我尝试执行以下操作时,它会给出客户端区域的宽度: MENUBARINFO mbi = {0}; mbi.cbSize = sizeof(mbi); if(::GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi)) { int nUsableWifth = mbi.rcBar

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

那我怎么计算呢

当我尝试执行以下操作时,它会给出客户端区域的宽度:

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

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

  • 使用
    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;
        ...
    }
    
  • 以上假设菜单在窗口客户端区域内的偏移量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;
        ...
    }
    
  • 无论哪种方式,如果您想知道菜单项不使用的宽度,只需获取菜单的总宽度并减去上述计算的宽度:

    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;
        }
    }
    ...
    
    humenu-humenu=::获取菜单(hWnd);
    int count=::GetMenuItemCount(hMenu);
    int-nUsedWidth=0;
    矩形r;
    对于(int idx=0;idx使用宽度)
    nUsedWidth=r.右;
    }
    }
    ...
    
    或:

    humenu-humenu=::获取菜单(hWnd);
    int count=::GetMenuItemCount(hMenu);
    int-nUsedWidth=0;
    RECT rFirst,r;
    if(::GetMenuItemRect(hWnd、humenu、0和rFirst))
    {
    nUsedWidth=rFirst.right-rFirst.left;
    对于(int idx=1;idxnUsedWidth)
    nUsedWidth=nWidth;
    }
    }
    }
    ...
    
    可用是什么意思?“可用”宽度是客户端区域,如果需要,菜单将使用整个宽度
    GetMenuItemRect()
    将为您获取特定菜单项的位置。@JonathanPotter:请参见上图中的红色箭头。因此,如果您想要“帮助”项的右边缘,请使用
    GetMenuItemRect()
    。但是您的图片描述不够。现在听起来您想要显示菜单所需的最小宽度,而不需要包装?但我不确定,我不得不猜测。你的最终目标是什么?谢谢。你能解释一下为什么在坐标上调用
    MapWindowPoints
    API吗?因为
    GetMenuItemRect()
    返回屏幕坐标,所以我将它们转换为客户机坐标。
    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;
            }
        }
    }
    ...