📄 popupmenu.cpp
字号:
Hide ourself and our parent
------------------------------------------------------------------------------*/
void
PopupMenuImpl_t::HidePopupMenus(
)
{
m_HideMyselfOnly = false;
if (IsWindow((HWND)m_ParentPopup))
{
SendMessage((HWND)m_ParentPopup ,WM_POPUPMENU_HIDEMENUS, 0, 0);
}
m_ParentPopup = (HWND)NULL;
m_ChildPopup = (HWND)NULL;
ShowWindow(m_hwnd, SW_HIDE);
m_TopItem = 0;
m_SelectedItem = -1;
return;
}
/*------------------------------------------------------------------------------
PopupMenuImpl_t::OnItemActivated
Handle an item being "activated" (or chosen via a click, VK_RETURN or flyout)
------------------------------------------------------------------------------*/
void
PopupMenuImpl_t::OnItemActivated(
)
{
if (m_SelectedItem < 0 || m_SelectedItem >= m_Items.size())
{
return;
}
PopupMenuItem_t* pItem = m_Items[m_SelectedItem];
ASSERT(pItem);
HWND FlyoutWindow = pItem->GetPopupMenu();
//if this item doesn't have a flyout menu, send the command id of the
//item to our parent
if (! FlyoutWindow)
{
if (!pItem->IsEnabled())
{
return;
}
UINT Id = pItem->GetId();
//if we are selecting a new IME type then
//hide the SIP before hiding our window!
if (m_IsInputMenu)
{
switch (Id)
{
case IDC_IMEMENU_NUM:
case IDC_IMEMENU_MULTITAP:
case IDC_IMEMENU_MULTITAPUPPERCASE:
//force notify the parent dialog that the SIP should be hidden
Input_HandleEvent(Input_t::ieChangeInputPanelStatus, FALSE);
break;
}
}
//hide all popup menus in this chain of menus
HidePopupMenus();
// If we are the Input menu, handle the command on behalf of applications
if (m_IsInputMenu)
{
bool NeedToUpdateIMEType = true;
Input_t::IMEType_e Type;
switch (Id)
{
case IDC_IMEMENU_SIP:
if (! Input_IsInputPanelVisible())
{
Input_ToggleInputPanel();
}
NeedToUpdateIMEType = false;
break;
case IDC_IMEMENU_MULTITAP:
Type = Input_t::itMultitap;
break;
case IDC_IMEMENU_MULTITAPUPPERCASE:
Type = Input_t::itMultitapUppercase;
break;
case IDC_IMEMENU_NUM:
Type = Input_t::itNum;
break;
default:
{
ASSERT(
(pItem->GetId() >= IDC_IMEMENU_SYMBOLS_FIRST__) &&
(pItem->GetId() <= IDC_IMEMENU_SYMBOLS_LAST__)
);
//send the text to the intended window
const WCHAR *pCharacterToSend = pItem->GetText();
if (pCharacterToSend)
{
Input_HandleEvent(
Input_t::ieInsertSymbol,
reinterpret_cast<Input_t::IPARAM>(*pCharacterToSend)
);
}
NeedToUpdateIMEType = false;
}
break;
}
if (NeedToUpdateIMEType)
{
Input_SetIMEType(Type);
}
return;
}
SendMessage(
GetParent(m_hwnd),
WM_COMMAND,
MAKEWPARAM(pItem->GetId(), 0),
(LPARAM)(HWND)*this
);
return;
}
//we have a child popup window we are responsible for positioning
m_ChildPopup = FlyoutWindow;
RECT ItemRect = {0};
SIZE Dimensions;
POINT Origin;
m_ChildPopup.SetFlyoutParent(*this);
m_ChildPopup.CalculateDimensions(&Dimensions);
GetItemRect(m_SelectedItem, &ItemRect);
//top of the new window = the top of the selected item
Origin.y = ItemRect.top;
//we'll try to position the window so it's on our right
Origin.x = ItemRect.left + (ItemRect.right - ItemRect.left)/2;
MapWindowPoints(
m_hwnd,
GetParent(m_hwnd),
&Origin,
1
);
//adjust the height so it doesn't appear below the menu bar
int AmountBelowMenuBar = Origin.y + Dimensions.cy - Layout_t::MenuBarTop();
if (AmountBelowMenuBar > 0)
{
Origin.y -= AmountBelowMenuBar;
}
//if the x position is offscreen to our right, then move it over our left
if ((Origin.x + Dimensions.cx) > Layout_t::MenuBarRight())
{
Origin.x -= Dimensions.cx;
}
SetWindowPos(
(HWND)m_ChildPopup,
HWND_TOP,
Origin.x,
Origin.y,
Dimensions.cx,
Dimensions.cy,
SWP_SHOWWINDOW
);
SetFocus((HWND)m_ChildPopup);
return;
}
/*------------------------------------------------------------------------------
PopupMenuImpl_t::OnPaint
Handle WM_PAINT messages
------------------------------------------------------------------------------*/
LRESULT
PopupMenuImpl_t::OnPaint(
HDC hdc
)
{
PaintHelper_t paint;
RECT ClientRect = {0};
RECT ItemRect = {0};
HRESULT hr;
hr = paint.Begin(m_hwnd);
ASSERT(SUCCEEDED(hr));
//Parent draws the background for us
ForwardEraseBackground(paint);
GetClientRect(m_hwnd, &ClientRect);
int StartIndex = m_TopItem + (paint.Rect().top / Layout_t::PopupItemHeight());
int EndIndex = m_TopItem + ((paint.Rect().bottom+1) / Layout_t::PopupItemHeight());
paint.SetBkMode(TRANSPARENT);
ce::auto_hpen SelectedPen = CreatePen(PS_SOLID, -1, Colors_t::PopupMenuItemSelectedBorderColor());
ce::auto_hpen Pen = CreatePen(PS_SOLID, -1, Colors_t::PopupMenuItemBorderColor());
ce::auto_hbrush SelectedBrush = CreateSolidBrush(Colors_t::PopupMenuItemSelectedBackgroundColor());
ce::auto_hbrush Brush = CreateSolidBrush(Colors_t::PopupMenuItemBackgroundColor());
Bitmap_t InputBackground;
if (m_IsInputMenu)
{
hr = InputBackground.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_IME_BACKGROUND)
);
ASSERT(SUCCEEDED(hr));
}
int MaxVisibleIndex = GetVisibleItems() - 1;
for (int Index = StartIndex; Index < EndIndex; Index++)
{
if (Index >= m_Items.size())
{
ASSERT(FALSE);
return 0;
}
GetItemRect(Index, &ItemRect);
//fill in the rectangle and the border
paint.SetPen((Index == m_SelectedItem) ? SelectedPen : Pen);
paint.SetBrush((Index == m_SelectedItem) ? SelectedBrush : Brush);
Rectangle(
paint,
ItemRect.left,
ItemRect.top,
ItemRect.right,
ItemRect.bottom
);
if (m_IsInputMenu)
{
//Draw the Input background as centered in the button
ItemRect.left += (Layout_t::ButtonWidth() - InputBackground.Width())/2;
int InputBackgroundWidth = InputBackground.Width() - 2*Layout_t::PopupTextMargin();
if (m_Items[Index]->IsInputMenuItem())
{
Bitmap_t InputIcon;
hr = InputIcon.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_SIP_ICON)
);
ASSERT(SUCCEEDED(hr));
//Draw the sip icon centered in the Input background
TransparentImage(
paint,
ItemRect.left + (InputBackgroundWidth - InputIcon.Width())/2,
(ItemRect.top + ItemRect.bottom - InputIcon.Height())/2,
InputIcon.Width(),
InputIcon.Height(),
InputIcon,
0,
0,
InputIcon.Width(),
InputIcon.Height(),
Colors_t::DefaultTransparentColor()
);
}
else
{
TransparentImage(
paint,
ItemRect.left,
(ItemRect.top + ItemRect.bottom - InputBackground.Height())/2,
InputBackgroundWidth,
InputBackground.Height(),
InputBackground,
0,
0,
InputBackgroundWidth,
InputBackground.Height(),
Colors_t::DefaultTransparentColor()
);
}
}
//draw the text
if (m_Items[Index]->GetText())
{
paint.SetFont(Fonts_t::StandardText());
if (Index == m_SelectedItem)
{
paint.SetTextColor(
(m_Items[Index]->IsEnabled()) ?
Colors_t::PopupMenuItemSelectedTextColor() :
Colors_t::PopupMenuItemDisabledTextColor()
);
}
else
{
paint.SetTextColor(
(m_Items[Index]->IsEnabled()) ?
Colors_t::PopupMenuItemTextColor() :
Colors_t::PopupMenuItemDisabledTextColor()
);
}
ItemRect.left += Layout_t::PopupTextMargin();
hr = paint.DrawText(
m_Items[Index]->GetText(),
-1,
&ItemRect,
DT_VCENTER | DT_LEFT | DT_NOPREFIX
);
ASSERT(SUCCEEDED(hr));
}
//draw cascade arrow
if (m_Items[Index]->GetPopupMenu())
{
Bitmap_t CascadeArrow;
hr = CascadeArrow.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_POPUPMENU_RIGHT_ARROW)
);
ASSERT(SUCCEEDED(hr));
TransparentImage(
paint,
ItemRect.right - CascadeArrow.Width() - Layout_t::PopupRightArrowRightMargin(),
ItemRect.top + Layout_t::PopupRightArrowTopMargin(),
CascadeArrow.Width(),
CascadeArrow.Height(),
CascadeArrow,
0,
0,
CascadeArrow.Width(),
CascadeArrow.Height(),
Colors_t::DefaultTransparentColor()
);
}
if ((Index == m_TopItem) && (m_TopItem > 0))
{
// Draw scroll up arrow
Bitmap_t ScrollArrowUp;
hr = ScrollArrowUp.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_POPUPMENU_SCROLL_ARROW_UP)
);
if (SUCCEEDED(hr))
{
TransparentImage(
paint,
ItemRect.right - ScrollArrowUp.Width() - Layout_t::PopupTextMargin(),
(ItemRect.top + ItemRect.bottom - ScrollArrowUp.Height())/2,
ScrollArrowUp.Width(),
ScrollArrowUp.Height(),
ScrollArrowUp,
0,
0,
ScrollArrowUp.Width(),
ScrollArrowUp.Height(),
Colors_t::DefaultTransparentColor()
);
}
}
else if ((Index == m_TopItem + MaxVisibleIndex) && (Index < m_Items.size() - 1))
{
// Draw scroll down arrow
Bitmap_t ScrollArrowDown;
hr = ScrollArrowDown.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_POPUPMENU_SCROLL_ARROW_DOWN)
);
if (SUCCEEDED(hr))
{
TransparentImage(
paint,
ItemRect.right - ScrollArrowDown.Width() - Layout_t::PopupTextMargin(),
(ItemRect.top + ItemRect.bottom - ScrollArrowDown.Height())/2,
ScrollArrowDown.Width(),
ScrollArrowDown.Height(),
ScrollArrowDown,
0,
0,
ScrollArrowDown.Width(),
ScrollArrowDown.Height(),
Colors_t::DefaultTransparentColor()
);
}
}
}
paint.End();
return 0;
}
/*------------------------------------------------------------------------------
PopupMenuImpl_t::SetMenuItemInfo
Updates a menu item (Text, Id, State or Popup Menu)
------------------------------------------------------------------------------*/
HRESULT
PopupMenuImpl_t::SetMenuItemInfo(
UINT MenuItemId,
const MENUITEMINFO* pInfo
)
{
if (!MenuBarImpl_t::IsValidMenuItemInfo(pInfo))
{
return E_INVALIDARG;
}
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
int Index;
for (Index = 0; Index < m_Items.size(); Index++)
{
HWND FlyoutWindow = m_Items[Index]->GetPopupMenu();
if (FlyoutWindow)
{
if (CommonUtilities_t::ControlTypePopupMenu !=
CommonUtilities_t::GetControlType(FlyoutWindow))
{
ASSERT(0);
return E_UNEXPECTED;
}
PopupMenuImpl_t* pSubMenu = reinterpret_cast<PopupMenuImpl_t*>(
GetWindowLong(FlyoutWindow, GWL_USERDATA)
);
if (!pSubMenu)
{
ASSERT(0);
return E_UNEXPECTED;
}
hr = pSubMenu->SetMenuItemInfo(MenuItemId, pInfo);
if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
{
continue;
}
break;
}
else if (m_Items[Index]->GetId() == MenuItemId)
{
hr = S_OK;
//set the text of the button
if (pInfo->fMask & MIIM_TYPE)
{
ASSERT(pInfo->fType == MFT_STRING);
hr = m_Items[Index]->SetText(pInfo->dwTypeData, pInfo->cch);
}
if (pInfo->fMask & MIIM_ID)
{
m_Items[Index]->SetId(pInfo->wID);
}
if (pInfo->fMask & MIIM_STATE)
{
m_Items[Index]->SetState(pInfo->fState);
}
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 ItemMenu;
hr = MenuBarImpl_t::CreatePopupMenu(
pInfo->hSubMenu,
m_MenuBar,
ItemMenu
);
if (FAILED(hr))
{
return hr;
}
m_Items[Index]->SetPopupMenu(ItemMenu);
}
break;
}
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -