📄 menubar.cpp
字号:
return E_INVALIDARG;
}
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
int ButtonIndex;
//find menu item
for (ButtonIndex = 0; ButtonIndex < m_ButtonArray.size(); ButtonIndex++)
{
MenuButton_t::ButtonData_t Data;
m_ButtonArray[ButtonIndex].m_Button.GetData(&Data);
if (Data.IsMenu)
{
if (CommonUtilities_t::ControlTypePopupMenu !=
CommonUtilities_t::GetControlType(Data.Value.PopupMenu))
{
ASSERT(0);
return E_UNEXPECTED;
}
PopupMenuImpl_t* pPopupMenu = reinterpret_cast<PopupMenuImpl_t*>(
GetWindowLong(Data.Value.PopupMenu, GWL_USERDATA)
);
if (!pPopupMenu)
{
ASSERT(0);
return E_UNEXPECTED;
}
hr = pPopupMenu->SetMenuItemInfo(MenuItemId, pInfo);
if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
{
continue;
}
break;
}
else if (Data.Value.ControlId == MenuItemId)
{
hr = OnSetMenuButtonInfo(ButtonIndex, pInfo);
break;
}
}
if (SUCCEEDED(hr))
{
ResizeMenuButtons();
}
return hr;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::OnShowMenuButton
Shows/hides a menu button
Parameters:
: UINT - id of the menu button to change
: BOOL - indicates whether the button should be visible or not
------------------------------------------------------------------------------*/
HRESULT
MenuBarImpl_t::OnShowMenuButton(
UINT MenuItemId,
BOOL VisibleCommand
)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
//find menu item
int ButtonIndex;
for (ButtonIndex = 0; ButtonIndex < m_ButtonArray.size(); ButtonIndex++)
{
MenuButton_t::ButtonData_t Data;
m_ButtonArray[ButtonIndex].m_Button.GetData(&Data);
if (Data.IsMenu)
{
continue;
}
else if (Data.Value.ControlId == MenuItemId)
{
hr = m_ButtonArray[ButtonIndex].m_Button.Show(VisibleCommand);
ResizeMenuButtons();
break;
}
}
return hr;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::OnResetPositions
Updates the size and position of menu buttons.
------------------------------------------------------------------------------*/
LRESULT
MenuBarImpl_t::OnResetPositions(
void
)
{
int ButtonIndex;
for (ButtonIndex = 0; ButtonIndex < m_ButtonArray.size(); ButtonIndex++)
{
GetWindowRect(
m_ButtonArray[ButtonIndex].m_Button,
&m_ButtonArray[ButtonIndex].m_WindowRect
);
MapWindowRect(NULL, GetParent(m_hwnd), &m_ButtonArray[ButtonIndex].m_WindowRect);
}
return 0;
}
/*------------------------------------------------------------------------------
MenuBarImpl_t::ResizeMenuButtons
Updates the size and position of menu buttons.
------------------------------------------------------------------------------*/
void
MenuBarImpl_t::ResizeMenuButtons(
void
)
{
struct ButtonPosition_t
{
RECT m_WindowRect;
LONG m_NewButtonWidth;
LONG m_GrowDirection;
};
ButtonPosition_t* pButtons = reinterpret_cast<ButtonPosition_t*>(
TrackAlloc(m_ButtonArray.size() * sizeof(ButtonPosition_t))
);
if (pButtons == NULL)
{
return;
}
LONG TotalWidths = 0;
LONG TotalIdealWidths = 0;
bool NeedToResize = false;
bool ShouldUseOriginalPosition = true;
int ButtonIndex;
const int c_LastButtonIndex = m_ButtonArray.size() - 1;
for (ButtonIndex = 0; ButtonIndex < m_ButtonArray.size(); ButtonIndex++)
{
SIZE Dimensions;
// Calculate and cache the minimum size required for each button
m_ButtonArray[ButtonIndex].m_Button.CalculateDimensions(&Dimensions);
pButtons[ButtonIndex].m_NewButtonWidth = Dimensions.cx;
// Accumulate the total width of menu buttons (minimum required
// and ideal - using ButtonWidth metric as the minimum size)
TotalWidths += Dimensions.cx;
TotalIdealWidths += max(Dimensions.cx, Layout_t::ButtonWidth());
GetWindowRect(
m_ButtonArray[ButtonIndex].m_Button,
&pButtons[ButtonIndex].m_WindowRect
);
MapWindowRect(NULL, GetParent(m_hwnd), &pButtons[ButtonIndex].m_WindowRect);
// Compare the new width against the current window and see if any
// change is needed.
if (pButtons[ButtonIndex].m_NewButtonWidth !=
RECTWIDTH(pButtons[ButtonIndex].m_WindowRect))
{
NeedToResize = true;
bool IsPreviousButtonHidden = (ButtonIndex > 0) ? !(
GetWindowLong(
m_ButtonArray[ButtonIndex-1].m_Button,
GWL_STYLE
) & WS_VISIBLE
) : false;
bool IsNextButtonHidden = (ButtonIndex < c_LastButtonIndex) ? !(
GetWindowLong(
m_ButtonArray[ButtonIndex+1].m_Button,
GWL_STYLE
) & WS_VISIBLE
) : false;
// If the next button is hidden, grow to the right if necessary
// If the previous button is hidden, grow to the left if necessary
// Notes:
// - First button can only adjust the right side
// - Last button can only adjust the left side
if (IsNextButtonHidden || (ButtonIndex == 0))
{
pButtons[ButtonIndex].m_GrowDirection = 1;
}
else if (IsPreviousButtonHidden || (ButtonIndex == c_LastButtonIndex))
{
pButtons[ButtonIndex].m_GrowDirection = -1;
}
// Otherwise growing towards the smaller button is preferred.
if (ButtonIndex >= 2)
{
pButtons[ButtonIndex-1].m_GrowDirection =
pButtons[ButtonIndex-2].m_NewButtonWidth -
pButtons[ButtonIndex].m_NewButtonWidth;
}
// It is desired to use the original layout (positions and sizes),
// thus we try to make sure that is still possible even when one or
// more buttons are wider than the default button size.
if (pButtons[ButtonIndex].m_NewButtonWidth > Layout_t::ButtonWidth())
{
ASSERT(pButtons[ButtonIndex].m_NewButtonWidth < 2*Layout_t::ButtonWidth());
// If at least one of the surrounding buttons is hidden, then it is
// assumed that the current button can grow towards the unused space.
ShouldUseOriginalPosition = ShouldUseOriginalPosition &&
(IsPreviousButtonHidden || IsNextButtonHidden);
}
}
}
// Bail out if there is no need to resize
if (!NeedToResize)
{
goto exit;
}
LONG MaxButtonWidth = LONG_MAX;
LONG SpaceBetweenButtons = pButtons[0].m_WindowRect.left;
LONG TotalSpace = pButtons[c_LastButtonIndex].m_WindowRect.right -
pButtons[0].m_WindowRect.left;
// Subtract space between buttons
TotalSpace -= (c_LastButtonIndex * SpaceBetweenButtons);
ASSERT(TotalSpace > TotalWidths);
// If the total accumulated using ideal widths is less than the
// available space, we can still attempt to use original positions.
if (TotalSpace > TotalIdealWidths)
{
ShouldUseOriginalPosition = true;
}
HDWP DWPHandle = BeginDeferWindowPos(m_ButtonArray.size());
if (DWPHandle == NULL)
{
goto exit;
}
LONG NextOrigin = pButtons[0].m_WindowRect.left;
for (ButtonIndex = 0; ButtonIndex < m_ButtonArray.size(); ButtonIndex++)
{
bool ShouldMove = true;
bool ShouldSize = true;
RECT WindowRect;
if (ButtonIndex == 0)
{
ShouldMove = false;
}
if (pButtons[ButtonIndex].m_NewButtonWidth ==
RECTWIDTH(pButtons[ButtonIndex].m_WindowRect))
{
ShouldSize = ShouldUseOriginalPosition;
}
if (ShouldUseOriginalPosition)
{
// Trye to set the original window positions if requested
WindowRect = m_ButtonArray[ButtonIndex].m_WindowRect;
LONG edge;
if (pButtons[ButtonIndex].m_GrowDirection >= 0)
{
PREFAST_ASSERT(ButtonIndex < c_LastButtonIndex);
// Before maximizing button grow to the right, see if this button
// should give up space to the next button.
if (pButtons[ButtonIndex+1].m_GrowDirection < 0)
{
// Calculate the maximum right edge this button can have based
// on a next button trying to grow to the left.
edge = pButtons[ButtonIndex+1].m_WindowRect.right -
pButtons[ButtonIndex+1].m_NewButtonWidth -
SpaceBetweenButtons;
WindowRect.right = min(WindowRect.right, edge);
}
// Calculate the maximum right edge this button should have.
edge = WindowRect.left + pButtons[ButtonIndex].m_NewButtonWidth;
WindowRect.right = max(WindowRect.right, edge);
}
else if (pButtons[ButtonIndex].m_GrowDirection < 0)
{
PREFAST_ASSERT(ButtonIndex > 0);
// Maximize button grow to the left
edge = WindowRect.right - pButtons[ButtonIndex].m_NewButtonWidth;
WindowRect.left = min(WindowRect.left, edge);
}
// Finally adjust the start position for the button based on
// placement for previous buttons.
int delta = NextOrigin - WindowRect.left;
if (delta > 0)
{
WindowRect.left += delta;
WindowRect.right += delta;
}
}
else
{
// If the original layout cannot be used, then use the new widths
WindowRect = pButtons[ButtonIndex].m_WindowRect;
if (ButtonIndex == 0)
{
WindowRect.right = WindowRect.left +
min(pButtons[ButtonIndex].m_NewButtonWidth, MaxButtonWidth);
}
else if (ButtonIndex == c_LastButtonIndex)
{
WindowRect.left = WindowRect.right -
min(pButtons[ButtonIndex].m_NewButtonWidth, MaxButtonWidth);
}
else
{
WindowRect.left = NextOrigin;
WindowRect.right = WindowRect.left +
min(pButtons[ButtonIndex].m_NewButtonWidth, MaxButtonWidth);
}
}
DWPHandle = DeferWindowPos(
DWPHandle,
(HWND)m_ButtonArray[ButtonIndex].m_Button,
NULL,
WindowRect.left,
WindowRect.top,
RECTWIDTH(WindowRect),
RECTHEIGHT(WindowRect),
(ShouldMove ? 0 : SWP_NOMOVE) | (ShouldSize ? 0 : SWP_NOSIZE) | SWP_NOZORDER
);
pButtons[ButtonIndex].m_WindowRect = WindowRect;
if (pButtons[ButtonIndex].m_NewButtonWidth != 0)
{
NextOrigin = WindowRect.right + SpaceBetweenButtons;
}
}
EndDeferWindowPos(DWPHandle);
exit:
if (pButtons)
{
TrackFree(pButtons);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -