?? cbmpmenu.cpp
字號(hào):
COLORREF OldColor = dc.SetTextColor(m_ColorText);
dc.SetBkMode(TRANSPARENT);
rect2.left = 2;
dc.DrawText ( GetTitle(), &rect2, DT_BOTTOM | DT_LEFT | DT_SINGLELINE );
// restore old text color
dc.SetTextColor( OldColor);
// restore old font
dc.SelectObject(OldFont);
// clean up
font.DeleteObject();
*/
//Fill the blank space with whiteness
dc.FillSolidRect(&rect, GetSysColor(COLOR_BTNHIGHLIGHT));
//draw the vertical bitmap if required
if(m_hBitmap)
{
CDC memDC;
memDC.CreateCompatibleDC(&dc);
HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC.GetSafeHdc(), m_hBitmap);
BITMAP bitmap;
GetObject(m_hBitmap, sizeof(bitmap), &bitmap);
//draw the bitmap
if(m_bStretchBmp)
dc.StretchBlt(0, 0, m_nTBOffSet, rect.Height(), &memDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight,
SRCCOPY);
else
{
//draw using pattern brush
HBRUSH hPatternBr = CreatePatternBrush(m_hBitmap);
RECT rect1={0, 0, m_nTBOffSet, rect.Height()};
FillRect(dc.GetSafeHdc(), &rect1, hPatternBr);
DeleteObject(hPatternBr);
}
//restore objects
memDC.SelectObject(hOldBmp);
memDC.DeleteDC();
}
}
//Used to place the menu window
void CBmpMenu::PositionMenuWindow(CPoint pt, CRect* pItemRect, CRect menuRect)
{
CRect deskRect;
GetDesktopWindow()->GetWindowRect(&deskRect);
//Check if this is a submenu...then we need to check either right top or right bottom point of menuRect
if(pItemRect)
{
if(PositionSubMenu(CPoint(pItemRect->right, pItemRect->top), menuRect, TRUE, TRUE) == FALSE)
{
if(PositionSubMenu(CPoint(pItemRect->right, pItemRect->bottom), menuRect, TRUE, FALSE) == FALSE)
{
if(PositionSubMenu(CPoint(pItemRect->left, pItemRect->top), menuRect, FALSE, TRUE) == FALSE)
{
PositionSubMenu(CPoint(pItemRect->left, pItemRect->bottom), menuRect, FALSE, FALSE);
}
}
}
return;
}
//we need to check which position is best for showing menu
//check for left top alignment with pt
if((pt.x+menuRect.Width() < deskRect.right) &&
(pt.y+menuRect.Height() < deskRect.bottom))
{
MoveWindow(pt.x, pt.y, menuRect.Width(), menuRect.Height());
}
else //right top
if((pt.x-menuRect.Width() > deskRect.left) &&
(pt.y+menuRect.Height() < deskRect.bottom))
{
MoveWindow(pt.x-menuRect.Width(), pt.y, menuRect.Width(), menuRect.Height());
}
else
//check for left bottom alignment with pt
if((pt.x+menuRect.Width() < deskRect.right) &&
(pt.y-menuRect.Height() > deskRect.top))
{
MoveWindow(pt.x, pt.y-menuRect.Height(), menuRect.Width(), menuRect.Height());
}
else
//check for right bottom alignment with pt
if((pt.x-menuRect.Width() > deskRect.left) &&
(pt.y-menuRect.Height() > deskRect.top))
{
MoveWindow(pt.x-menuRect.Width(), pt.y-menuRect.Height(), menuRect.Width(), menuRect.Height());
}
else //left top is default
MoveWindow(pt.x, pt.y, menuRect.Width(), menuRect.Height());
}
BOOL
CBmpMenu::PositionSubMenu(CPoint pt, CRect menuRect, BOOL bRtAlign, BOOL bDnAlign)
{
CRect deskRect;
GetDesktopWindow()->GetWindowRect(&deskRect);
if(bRtAlign && bDnAlign)
{
if((pt.x+menuRect.Width() < deskRect.right) &&
(pt.y+menuRect.Height() < deskRect.bottom))
{
MoveWindow(pt.x, pt.y, menuRect.Width(), menuRect.Height());
}
else
{
return FALSE;
}
}
if(bRtAlign && ! bDnAlign)
{
if((pt.x+menuRect.Width() < deskRect.right) &&
(pt.y-menuRect.Height() > deskRect.top))
{
MoveWindow(pt.x, pt.y-menuRect.Height(), menuRect.Width(), menuRect.Height());
}
else
{
return FALSE;
}
}
if(!bRtAlign && bDnAlign)
{
if((pt.x-menuRect.Width() > deskRect.left) &&
(pt.y+menuRect.Height() < deskRect.bottom))
{
MoveWindow(pt.x-menuRect.Width(), pt.y, menuRect.Width(), menuRect.Height());
}
else
{
return FALSE;
}
}
if(!bRtAlign && !bDnAlign)
{
if((pt.x-menuRect.Width() > deskRect.left) &&
(pt.y-menuRect.Height() > deskRect.top))
{
MoveWindow(pt.x-menuRect.Width(), pt.y-menuRect.Height(), menuRect.Width(), menuRect.Height());
}
else
{
return FALSE;
}
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// MenuToolBar
MenuToolBar::MenuToolBar()
{
m_nLastLBDownIndex = -1;
m_nLastHoverIndex = -1;
m_oHoverPt.x = -1;
m_oHoverPt.y = -1;
m_nSelectedItem = -1;
}
MenuToolBar::~MenuToolBar()
{
m_oMenuFont.DeleteObject();
}
BEGIN_MESSAGE_MAP(MenuToolBar, CToolBar)
//{{AFX_MSG_MAP(MenuToolBar)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_KEYDOWN()
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW , OnCustomDrawNotify)
ON_WM_MOUSEMOVE()
ON_WM_CHAR()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_LBUTTONDOWNAFTER, OnPostLbuttonMsg)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// MenuToolBar message handlers
void MenuToolBar::OnCustomDrawNotify(LPARAM lParam, LRESULT* pResult )
{
LPNMTBCUSTOMDRAW lpNMCustomDraw = (LPNMTBCUSTOMDRAW) lParam;
if(!lParam)
return;
if(lpNMCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW ; //we need CDDS_ITEMPREPAINT notifications
return;
}
if(lpNMCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
MENUITEMINFO menuInfo = *(MENUITEMINFO*)(lpNMCustomDraw->nmcd.lItemlParam);
CRect rcItem = lpNMCustomDraw->nmcd.rc;
CDC dc;
CFont* pOldFont;
dc.Attach(lpNMCustomDraw->nmcd.hdc);
//Check if this is a hot item
if(lpNMCustomDraw->nmcd.uItemState & CDIS_HOT)
{
lpNMCustomDraw->clrText = GetSysColor(COLOR_HIGHLIGHTTEXT);
lpNMCustomDraw->clrHighlightHotTrack = GetSysColor(COLOR_HIGHLIGHT);
//check if last hot item was same as this hot item. If not then we need to send notification
//to owner window
if(m_nSelectedItem != (int)lpNMCustomDraw->nmcd.dwItemSpec)
{
int ndx = lpNMCustomDraw->nmcd.dwItemSpec;
//for submenus we need to send index of this item rather than Command Id
if(menuInfo.hSubMenu)
{
ndx = CommandToIndex(lpNMCustomDraw->nmcd.dwItemSpec);
menuInfo.fState = MF_POPUP;
}
//Send WM_MENUSELECT notification message to owner window
((CBmpMenu*)GetParent())->m_pOwnerWnd->SendMessage(WM_MENUSELECT,
MAKEWPARAM(ndx, menuInfo.fState),
(LPARAM)((CBmpMenu*)GetParent())->m_hMenu);
}
//當(dāng)選中時(shí)顯示立體漸變色菜單
CRect rc=rcItem;
rc.left =rcItem.left +22;
((CBmpMenu*)GetParent())->PaintGradiantRect(&dc, rc, RGB(0,0,255), RGB(160,180,100), true, true);
dc.Draw3dRect(&rc,::GetSysColor(COLOR_3DDKSHADOW),::GetSysColor(COLOR_3DHILIGHT));
//當(dāng)選中時(shí)將左側(cè)圖標(biāo)突出顯示
CRect rcIcon=rcItem;
rcIcon.left +=1;
rcIcon.right =rcItem.left +20;
dc.Draw3dRect(&rcIcon,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DDKSHADOW));
//store th hot item index
m_nSelectedItem = lpNMCustomDraw->nmcd.dwItemSpec;
}
else
{
//沒(méi)選中時(shí),左側(cè)圖標(biāo)平面顯示
CRect rcIcon=rcItem;
rcIcon.left +=1;
rcIcon.right =rcItem.left +20;
dc.Draw3dRect(&rcIcon,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE));
lpNMCustomDraw->clrText = GetSysColor(COLOR_MENUTEXT);
lpNMCustomDraw->clrHighlightHotTrack = GetSysColor(COLOR_MENU);
}
if(menuInfo.fState & MF_GRAYED)
{
lpNMCustomDraw->clrText = GetSysColor(COLOR_GRAYTEXT);
//this is required for checkmark color
dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
}
else
dc.SetTextColor(GetSysColor(COLOR_MENUTEXT));
//leave a one pixel gap
rcItem.left++;
//draw the background rectangle first
// dc.FillSolidRect(rcItem, lpNMCustomDraw->clrHighlightHotTrack); //去掉,用漸變色填充
//Select menu font
pOldFont = dc.SelectObject(&m_oMenuFont);
//check if we need to draw the checkmark for this menu item
if(menuInfo.fState & MF_CHECKED)
{
CRect CheckRect = rcItem;
CheckRect.right = CheckRect.left + CheckRect.Height();
//draw the checkmarked image
Draw3DCheckmark(dc, CheckRect, lpNMCustomDraw->nmcd.uItemState & CDIS_HOT,
menuInfo.hbmpChecked, TRUE, menuInfo.fState & MF_GRAYED);
}
else
{
//if unchecked bmp is provided
if(menuInfo.hbmpUnchecked)
{
CRect CheckRect = rcItem;
CheckRect.right = CheckRect.left + CheckRect.Height();
//draw the UnCheckmarked image
Draw3DCheckmark(dc, CheckRect, lpNMCustomDraw->nmcd.uItemState & CDIS_HOT,
menuInfo.hbmpUnchecked, FALSE, menuInfo.fState & MF_GRAYED);
}
}
//draw the background rectangle for this button and then draw menu text
dc.SetTextColor(lpNMCustomDraw->clrText);
dc.SetBkMode(TRANSPARENT);
//calculate text rectangle. The width of Checkmark has to be added
rcItem.left += rcItem.Height() + 5;
//Check if the item is disabled or grayed. Then we need to draw embossed text
if((menuInfo.fState & MF_GRAYED) && !(lpNMCustomDraw->nmcd.uItemState & CDIS_HOT))
{
rcItem.OffsetRect(1,1);
dc.SetTextColor(GetSysColor(COLOR_3DHILIGHT));
dc.DrawText(menuInfo.dwTypeData, rcItem, DT_SINGLELINE|DT_LEFT|DT_VCENTER);
dc.SetTextColor(lpNMCustomDraw->clrText);
rcItem.OffsetRect(-1,-1);
}
//draw the text
dc.DrawText(menuInfo.dwTypeData, rcItem, DT_SINGLELINE|DT_LEFT|DT_VCENTER);
dc.SelectObject(pOldFont);
//draw the popup arrow mark
if(menuInfo.hSubMenu)
{
rcItem.left = rcItem.right-GetSystemMetrics(SM_CXMENUCHECK)*3/4;
rcItem.right = rcItem.left + GetSystemMetrics(SM_CXMENUCHECK);
CRect arrowRect = rcItem;
arrowRect.top += (rcItem.Height()-GetSystemMetrics(SM_CXMENUCHECK))/2;
arrowRect.bottom = arrowRect.top + GetSystemMetrics(SM_CXMENUCHECK);
arrowRect.left += GetSystemMetrics(SM_CXMENUCHECK)*3/10;
arrowRect.top += GetSystemMetrics(SM_CXMENUCHECK)*3/10;
arrowRect.bottom -= GetSystemMetrics(SM_CXMENUCHECK)*3/10;
POINT points[3];
points[0].x = arrowRect.left;
points[0].y = arrowRect.top;
points[1].x = arrowRect.left+arrowRect.Width()/2;
points[1].y = arrowRect.top+arrowRect.Height()/2;
points[2].x = points[0].x;
points[2].y = points[1].y + arrowRect.Height()/2;
CPen oPen(PS_SOLID, 1, lpNMCustomDraw->clrText), *pOldPen;
pOldPen=dc.SelectObject(&oPen);
dc.MoveTo(points[0]);
dc.LineTo(points[1]);
dc.LineTo(points[2]);
dc.LineTo(points[0]);
dc.SelectObject(pOldPen);
CBrush oBrush(lpNMCustomDraw->clrText), *pOldBrush;
pOldBrush = dc.SelectObject(&oBrush);
dc.FloodFill(points[0].x +1, points[0].y +2, lpNMCustomDraw->clrText);
dc.SelectObject(pOldBrush);
}
//detach DC
dc.Detach();
*pResult = CDRF_SKIPDEFAULT;
}
else
*pResult = 0;
}
//////////////////
// Draw 3D checkmark
BOOL MenuToolBar::Draw3DCheckmark(CDC& dc, CRect rc,
BOOL bSelected, HBITMAP hbmCheck, BOOL bDrawSunkenBdr, BOOL bGrayImage)
{
// get checkmark bitmap if none, use Windows standard
HBITMAP hbm = hbmCheck;
if (!hbmCheck) {
CBitmap bm;
bm.LoadOEMBitmap(OBM_CHECK);
hbm = (HBITMAP)bm.Detach();
if(!hbm)
return FALSE;
}
// center bitmap in caller's rectangle
BITMAP bm;
::GetObject(hbm, sizeof(bm), &bm);
int cx = bm.bmWidth;
int cy = bm.bmHeight;
CRect rcDest = rc;
CPoint p(0,0);
CSize delta(CPoint((rc.Width() - cx)/2, (rc.Height() - cy)/2));
if (rc.Width() > cx)
rcDest = CRect(rc.TopLeft() + delta, CSize(cx, cy));
else
p -= delta;
//draw background rectangle first
if(hbmCheck && bDrawSunkenBdr)
dc.FillSolidRect(rc, GetSysColor(COLOR_MENU));
// select checkmark into memory DC
CDC memdc;
memdc.CreateCompatibleDC(&dc);
//change the background colors of bitmap
if(hbmCheck)
{
hbm = GetSysColorBitmap(dc.GetSafeHdc(), hbm, bGrayImage, bSelected);
}
HBITMAP hOldBM = (HBITMAP)::SelectObject(memdc, hbm);
// set BG color based on selected state
COLORREF colorOld = dc.SetBkColor(GetSysColor((bSelected && !bGrayImage)?COLOR_HIGHLIGHT:COLOR_MENU));
dc.BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
&memdc, p.x, p.y, SRCCOPY);
dc.SetBkColor(colorOld);
::SelectObject(memdc, hOldBM); //restore
//Delete hbm object..it is either created by GetSysColorBitmap function or LoadOEMBitmap
DeleteObject(hbm);
memdc.DeleteDC();
//Check if we need to draw sunken border
if(bDrawSunkenBdr)
{
dc.DrawEdge(rc, BDR_SUNKENOUTER, BF_RECT);
//draw background
CBrush brush;
CBitmap bmp;
WORD Bits[8] = { 0x0055, 0x00aa, 0x0055, 0x00aa,
0x0055, 0x00aa, 0x0055, 0x00aa };
bmp.CreateBitmap( 8, 8, 1, 1, &Bits );
//hatched background
brush.CreatePatternBrush(&bmp);
//if item is selected, then we draw plain background
CBrush brush1(GetSysColor(COLOR_MENU));
CBrush* oldBr = dc.SelectObject(bSelected ? &brush1 : &brush);
//the text color is used by pattern brush
dc.SetTextColor(GetSysColor(COLOR_3DHIGHLIGHT));
dc.SetBkColor(GetSysColor(COLOR_MENU));
if(!hbmCheck)
dc.ExtFloodFill(rc.left+1, rc.top+1, GetSysColor(bSelected?COLOR_HIGHLIGHT:COLOR_MENU), FLOODFILLSURFACE);
else
dc.ExtFloodFill(rc.left+1, rc.top+1, GetSysColor(COLOR_MENU), FLOODFILLSURFACE);
//cleanup
dc.SelectObject(oldBr);
brush.DeleteObject();
brush1.DeleteObject();
bmp.DeleteObject();
}
return TRUE;
}
int MenuToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
lpCreateStruct->style &= ~WS_VISIBLE;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -