Code:
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;
}
}
}
Why is it that the pMenuEdit->GetMenuString(i, strMenuText, MF_BYPOSITION); approach works correctly but the GetMenuItemInfo(pMenuEdit->GetSafeHmenu(), i, TRUE, &sInfo); approach does not? According to the debugger the text is empty.
The Microsoft documentation encourage using GetMenuItemInfo instead of GetMenuString.
My mistake?
Text buffers in C always consist of two parts: A pointer to the beginning of the buffer and a count (in elements or bytes). The code in question never supplies a value for the
cchfield of theMENUITEMINFOstructure.Solving this will still cause the code to fail to retrieve the menu item text because the
strMenuTextbuffer is empty. You also must allocate sufficient space (e.g., by supplying a buffer size in the call toCString::GetBuffer()).The standard pattern is to discover the required length first:
and use that information to allocate a sufficiently sized buffer: