检测菜单项文本(和 ID)

问题描述 投票:0回答:1

代码:

auto pMenuEdit = GetCongregationSubMenu(1);
if (pMenuEdit != nullptr)
{
    const int iSize = pMenuEdit->GetMenuItemCount();
    for (int i = 0; i < iSize; i++)
    {
        CString strMenuText;

        MENUITEMINFO sInfo{};
        sInfo.cbSize = sizeof(MENUITEMINFO);
        sInfo.fMask = MIIM_STRING | MIIM_ID;
        sInfo.dwTypeData = strMenuText.GetBuffer();
        GetMenuItemInfo(pMenuEdit->GetSafeHmenu(), i, TRUE, &sInfo);
        strMenuText.ReleaseBuffer();

        if (strMenuText == strCongregation)
        {
            // Simulate pressing the Edit Congregation menu item
            PostMessage(WM_COMMAND, sInfo.wID);
            break;
        }

        pMenuEdit->GetMenuString(i, strMenuText, MF_BYPOSITION);
        if (strMenuText == strCongregation)
        {
            // Simulate pressing the Edit Congregation menu item
            PostMessage(WM_COMMAND, sInfo.wID);
            break;
        }
    }
}

为什么

pMenuEdit->GetMenuString(i, strMenuText, MF_BYPOSITION);
方法可以正确工作,而
GetMenuItemInfo(pMenuEdit->GetSafeHmenu(), i, TRUE, &sInfo);
方法却不能?根据调试器,文本为空。

Microsoft 文档鼓励使用

GetMenuItemInfo
而不是
GetMenuString

我的错误?

visual-c++ mfc menuitem
1个回答
0
投票

C 中的文本缓冲区始终由两部分组成:指向缓冲区开头的指针和计数(以元素或字节为单位)。相关代码永远不会为

cch
 结构的 
MENUITEMINFO
字段提供值。

解决此问题仍然会导致代码无法检索菜单项文本,因为

strMenuText
缓冲区为空。您还必须分配足够的空间(例如,通过在调用中提供缓冲区大小
CString::GetBuffer()
)。

标准模式是首先发现所需的长度:

MENUITEMINFO sInfo{};
sInfo.cbSize = sizeof(MENUITEMINFO);
sInfo.fMask = MIIM_STRING | MIIM_ID;
if (!GetMenuItemInfo(pMenuEdit->GetSafeHmenu(), i, TRUE, &sInfo)) {
    // Handle error
}

UINT const required_length = sInfo.cch;

并使用该信息来分配足够大小的缓冲区:

CString strMenuText;

sInfo.dwTypeData = strMenuText.GetBuffer(required_length);
sInfo.cch = required_length + 1;
if (!GetMenuItemInfo(pMenuEdit->GetSafeHmenu(), i, TRUE, &sInfo)) {
    // Handle error
}
strMenuText.ReleaseBufferSetLength(sInfo.cch);
© www.soinside.com 2019 - 2024. All rights reserved.