📄 rtmenu.cpp
字号:
rc.right -= TEXTPADDING+4;
pDC->DrawText (sShortCut, rc, DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
}
if ( GetChecked() )
{
COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CPenDC pen (*pDC, crHighLight);
CBrushDC brush (*pDC, crBackImg = GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) :
(bSelected ? HLS_TRANSFORM (crHighLight, +50, -50) : HLS_TRANSFORM (crHighLight, +70, -57)));
pDC->Rectangle (CRect (pRect->left+1, pRect->top+1, pRect->left+IMGWIDTH+4, pRect->bottom-1));
}
if ( m_ImgDesc.m_hImgList != NULL && m_ImgDesc.m_nIndex != -1 )
{
bool bOver = !GetDisabled() && bSelected;
if ( GetDisabled() || (bSelected && !GetChecked()) )
{
HICON hIcon = ImageList_ExtractIcon (NULL, m_ImgDesc.m_hImgList, m_ImgDesc.m_nIndex);
pDC->DrawState (CPoint (pRect->left + ( bOver ? 4 : 3 ), rc.top + ( bOver ? 4 : 3 )),
CSize (IMGWIDTH, IMGHEIGHT), hIcon, DSS_MONO,
CBrush (bOver ? HLS_TRANSFORM (::GetSysColor (COLOR_HIGHLIGHT), +50, -66) : HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0)));
DestroyIcon (hIcon);
}
if ( !GetDisabled() )
{
::ImageList_Draw (m_ImgDesc.m_hImgList, m_ImgDesc.m_nIndex, pDC->m_hDC,
pRect->left+( (bSelected && !GetChecked()) ? 2 : 3 ), rc.top+( (bSelected && !GetChecked()) ? 2 : 3 ), ILD_TRANSPARENT);
}
}
else if ( GetChecked() )
{
// Draw the check mark
rc.left = pRect->left+IMGWIDTH/4+1;
rc.right = rc.left + IMGWIDTH-1;
if ( GetRadio() )
{
CPoint ptCenter = rc.CenterPoint();
COLORREF crBullet = GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -27, 0) : ::GetSysColor (COLOR_MENUTEXT);
CPenDC pen (*pDC, crBullet);
CBrushDC brush (*pDC, crBullet);
pDC->Ellipse (CRect (ptCenter.x-4, ptCenter.y-3, ptCenter.x+3, ptCenter.y+4));
pDC->SetPixel (ptCenter.x+1, ptCenter.y+2, crBackImg);
}
else
{
pDC->SetBkColor (crBackImg);
HBITMAP hBmp = LoadBitmap (NULL, MAKEINTRESOURCE(OBM_CHECK));
pDC->DrawState (CPoint (rc.left,rc.top+3), CSize(rc.Size()), hBmp, DSS_NORMAL, (HBRUSH)NULL);
DeleteObject (hBmp);
}
}
}
}
}
return bMenuBarItemSelected;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
CMap <int, int, CString, CString&> CRTMenu::ms_sCaptions;
CMap <HMENU, HMENU, CString, CString&> CRTMenu::ms_sSubMenuCaptions;
CMap <int, int, CImgDesc, CImgDesc&> CRTMenu::ms_Images;
CMap <HMENU, HMENU, CImgDesc, CImgDesc&> CRTMenu::ms_SubMenuImages;
CBitmap* CRTMenu::m_MenuBarBitmap[5] = {NULL,NULL,NULL,NULL,NULL};
UINT CRTMenu::m_MenuBarBitmapDrawMode[5] = {0,0,0,0,0};
CBitmap* CRTMenu::m_MenuItemBitmap[5] = {NULL,NULL,NULL,NULL,NULL};
UINT CRTMenu::m_MenuItemBitmapDrawMode[5] = {0,0,0,0,0};
BOOL CRTMenu::m_bEnableSkin = FALSE;
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::EnableSkin(BOOL IsEnable)
{
m_bEnableSkin = IsEnable;
}
void CRTMenu::SetXPLookNFeel (CWnd* pWnd, BOOL bXPLook)
{
if ( bXPLook )
{
::SetProp (pWnd->GetSafeHwnd(), _WndPropName_MenuXP, (HANDLE)TRUE);
}
else
{
::RemoveProp (pWnd->GetSafeHwnd(), _WndPropName_MenuXP);
}
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenu::GetXPLookNFeel (const CWnd* pWnd)
{
return ::GetProp (pWnd->GetSafeHwnd(), _WndPropName_MenuXP) != NULL;
}
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::UpdateMenuBar (CWnd* pWnd)
{
if ( GetXPLookNFeel (pWnd) )
{
HMENU hMenu = pWnd->GetMenu()->GetSafeHmenu();
if ( hMenu != NULL )
{
SetXPLookNFeel (pWnd, hMenu, true, true);
}
}
}
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::SetXPLookNFeel (CWnd* pWnd, HMENU hMenu, BOOL bXPLook, BOOL bMenuBar)
{
if ( !bXPLook )
{
// TODO: Remove the ownerdraw style ?
return;
}
// TRACE(_T("Referenced captions : %i\n"), ms_sCaptions.GetCount()+ms_sSubMenuCaptions.GetCount());
// Clean up old references...
// ... for captions
POSITION pos = ms_sSubMenuCaptions.GetStartPosition();
while ( pos != NULL )
{
HMENU hSubMenu;
CString sBuff;
ms_sSubMenuCaptions.GetNextAssoc (pos, hSubMenu, sBuff);
if ( !::IsMenu (hSubMenu) )
{
ms_sSubMenuCaptions.RemoveKey (hSubMenu);
}
}
// ... for images
pos = ms_SubMenuImages.GetStartPosition();
while ( pos != NULL )
{
HMENU hSubMenu;
CImgDesc ImgDesc;
ms_SubMenuImages.GetNextAssoc (pos, hSubMenu, ImgDesc);
if ( !::IsMenu (hSubMenu) )
{
ms_SubMenuImages.RemoveKey (hSubMenu);
}
}
ASSERT(hMenu != NULL);
int nItemCount = ::GetMenuItemCount (hMenu);
MENUITEMINFO mii = { sizeof MENUITEMINFO, MIIM_ID|MIIM_TYPE|MIIM_SUBMENU };
CClientDC cDC (AfxGetMainWnd());
TEXTMETRIC tm;
CFontDC font (cDC, DEFAULT_GUI_FONT);
cDC.GetTextMetrics (&tm);
int nHeight = max(tm.tmHeight+2,IMGHEIGHT)+4;
int nSepHeight = tm.tmHeight/2+2;
int nCaptionLength = 0;
int nShortCutLength = 0;
CPtrList* pListControlBars = NULL;
if ( pWnd != NULL && !bMenuBar )
{
if ( pWnd->IsKindOf (RUNTIME_CLASS(CMDIFrameWnd)) )
{
CMDIChildWnd* pActiveChild = ((CMDIFrameWnd*)pWnd)->MDIGetActive();
if ( pActiveChild != NULL && pActiveChild->GetSystemMenu (false)->GetSafeHmenu() == hMenu )
{
CRTMenuItem::ms_rcMRUMenuBarItem.SetRectEmpty();
return;
}
}
if ( pWnd->IsKindOf (RUNTIME_CLASS(CFrameWnd)) && !((CFrameWnd*)pWnd)->m_listControlBars.IsEmpty() )
{
pListControlBars = &((CFrameWnd*)pWnd)->m_listControlBars;
}
else
{
CFrameWnd* pFrame = pWnd->GetParentFrame();
if ( pFrame != NULL && pFrame->IsKindOf (RUNTIME_CLASS(CMDIChildWnd)) )
{
pFrame = pFrame->GetParentFrame();
}
if ( pFrame != NULL )
{
pListControlBars = &pFrame->m_listControlBars;
}
}
}
for ( int i = 0; i < nItemCount; i++ )
{
TCHAR sCaption[256] = _T("");
mii.dwTypeData = sCaption;
mii.cch = 255;
mii.fMask &= ~MIIM_DATA;
::GetMenuItemInfo (hMenu, i, true, &mii);
if ( (mii.fType & MFT_OWNERDRAW) == 0 && (!bMenuBar || (mii.fType & MFT_BITMAP) == 0) )
{
mii.fType |= MFT_OWNERDRAW;
if ( bMenuBar )
{
CRect rcText (0, 0, 1000, 0);
cDC.DrawText (sCaption, (int)_tcslen (sCaption), rcText, DT_SINGLELINE|DT_LEFT|DT_CALCRECT);
mii.dwItemData = MAKELONG(MAKEWORD(0, 0), rcText.Width());
mii.fMask |= MIIM_DATA;
}
::SetMenuItemInfo (hMenu, i, true, &mii);
if ( (mii.fType & MFT_SEPARATOR) == 0 )
{
CString sBuff(sCaption);
if ( mii.hSubMenu != NULL )
{
ms_sSubMenuCaptions.SetAt (mii.hSubMenu, sBuff);
}
else
{
ms_sCaptions.SetAt (mii.wID, sBuff);
}
if ( pListControlBars != NULL )
{
POSITION pos = pListControlBars->GetHeadPosition();
while ( pos != NULL )
{
CControlBar* pBar = (CControlBar*)pListControlBars->GetNext (pos);
ASSERT(pBar != NULL);
TCHAR sClassName[256];
::GetClassName (pBar->m_hWnd, sClassName, lengthof (sClassName));
if ( !_tcsicmp (sClassName, _T("ToolbarWindow32")) )
{
TBBUTTONINFO tbbi = { sizeof(TBBUTTONINFO), TBIF_COMMAND|TBIF_IMAGE };
if ( pBar->SendMessage (TB_GETBUTTONINFO, mii.wID, (LPARAM)&tbbi) != -1 &&
(UINT)tbbi.idCommand == mii.wID && tbbi.iImage != -1 )
{
CImgDesc imgDesc ((HIMAGELIST)pBar->SendMessage (TB_GETIMAGELIST, 0, 0), tbbi.iImage);
if ( mii.hSubMenu != NULL )
{
ms_SubMenuImages.SetAt (mii.hSubMenu, imgDesc);
}
else
{
ms_Images.SetAt (mii.wID, imgDesc);
}
break;
}
}
}
}
}
}
if ( !bMenuBar )
{
CRTMenuItem mnuItem (hMenu, i);
int nWidth = mnuItem.GetCaptionWidth (&cDC);
if ( nWidth > nCaptionLength )
{
nCaptionLength = nWidth;
}
nWidth = mnuItem.GetShortCutWidth (&cDC);
if ( nWidth > nShortCutLength )
{
nShortCutLength = nWidth;
}
}
}
if ( !bMenuBar )
{
for ( int j = 0; j < nItemCount; j++ )
{
mii.fMask = MIIM_TYPE;
::GetMenuItemInfo (hMenu, j, true, &mii);
if ( (mii.fType & MFT_SEPARATOR) == 0 )
{
mii.dwItemData = MAKELONG(MAKEWORD(nHeight, nShortCutLength), nCaptionLength);
}
else
{
mii.dwItemData = nSepHeight;
}
mii.fMask = MIIM_DATA;
::SetMenuItemInfo (hMenu, j, true, &mii);
}
}
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenu::IsOwnerDrawn (HMENU hMenu)
{
MENUITEMINFO mii = { sizeof MENUITEMINFO, MIIM_TYPE };
::GetMenuItemInfo (hMenu, 0, true, &mii);
return (mii.fType & MFT_OWNERDRAW) != 0;
}
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::SetMRUMenuBarItem (RECT& rc)
{
CRTMenuItem::ms_rcMRUMenuBarItem = rc;
}
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::SetMenuItemImage (UINT nID, HIMAGELIST hImgList, int nIndex)
{
CImgDesc imgDesc (hImgList, nIndex);
ms_Images.SetAt (nID, imgDesc);
}
void CRTMenu::SetMenuBarBitmap(CBitmap* MenuBarBitmap[],UINT DrawMode[])
{
for(int i = 0; i < 5; i ++)
{
m_MenuBarBitmap[i] = MenuBarBitmap[i];
m_MenuBarBitmapDrawMode[i] = DrawMode[i];
}
}
void CRTMenu::SetMenuItemBitmap(CBitmap* MenuItemBitmap[],UINT DrawMode[])
{
for(int i = 0; i < 5; i ++)
{
m_MenuItemBitmap[i] = MenuItemBitmap[i];
m_MenuItemBitmapDrawMode[i] = DrawMode[i];
}
}
///////////////////////////////////////////////////////////////////////////////
void CRTMenu::OnMeasureItem (MEASUREITEMSTRUCT* pMeasureItemStruct)
{
if ( pMeasureItemStruct->CtlType == ODT_MENU )
{
pMeasureItemStruct->itemHeight = LOBYTE(LOWORD(pMeasureItemStruct->itemData));
if ( pMeasureItemStruct->itemHeight == 0 )
{
// This is a menubar item
pMeasureItemStruct->itemWidth = HIWORD(pMeasureItemStruct->itemData) + TEXTPADDING_MNUBR;
}
else
{
pMeasureItemStruct->itemWidth = IMGWIDTH + IMGPADDING + HIWORD(pMeasureItemStruct->itemData) + TEXTPADDING + HIBYTE(LOWORD(pMeasureItemStruct->itemData)) + TEXTPADDING + 4;
}
}
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenu::OnDrawItem (DRAWITEMSTRUCT* pDrawItemStruct, HWND hWnd)
{
if ( pDrawItemStruct->CtlType != ODT_MENU )
{
return false;
}
ASSERT (pDrawItemStruct->CtlType == ODT_MENU);
CBufferDC cDC (pDrawItemStruct->hDC, pDrawItemStruct->rcItem);
CRTMenuItem item ((HMENU)pDrawItemStruct->hwndItem, pDrawItemStruct->itemID, false);
CFontDC font (cDC, DEFAULT_GUI_FONT);
if ( item.Draw (&cDC, &pDrawItemStruct->rcItem, (pDrawItemStruct->itemState&ODS_SELECTED)!=0,LOBYTE(LOWORD(pDrawItemStruct->itemData))==0, (pDrawItemStruct->itemState&ODS_HOTLIGHT)!=0, (pDrawItemStruct->itemState&ODS_INACTIVE)!=0, (pDrawItemStruct->itemState&ODS_NOACCEL)!=0) )
{
CRect rc;
::GetMenuItemRect (hWnd, (HMENU)pDrawItemStruct->hwndItem, 0, rc);
::ClientToScreen (hWnd, CRTMenuItem::ms_rcMRUMenuBarItem);
CRTMenuItem::ms_rcMRUMenuBarItem.top = rc.top;
CRTMenuItem::ms_rcMRUMenuBarItem.bottom = rc.bottom;
if ( CWnd::FromHandle (hWnd)->IsKindOf (RUNTIME_CLASS(CDialog)) )
{
CRTMenuItem::ms_rcMRUMenuBarItem.OffsetRect (1, 0);
}
}
CRTMenuItem::ms_nCheck++;
return true;
}
///////////////////////////////////////////////////////////////////////////////
LRESULT CRTMenu::OnMenuChar (HMENU hMenu, UINT nChar, UINT nFlags)
{
if ( (nFlags & (MF_POPUP|MF_SYSMENU)) == MF_POPUP || nFlags == 0 )
{
int nItemCount = ::GetMenuItemCount (hMenu);
nChar = toupper (nChar);
for ( int i = 0; i < nItemCount; i++ )
{
CRTMenuItem mnuItem (hMenu, i);
CString sCaption;
mnuItem.GetCaption (sCaption);
sCaption.MakeUpper();
for ( int nPos = sCaption.GetLength()-2; nPos >= 0; nPos-- )
{
if ( sCaption[nPos] == '&' && (UINT)toupper (sCaption[nPos+1]) == nChar &&
(nPos == 0 || sCaption[nPos-1] != '&') )
{
return MAKELRESULT(i,2);
}
}
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -