📄 menubar.cpp
字号:
MenuBarImpl_t::CreatePopupMenu
Create a popup menu out of a HMENU handle
Parameters:
: HMENU - the submenu containing the items for the popupmenu
: HWND - the menu bar (parent)
: PopupMenu_t& - reference to a popup menu to create and populate
------------------------------------------------------------------------------*/
HRESULT
MenuBarImpl_t::CreatePopupMenu(
HMENU hMenu,
HWND MenuBar,
PopupMenu_t& Menu,
DWORD Style
)
{
//create the new menu
int ItemIndex = 0;
MENUITEMINFO Info = {0};
HRESULT hr;
//create the menu (with our parent window as the menu's parent) offscreen
hr = Menu.Create(
PopupMenu_t::GetWindowClassName(),
NULL,
WS_VISIBLE | WS_TABSTOP | Style,
WS_EX_TOPMOST,
GetParent(MenuBar),
0,
0,
0,
0,
reinterpret_cast<void*>(MenuBar)
);
if (FAILED(hr))
{
return hr;
}
//collect all items from the menu
while (true)
{
WCHAR ItemText[100] = L"";
PopupMenuItem_t* pItem = NULL;
ZeroMemory(&Info, sizeof(Info));
Info.cbSize = sizeof(Info);
Info.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE;
Info.dwTypeData = ItemText;
Info.cch = _countof(ItemText);
if (!GetMenuItemInfo(
hMenu,
ItemIndex,
TRUE, //by position
&Info
))
{
//we're out of items
hr = S_OK;
break;
}
//for now, we only accept strings!
if (Info.fType != MFT_STRING)
{
hr = E_INVALIDARG;
break;
}
pItem = new PopupMenuItem_t();
if (! pItem)
{
hr = E_OUTOFMEMORY;
break;
}
hr = pItem->Initialize(
Info.wID, //Item identifier
Info.dwTypeData //Text
);
if (FAILED(hr))
{
delete pItem;
break;
}
//if there is a submenu, we need to enumerate its items
//and create a new popup menu structure
if (Info.hSubMenu != NULL)
{
PopupMenu_t ItemMenu;
hr = CreatePopupMenu(Info.hSubMenu, MenuBar, ItemMenu);
if (FAILED(hr))
{
//delete the button we previously created
delete pItem;
break;
}
//set the button to have a popup menu
pItem->SetPopupMenu(ItemMenu);
}
//insert the item in our menu
hr = Menu.InsertItem(pItem);
if (FAILED(hr))
{
delete pItem;
break;
}
ItemIndex++;
}
if (FAILED(hr))
{
Menu.Destroy();
return hr;
}
//ensure the item has no visible regions
ShowWindow(Menu, SW_HIDE);
return S_OK;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::CreateInputMenu
Create the Input popup menu
Parameters:
: HWND - the menu bar (parent)
: PopupMenu_t& - reference to a popup menu to create and populate
------------------------------------------------------------------------------*/
HRESULT
MenuBarImpl_t::CreateInputMenu(
HWND MenuBar,
PopupMenu_t& Menu
)
{
HMENU InputMenu = ::CreatePopupMenu();
if (!InputMenu)
{
return CommonUtilities_t::GetErrorFromWin32();
}
static const UINT sc_InputMenuStrings[] =
{
IDS_IMEMENU_NUM,
IDS_IMEMENU_MULTITAP,
IDS_IMEMENU_MULTITAPUPPERCASE,
};
HRESULT hr = S_OK;
BOOL Success;
int Index;
for (Index = 0; Index < _countof(sc_InputMenuStrings); Index++)
{
Success = AppendMenuW(
InputMenu,
MF_STRING,
IDC_IMEMENU_FIRST__ + Index,
CommonUtilities_t::LoadString(
GlobalData_t::s_ModuleInstance,
sc_InputMenuStrings[Index]
)
);
if (!Success)
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
}
// Insert the SIP button
if (Input_IsInputPanelEnabled())
{
Success = AppendMenuW(
InputMenu,
MF_STRING,
IDC_IMEMENU_SIP,
MenuButtonImpl_t::INPUT_BUTTON
);
if (!Success)
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
}
// Load all the symbols after the IME items
const WCHAR* pSymbols = CommonUtilities_t::LoadString(
GlobalData_t::s_ModuleInstance,
IDS_IMEMENU_SYMBOLS
);
if (!pSymbols)
{
hr = CommonUtilities_t::GetErrorFromWin32();
goto exit;
}
// Each symbol is just 1 character
const WCHAR* pSymbolCharacter = pSymbols;
WCHAR SymbolText[2] = {0};
while (pSymbolCharacter && *pSymbolCharacter)
{
SymbolText[0] = *pSymbolCharacter;
Success = AppendMenuW(
InputMenu,
MF_STRING,
IDC_IMEMENU_SYMBOLS_FIRST__ + (pSymbolCharacter - pSymbols),
SymbolText
);
ASSERT(Success);
pSymbolCharacter++;
}
hr = CreatePopupMenu(InputMenu, MenuBar, Menu, VPMS_INPUT);
if (SUCCEEDED(hr))
{
Menu.SetVisibleItems(6);
}
exit:
DestroyMenu(InputMenu);
return hr;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::IsValidMenuItemInfo
Validates a MENUITEMINFO structure (checks for supported features)
Parameters:
: const MENUITEMINFO* - pointer to the MENUITEMINFO structure
------------------------------------------------------------------------------*/
bool
MenuBarImpl_t::IsValidMenuItemInfo(
const MENUITEMINFO* pInfo
)
{
//We only supports changes to
// - Command id of the menu item
// - State of a popup menu item (Checked/Unchecked, Enabled/Grayed)
// - Text of the menu item
// - Popup menu
if (!pInfo ||
(pInfo->cbSize != sizeof(MENUITEMINFO)) ||
!(pInfo->fMask & (MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_SUBMENU)) ||
((pInfo->fMask == MIIM_TYPE) && (
(pInfo->fType != MFT_STRING) ||
(pInfo->dwTypeData == NULL) ||
(pInfo->cch == 0)
)) ||
((pInfo->fMask == MIIM_STATE) &&
(pInfo->fState != MF_ENABLED) &&
!(pInfo->fState & (MF_CHECKED | MF_GRAYED))) ||
((pInfo->fMask & MIIM_SUBMENU) &&
(pInfo->fMask & (MIIM_ID | MIIM_STATE)))
)
{
return false;
}
return true;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::OnSetMenuButtonInfo
Updates a menu button
Parameters:
: UINT - position of the menu button to change
: const MENUITEMINFO* - pointer to a MENUITEMINFO structure
------------------------------------------------------------------------------*/
LRESULT
MenuBarImpl_t::OnSetMenuButtonInfo(
int ButtonIndex,
const MENUITEMINFO* pInfo
)
{
if (static_cast<UINT>(ButtonIndex) >= m_ButtonArray.size())
{
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
if (!IsValidMenuItemInfo(pInfo))
{
return E_INVALIDARG;
}
bool RedrawButton = false;
int ShowCommand = SW_SHOW;
MenuButton_t::ButtonData_t Data;
m_ButtonArray[ButtonIndex].m_Button.GetData(&Data);
//set the text of the button
if (pInfo->fMask & MIIM_TYPE)
{
if (!SetWindowText((HWND)m_ButtonArray[ButtonIndex].m_Button, pInfo->dwTypeData))
{
return CommonUtilities_t::GetErrorFromWin32();
}
RedrawButton = true;
}
if (pInfo->fMask & MIIM_ID)
{
Data.IsMenu = false;
Data.Value.ControlId = pInfo->wID;
ShowCommand = (Data.Value.ControlId ? SW_SHOW : SW_HIDE);
}
if (pInfo->fMask & MIIM_SUBMENU)
{
//if there is a submenu, we need to enumerate its items
//and create a new popup menu structure
PopupMenu_t Menu;
HRESULT hr = CreatePopupMenu(pInfo->hSubMenu, m_hwnd, Menu);
if (FAILED(hr))
{
return hr;
}
//set the button to have a popup menu
Data.IsMenu = true;
Data.Value.PopupMenu = Menu;
}
m_ButtonArray[ButtonIndex].m_Button.SetData(&Data);
if (ShowWindow((HWND)m_ButtonArray[ButtonIndex].m_Button, ShowCommand) &&
(ShowCommand == SW_SHOW) &&
RedrawButton)
{
InvalidateRect((HWND)m_ButtonArray[ButtonIndex].m_Button, NULL, TRUE);
}
ResizeMenuButtons();
return S_OK;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::OnSetMenuItemInfo
Updates a menu item (MenuButton or PopupMenuItem)
Parameters:
: UINT - id of the menu item to change
: const MENUITEMINFO* - pointer to a MENUITEMINFO structure
------------------------------------------------------------------------------*/
LRESULT
MenuBarImpl_t::OnSetMenuItemInfo(
UINT MenuItemId,
const MENUITEMINFO* pInfo
)
{
if (!IsValidMenuItemInfo(pInfo))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -