📄 menubar.cpp
字号:
}
BOOL CMenuBar::OnMenuInput(MSG& m)
{
ASSERT_VALID(this);
int nMsg = m.message;
CPoint pt = m.lParam;
ScreenToClient(&pt);
int nIndex;
switch (nMsg) {
case WM_MOUSEMOVE:
{
if (pt != m_ptMouse)
{
nIndex = HitTestOnTrack(pt);
if (IsValidIndex(nIndex) && nIndex != m_nCurIndex)
{
// defferent button clicked
m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
UpdateBar(); // clean up
m_nCurIndex = nIndex;
m_nLastIndex=nIndex;
m_bLoop = TRUE; // continue loop
}
m_ptMouse = pt;
}
if (!m_Rect.IsRectEmpty() && !m_pMenu->CheckIfGrayedDraw())
{
POINT pt2;
pt2.x=pt.x;
pt2.y=pt.y;
/*m_pParent->*/ClientToScreen(&pt2);
if (m_hookFrame.m_bTimerSet &&
(pt2.x<m_Rect.left || pt2.x>m_Rect.right ||
pt2.y<m_Rect.top || pt2.y>m_Rect.bottom))
{
m_pParent->KillTimer((UINT)&m_hookFrame);
m_hookFrame.m_bTimerSet=FALSE;
EnableGrayedDraw(FALSE);
}
}
break;
}
break;
case WM_LBUTTONDOWN:
nIndex = HitTestOnTrack(pt);
if(m_hookFrame.m_bTimerSet)
{
m_pParent->KillTimer((UINT)&m_hookFrame);
m_hookFrame.m_bTimerSet=FALSE;
}
if (nIndex != -1 && nIndex == m_nCurIndex) {
// same button clicked
m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
UpdateBar(button, m_nCurIndex);
m_bLoop = FALSE; // out of loop
return TRUE; // eat it!
}
break;
case WM_KEYDOWN:
{
TCHAR vKey = m.wParam;
/*if (m_dwStyle & CBRS_ORIENT_VERT)
{ // if vertical
break; // do nothing
}*/
if (vKey== VK_ESCAPE)
{
if(m_arrDepth<=2)EnableGrayedDraw(FALSE);
}
else if ((vKey == VK_UP ) ||
(vKey == VK_DOWN ))
{
TRACE ("UP/DOWN\n");
m_nDirectionKey=vKey;
//AfxMessageBox("OK");
}
else if ((vKey == VK_LEFT ) ||
(vKey == VK_RIGHT ))
{
m_nDirectionKey=VK_DOWN;
CString str;
str.Format("LEFT/RIGHT m_arrDepth=%d\n",m_arrDepth);
TRACE (str);
}
if ((vKey == VK_LEFT && m_bProcessLeftArrow) ||
(vKey == VK_RIGHT && m_bProcessRightArrow))
{
// no submenu
int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vKey==VK_LEFT);
m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
UpdateBar();
m_nCurIndex = nNewIndex;
if(nNewIndex>=0) m_nLastIndex=nNewIndex;
m_bLoop = TRUE; // continue loop
return TRUE; // eat it!
}
}
break;
case WM_SYSKEYDOWN:
// LTRACE(_T(" m_bIgnore = TRUE\n"));
m_bIgnoreAlt = TRUE; // next SysKeyUp will be ignored
break;
}
return FALSE; // pass along...
}
BOOL CMenuBar::TranslateFrameMessage(MSG* pMsg)
{
ASSERT_VALID(this);
ASSERT(pMsg);
/* if (_GetCmdSentWnd(NULL)->GetSafeHwnd() != GetTopLevelParent()->GetSafeHwnd()) {
if (m_nTrackingState == popup) {
LTRACE(_T("CMenuBar::TranslateMessage - SendMessage\n"));
pMsg->hwnd = _GetCmdSentWnd(NULL)->GetSafeHwnd();
_GetCmdSentWnd(NULL)->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
return TRUE;
}
}
*/
UINT nMsg = pMsg->message;
if (WM_LBUTTONDOWN <= nMsg && nMsg <= WM_MOUSELAST) {
if (pMsg->hwnd != m_hWnd && m_nTrackingState > 0) {
// clicked outside
UpdateBar();
}
}
else if (nMsg == WM_SYSKEYDOWN || nMsg == WM_SYSKEYUP || nMsg == WM_KEYDOWN) {
BOOL bAlt = HIWORD(pMsg->lParam) & KF_ALTDOWN; // Alt key presed?
TCHAR vkey = pMsg->wParam; // + X key
if (vkey == VK_MENU ||
(vkey == VK_F10 && !((GetKeyState(VK_SHIFT) & 0x80000000) ||
(GetKeyState(VK_CONTROL) & 0x80000000) || bAlt))) {
// only alt key pressed
if (nMsg == WM_SYSKEYUP) {
switch (m_nTrackingState) {
case none:
if (m_bIgnoreAlt == TRUE) {
// LTRACE(_T(" ignore ALT key up\n"));
m_bIgnoreAlt = FALSE;
break;
}
if (m_bMDIApp) {
UpdateBar(button, GetNextOrPrevButton(0, FALSE));
}
else {
UpdateBar(button, 0);
}
break;
case button:
UpdateBar();
break;
case buttonmouse:
break; // do nothing
}
}
return TRUE;
}
else if ((nMsg == WM_SYSKEYDOWN || nMsg == WM_KEYDOWN)) {
if (m_nTrackingState == button) {
if (m_dwStyle & CBRS_ORIENT_HORZ) { // if horizontal
switch (vkey) {
case VK_LEFT:
case VK_RIGHT: {
int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vkey == VK_LEFT);
m_nDirectionKey=VK_DOWN;
UpdateBar(button, nNewIndex);
return TRUE;
}
case VK_SPACE:
case VK_UP:
case VK_DOWN:
RefreshMenuPainting(m_pMenu,m_nCurIndex);
TrackPopup(m_nCurIndex);
return TRUE;
case VK_ESCAPE:
EnableGrayedDraw(FALSE,TRUE);
UpdateBar();
return TRUE;
}
}
else { // if vertical
switch (vkey) {
case VK_UP:
case VK_DOWN:{
int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vkey == VK_LEFT);//UP);
m_nDirectionKey=VK_DOWN;
UpdateBar(button, nNewIndex);
return TRUE;
}
case VK_SPACE:
case VK_RIGHT:
case VK_LEFT:
m_nDirectionKey=VK_DOWN;
RefreshMenuPainting(m_pMenu,m_nCurIndex);
TrackPopup(m_nCurIndex);
return TRUE;
case VK_ESCAPE:
EnableGrayedDraw(FALSE,TRUE);
UpdateBar();
return TRUE;
}
}
}
// Alt + X pressed
if ((bAlt || m_nTrackingState == button) && _istalnum(vkey)) {
int nIndex;
if (MapAccessKey(vkey, nIndex) == TRUE) {
UpdateBar();
RefreshMenuPainting(m_pMenu,nIndex);
TrackPopup(nIndex);
return TRUE; // eat it!
}
else if (m_nTrackingState==button && !bAlt) {
// MessageBeep(0); // if you want
return TRUE;
}
}
if (m_nTrackingState > 0) { // unknown key
if (m_nTrackingState != buttonmouse) { // if tracked with mouse, don't update bar
UpdateBar();
}
}
}
}
return FALSE; // pass along...
}
BOOL CMenuBar::MapAccessKey(TCHAR cAccessKey, int& nIndex)
{
for (int i = 0; i < GetItemCount(); ++i) {
// fixing point
TCHAR cKey = m_arrItem[i]->GetAccessKey();
if (toupper(cKey)/*_totupper(cKey)*/ == cAccessKey) {// *****fixed by andi, thanx!*****
nIndex = i;
return TRUE;
}
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CMenuBar layout
int CMenuBar::GetClipBoxLength(BOOL bHorz)
{
CFrameWnd* pFrame = GetTopLevelFrame(); ASSERT_VALID(pFrame);
CRect rcFrame; pFrame->GetWindowRect(rcFrame);
CWnd* pParent = GetParent(); ASSERT_VALID(pParent);
CRect rcParent; pParent->GetWindowRect(rcParent);
const int cxFrameBorder = ::GetSystemMetrics(SM_CXFRAME);
int cxNonClient = cxFrameBorder*2 + m_cxLeftBorder + m_cxRightBorder;
if (m_dwExStyle & CBRS_GRIPPER)
cxNonClient += CX_GRIPPER_ALL;
if (m_dwStyle & CBRS_SIZE_DYNAMIC) {
if (bHorz) {
return rcFrame.Width() - cxNonClient;
}
else {
int nResult = rcParent.Height();
// I don't know the reason of the following code...
nResult -= m_cxRightBorder + m_cxLeftBorder + cyBorder2*2;
if (m_dwExStyle & CBRS_GRIPPER)
nResult -= CY_GRIPPER_ALL;
return nResult;
}
}
else {
CRect rect; GetClientRect(rect);
if (bHorz) {
return rect.Width();
}
else {
return rect.Height();
}
}
}
CSize CMenuBar::CalcLayout(DWORD dwMode, int nLength)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
if (dwMode & LM_HORZDOCK)
ASSERT(dwMode & LM_HORZ);
// make SC_CLOSE button disable
if (m_dwStyle & CBRS_FLOATING)
{
CFrameWnd* pMiniFrame = CControlBar::GetParentFrame();
ASSERT_KINDOF(CMiniFrameWnd, pMiniFrame);
// Don't do this, cause right click menu turns unavairable
// pMiniFrame->ModifyStyle(WS_SYSMENU, 0);
CMenu* pSysMenu = pMiniFrame->GetSystemMenu(FALSE); ASSERT_VALID(pSysMenu);
pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
}
int nCount = GetItemCount();
CSize sizeResult(0, 0);
if (nCount > 0)
{
if (!(m_dwStyle & CBRS_SIZE_FIXED))
{
BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;
if (bDynamic && (dwMode & LM_MRUWIDTH))
{
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_MRUWIDTH\n"));
SizeMenuBar(m_nMRUWidth);
CalcItemLayout(nCount);// added
sizeResult = CalcSize(nCount);
}
else if (bDynamic && (dwMode & LM_HORZDOCK))
{
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_HORZDOCK\n"));
if (IsFloating() || (m_dwStyle & CBRS_ORIENT_VERT)) {
// I can't synchronize horz size on dragging with size on dock bar
// as VC++ developer can't.
SizeMenuBar(32767);
}
else {
// Menu Button wrapped by frame width
SizeMenuBar(GetClipBoxLength(TRUE));
}
CalcItemLayout(nCount);// added
sizeResult = CalcSize(nCount);
if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_VERT)) {
if (m_pDockContext->m_pDC) {// while dragging (m_pDockContext->m_bDragging is helpless)
sizeResult.cx = GetClipBoxLength(TRUE);
}
}
}
else if (bDynamic && (dwMode & LM_VERTDOCK))
{
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_VERTDOCK\n"));
//SizeMenuBar(0);
CalcItemLayout(nCount, TRUE);// added
sizeResult = CalcVertDockSize(nCount);
if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_HORZ)) {
if (m_pDockContext->m_pDC) {// while dragging
sizeResult.cy = GetClipBoxLength(FALSE);//GetrcParent.Height() - m_cxRightBorder - m_cxLeftBorder;
}
}
}
else if (bDynamic && (nLength != -1))
{
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---nLength != -1\n"));
CRect rect; rect.SetRectEmpty();
_CalcInsideRect(rect, (dwMode & LM_HORZ));
BOOL bVert = (dwMode & LM_LENGTHY);
int nLen = nLength + (bVert ? rect.Height() : rect.Width());
SizeMenuBar(nLen, bVert);
CalcItemLayout(nCount, bVert);// added
sizeResult = CalcSize(nCount);
}
else if (bDynamic && (m_dwStyle & CBRS_FLOATING))
{
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---CBRS_FLOATING\n"));
SizeMenuBar(m_nMRUWidth);
CalcItemLayout(nCount);// added
sizeResult = CalcSize(nCount);
}
else
{
if (!bDynamic) {
InvalidateRect(NULL);
goto Junk;
}
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---other\n"));
BOOL bVert = !(dwMode & LM_HORZ);
SizeMenuBar(GetClipBoxLength(TRUE));
CalcItemLayout(nCount, bVert);// added
if (bVert) {
InvalidateRect(NULL);// draw forcefully for captions
sizeResult = CalcVertDockSize(nCount);
// DockBar not replaced yet, so I can't get precise size
sizeResult.cy = 10000;
}
else {
sizeResult = CalcSize(nCount);
sizeResult.cx = GetClipBoxLength(TRUE);
}
}
}
else {// CBRS_SIZE_FIXED
LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_FIXED)\n"));
Junk:
BOOL bVert = !(dwMode & LM_HORZ);
SizeMenuBar(32767);
CalcItemLayout(nCount, bVert);// added
if (bVert) {
sizeResult = CalcVertDockSize(nCount);
}
else {
sizeResult = CalcSize(nCount);
}
}
if (dwMode & LM_COMMIT)
{
LTRACE(_T("CMenuBar::CalcLayout---LM_COMMIT\n"));
int nControlCount = 0;
BOOL bIsDelayed = m_bDelayedButtonLayout;
m_bDelayedButtonLayout = FALSE;
if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
m_nMRUWidth = sizeResult.cx;
//CalcItemLayout(nCount, dwMode);
m_bDelayedButtonLayout = bIsDelayed;
}
}
//BLOCK: Adjust Margins
{
CRect rect; rect.SetRectEmpty();
_CalcInsideRect(rect, (dwMode & LM_HORZ));
sizeResult.cy -= rect.Height();
sizeResult.cx -= rect.Width();
CSize size = CControlBar::CalcFixedLayout((dwMode & LM_STRETCH), (dwMode & LM_HORZ));
sizeResult.cx = max(sizeResult.cx, size.cx);
sizeResult.cy = max(sizeResult.cy, size.cy);
}
return sizeResult;
}
CSize CMenuBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
LTRACE(_T("CMenuBar::CalcFixedLayout\n"));
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
DWORD dwMode = bStretch ? LM_STRETCH : 0;
dwMode |= bHorz ? LM_HORZ : 0;
return CalcLayout(dwMode);
}
CSize CMenuBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
LTRACE(_T("CMenuBar::CalcDynamicLayout\n"));
if ((nLength == -1) && !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
((dwMode & LM_HORZDOCK) || (dwMode & LM_VERTDOCK)))
{
LTRACE(_T(" FixedLayout\n"));
return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
}
return CalcLayout(dwMode, nLength);
}
// set m_bWrapped by nWidth
int CMenuBar::WrapMenuBar(int nCount, int nWidth)
{
// LTRACE(_T("CMenuBar::WrapMenuBar\n"));
int nResult = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -