gusucode.com > VC++模仿QQ界面风格源码程序 > VC++模仿QQ界面风格/QMenu.cpp
////// // EZMenu - Owner drawn menu with Icons & progressbars // Copyright V.Lakshmi Narasimhan,ezlux@Yahoo.com. // Feel free to use,modify,twist,turn or even // digest the code for any non commercial purposes. // I would appreciate constructive suggestions & bug reports. // Please dont delete the above lines. /////// //Implementation file for owner drawn menu EZMenu #include "stdafx.h" #include "QMenu.h" #include "resource.h" QMenu::QMenu() { m_szBitmapSize=CSize(20,60); m_SeperatorNum=m_nCount=m_nItems=0; m_nAveHeight=16; m_clrExtend=RGB(0,0,255); m_ItemHeight=20; m_MenuWidth=50; CMenu::CMenu(); } void QMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { m_nCount++; LPQMENUITEMDATA lpez=(LPQMENUITEMDATA)lpDrawItemStruct->itemData; CDC* pdc=CDC::FromHandle(lpDrawItemStruct->hDC); if(lpez->bSeperator) { m_SeperatorNum++; int nWidth=0; if(m_bitmap.m_hObject) nWidth+=(m_szBitmapSize.cx+lpDrawItemStruct->rcItem.left); CRect rcSep(lpDrawItemStruct->rcItem); rcSep.left+=nWidth; pdc->DrawEdge(&rcSep,EDGE_ETCHED,BF_TOP); return; } // Rects Definition CRect rect(lpDrawItemStruct->rcItem);//general m_MenuWidth=(m_MenuWidth>rect.right)?m_MenuWidth:rect.right; CRect rcBmp(rect); CRect rcIcon(rect);//Icon rect CRect rcText(rect);//Text rect; //Rects Initialization rcBmp.right=rcBmp.left+m_szBitmapSize.cx; rcIcon.top+=3; rcIcon.left=rcBmp.right+5; rcIcon.right=rcIcon.left+16; rcText.left=rcIcon.right+8; //Drawing code HICON hItemIcon=lpez->hItemIcon; CSize szIcon=CSize(16,16); //Draws the whole thing if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE) { //Draw the Icon int nOldMap=pdc->SetMapMode(MM_TEXT); if(hItemIcon) pdc->DrawState(rcIcon.TopLeft(),szIcon,hItemIcon,DST_ICON|DSS_NORMAL,(CBrush*)NULL); else if(lpez->bChecked) { HICON hCheck=(HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_CHECK_SMALL),IMAGE_ICON,szIcon.cx,szIcon.cy,LR_DEFAULTCOLOR); pdc->DrawState(rcIcon.TopLeft(),szIcon,hCheck,DST_ICON|DSS_NORMAL,(CBrush*)NULL); } //Finally draw the text pdc->SetMapMode(nOldMap); CBrush *pBrush=new CBrush(::GetSysColor(COLOR_BTNFACE)); pdc->FillRect(rcText,pBrush); delete pBrush; pdc->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE)); // rcText.left++; pdc->DrawText(lpez->strItemText,&rcText,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER); // rcText.left--; //Draw the bitmap at the end if(m_nCount==m_nItems) { m_nCount=0; if(m_bitmap.m_hObject) { CDC memdc; memdc.CreateCompatibleDC(pdc); memdc.SelectObject(m_bitmap); if(m_nAveHeight>m_szBitmapSize.cy) { int nTop=rect.bottom-m_szBitmapSize.cy; pdc->BitBlt(rect.left,nTop,m_szBitmapSize.cx,m_szBitmapSize.cy,&memdc,0,0,SRCCOPY); pdc->FillSolidRect(rect.left,rect.bottom-m_nAveHeight,m_szBitmapSize.cx,m_nAveHeight-m_szBitmapSize.cy,m_clrExtend); } else pdc->BitBlt(rect.left,rect.bottom-m_nAveHeight,m_szBitmapSize.cx,m_nAveHeight,&memdc,0,0,SRCCOPY); } } } //Draws the selected item if ((lpDrawItemStruct->itemState & ODS_SELECTED) && (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))) { if(hItemIcon) { CRect rcIconHilite(rcIcon); rcIconHilite.left-=2; rcIconHilite.top-=2; rcIconHilite.bottom-=2; rcIconHilite.right+=2; pdc->Draw3dRect(&rcIconHilite,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DDKSHADOW)); } //Text CRect textrect(rcText); COLORREF crOld=pdc->SetTextColor(::GetSysColor(COLOR_HIGHLIGHT)); COLORREF crBgOld=pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE)); // CFont* pFont=pdc->GetCurrentFont(); // LOGFONT* pLf=new LOGFONT; // pFont->GetLogFont(pLf); // pLf->lfWeight=FW_SEMIBOLD; // CFont* pNewFont=new CFont; // pNewFont->CreateFontIndirect(pLf); // pFont=pdc->SelectObject(pNewFont); //textrect.left+=2; pdc->DrawText(lpez->strItemText,&textrect,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER); //textrect.left-=2; pdc->SetTextColor(crOld); pdc->SetBkColor(crBgOld); // delete pdc->SelectObject(pFont); // delete pLf; textrect.top+=1; textrect.bottom-=2; textrect.left-=1; pdc->Draw3dRect(&textrect,::GetSysColor(COLOR_3DDKSHADOW),::GetSysColor(COLOR_3DHILIGHT)); } //Draws the deselected item if (!(lpDrawItemStruct->itemState & ODS_SELECTED) && (lpDrawItemStruct->itemAction & ODA_SELECT)) { if(hItemIcon) { CRect rcIconHilite(rcIcon); rcIconHilite.left-=2; rcIconHilite.top-=2; rcIconHilite.bottom-=2; rcIconHilite.right+=2; pdc->Draw3dRect(&rcIconHilite,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE)); } pdc->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE)); CRect textrect(rcText); CBrush *pBrush=new CBrush(::GetSysColor(COLOR_BTNFACE)); pdc->FillRect(&textrect,pBrush); delete pBrush; pdc->DrawText(lpez->strItemText,&textrect,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER); textrect.top+=1; textrect.bottom-=2; textrect.left-=1; pdc->Draw3dRect(&textrect,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE)); } } void QMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { LPQMENUITEMDATA lpez=(LPQMENUITEMDATA )lpMeasureItemStruct->itemData; if(lpez->bSeperator) { lpMeasureItemStruct->itemHeight=5; return; } CDC* pdc=new CDC; pdc->Attach(::GetDC(AfxGetMainWnd()->m_hWnd)); CSize szText=pdc->GetTextExtent(lpez->strItemText); ::ReleaseDC(AfxGetMainWnd()->m_hWnd,pdc->m_hDC); delete pdc; lpMeasureItemStruct->itemWidth=szText.cx+18+m_szBitmapSize.cx+8; lpMeasureItemStruct->itemHeight=__max(m_ItemHeight,szText.cy)+4; m_nAveHeight=m_nItems*lpMeasureItemStruct->itemHeight; } QMenu::~QMenu() { DestroyMenu(); CMenu::~CMenu(); } void QMenu::SetMenuBitmap(HBITMAP hBitmap) { m_bitmap.Attach(hBitmap); } void QMenu::AppendOwnerDrawnItem(UINT nID, LPQMENUITEMDATA lpez) { VERIFY(AppendMenu(MF_ENABLED | MF_OWNERDRAW, nID,(LPCTSTR)lpez)); } void QMenu::SetBitmapDimension(CSize sz) { m_szBitmapSize=sz; } void QMenu::InsertOwnerDrawnMenuItem(UINT nID, LPQMENUITEMDATA lpez,int nPos) { VERIFY(InsertMenu(nPos,MF_BYPOSITION|MF_ENABLED | MF_OWNERDRAW, nID,(LPCTSTR)lpez)); } void QMenu::SetExtensionColor(COLORREF clrExtend) { m_clrExtend=clrExtend; } void QMenu::SetTotalItems(int nItems) { m_nItems=nItems; } QMenuItemData::QMenuItemData() { bChecked=FALSE; bSeperator=FALSE; hItemIcon=NULL; strItemText.Empty(); } QMenuItemData::~QMenuItemData() { // delete this; } void QMenu::ModifyOwnerDrawnMenuItem(int nPos, UINT nID, int nTotalCheck,LPQMENUITEMDATA lpez) { //Iam not sure how to implement this.Suggestions are welcome. //if(GetMenuItemCount()>(UINT)nTotalCheck)? VERIFY(ModifyMenu(nPos,MF_BYPOSITION|MF_OWNERDRAW,nID,(LPCTSTR)lpez)); //else // InsertOwnerDrawnMenuItem(nID,lpez,nPos); } void QMenuItemData::SetItemIcon(int idIcon) { HICON hIcon=(HICON)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(idIcon), IMAGE_ICON,16,16,LR_DEFAULTCOLOR); hItemIcon=hIcon; } void QMenuItemData::SetItemIcon(HICON hIcon) { hItemIcon=hIcon; } void QMenuItemData::SetCheck(int iState) { bChecked=iState; } void QMenuItemData::SetSeperator(int enable) { bSeperator=enable; } void QMenuItemData::SetItemText(CString szText) { strItemText=szText; } CSize QMenu::GetMenuSize() { CSize size; size.cx=m_MenuWidth+74; size.cy=(m_ItemHeight+4)*m_nItems-m_SeperatorNum*4-8; return size; } void QMenu::SetItemHeight(int value) { }