gusucode.com > CComboBox的自绘源码C++源码程序 > CComboBox的自绘源码/CComboBoxCheck/ComboBoxCheck.cpp
// ComboBoxCheck.cpp : 实现文件 // #include "stdafx.h" #include "CComboBoxCheck.h" #include "ComboBoxCheck.h" #include ".\comboboxcheck.h" // CComboBoxCheck IMPLEMENT_DYNAMIC(CComboBoxCheck, CComboBox) CComboBoxCheck::CComboBoxCheck() { m_bOver = FALSE; m_pBrsh = CBrush::FromHandle( ( HBRUSH )GetStockObject( NULL_BRUSH ) ); m_bgBrush = new CBrush; m_bgBrush->CreateSolidBrush( RGB( 141,178,227 ) ); m_bgPen.CreatePen( PS_SOLID,1,RGB( 160,31,208 ) ); m_font.CreateFont( 15,0,0,0,0,0,0,0,0,0,0,0,0,_T("宋体") ); m_bDown = FALSE; m_selItem = 666666666; m_preSelItem = 666666666; m_bFous = FALSE; } CComboBoxCheck::~CComboBoxCheck() { if ( m_bgPen.m_hObject != NULL ) { m_bgPen.DeleteObject(); } if ( m_pBrsh->m_hObject != NULL ) { m_pBrsh->DeleteObject(); } if ( m_bgBrush != NULL ) { delete m_bgBrush; } if ( m_bgBrush->m_hObject == NULL ) { m_bgBrush->DeleteObject(); } if ( m_font.m_hObject != NULL ) { m_font.DeleteObject(); } for ( IterItem iter = m_vecItemList.begin();iter != m_vecItemList.end();iter ++ ) { if ( *iter != NULL ) { delete *iter; } } } BEGIN_MESSAGE_MAP(CComboBoxCheck, CComboBox) ON_WM_ERASEBKGND() ON_WM_MOUSEMOVE() ON_MESSAGE( WM_MOUSELEAVE,OnMouseLeave ) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_CONTROL_REFLECT(CBN_SELCHANGE, OnCbnSelchange) END_MESSAGE_MAP() // CComboBoxCheck 消息处理程序 BOOL CComboBoxCheck::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CComboBoxCheck::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if ( lpDrawItemStruct->CtlType != ODT_COMBOBOX ) { return; } UINT itemID = lpDrawItemStruct->itemID; CRect rcClient = lpDrawItemStruct->rcItem; UINT iState = lpDrawItemStruct->itemState; CBitmap MemBit; CDC* pDC = CDC::FromHandle( lpDrawItemStruct->hDC ); DrawContent( iState,rcClient,pDC,itemID ); } void CComboBoxCheck::OnMouseMove(UINT nFlags, CPoint point) { if ( m_bOver == FALSE ) { m_bOver = TRUE; //更新当前区域 UpdateRect(); TRACKMOUSEEVENT tme; tme.cbSize = sizeof( TRACKMOUSEEVENT ); tme.dwFlags = TME_LEAVE; tme.dwHoverTime = 0; tme.hwndTrack = m_hWnd; _TrackMouseEvent( &tme ); } CComboBox::OnMouseMove(nFlags, point); } LRESULT CComboBoxCheck::OnMouseLeave( WPARAM wParam,LPARAM lParam ) { if ( m_bOver ) { m_bOver = FALSE; } UpdateRect(); return 1; } void CComboBoxCheck::UpdateRect(void) { CRect rcClient; GetWindowRect( &rcClient ); rcClient.DeflateRect( -2,-2 ); GetParent()->ScreenToClient( &rcClient ); GetParent()->InvalidateRect( &rcClient,FALSE ); return; } void CComboBoxCheck::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight = 30; lpMeasureItemStruct->itemWidth = 400; } void CComboBoxCheck::InitControl(void) { ItemList* pItem = new ItemList; pItem->clrLeft = RGB( 0,132,114 ); pItem->clrRight = RGB( 0,255,125 ); pItem->hIcon = AfxGetApp()->LoadIcon( IDI_ICON1 ); pItem->strTitle = _T("腾讯首页"); pItem->strUrl = _T( "http://www.qq.com" ); pItem->iItem = AddString( _T("腾讯首页") ); m_vecItemList.push_back( pItem ); ItemList* pItem1 = new ItemList; pItem1->clrLeft = RGB( 0,132,114 ); pItem1->clrRight = RGB( 0,255,125 ); pItem1->hIcon = AfxGetApp()->LoadIcon( IDI_ICON2 ); pItem1->strTitle = _T("Google首页"); pItem1->strUrl = _T( "http://www.google.com.hk" ); pItem->iItem = AddString( _T("Google首页") ); m_vecItemList.push_back( pItem1 ); ItemList* pItem2 = new ItemList; pItem2->clrLeft = RGB( 0,132,114 ); pItem2->clrRight = RGB( 0,255,125 ); pItem2->hIcon = AfxGetApp()->LoadIcon( IDI_ICON3 ); pItem2->strTitle = _T("新浪首页"); pItem2->strUrl = _T( "http://www.sina.cn" ); pItem->iItem = AddString( _T("新浪首页") ); m_vecItemList.push_back( pItem2 ); ItemList* pItem3 = new ItemList; pItem3->clrLeft = RGB( 0,132,114 ); pItem3->clrRight = RGB( 0,255,125 ); pItem3->hIcon = AfxGetApp()->LoadIcon( IDI_ICON4 ); pItem3->strTitle = _T("百度首页"); pItem3->strUrl = _T( "http://www.sina.cn" ); pItem->iItem = AddString( _T("百度首页") ); m_vecItemList.push_back( pItem3 ); ItemList* pItem4 = new ItemList; pItem4->clrLeft = RGB( 0,132,114 ); pItem4->clrRight = RGB( 0,255,125 ); pItem4->hIcon = AfxGetApp()->LoadIcon( IDI_ICON5 ); pItem4->strTitle = _T("酷狗首页"); pItem4->strUrl = _T( "http://www.kugou.cn" ); pItem->iItem = AddString( _T("酷狗首页") ); m_vecItemList.push_back( pItem4 ); } void CComboBoxCheck::OnNcPaint( CDC* pDC ) { //绘制客户区 CDC dMemDC; dMemDC.CreateCompatibleDC(pDC); dMemDC.SetMapMode(pDC->GetMapMode()); //画动作 CBitmap mNewBmp; CRect rc; GetClientRect(&rc); mNewBmp.CreateCompatibleBitmap(pDC, rc.right - rc.left, rc.bottom - rc.top); CBitmap* pOldBmp = dMemDC.SelectObject(&mNewBmp); CPen* pOldPen = dMemDC.SelectObject( &m_bgPen ); CBrush* pOldBrsh = dMemDC.SelectObject( m_bgBrush ); dMemDC.Rectangle( &rc ); dMemDC.SelectObject( pOldPen ); dMemDC.SelectObject( &pOldBrsh ); if ( (GetCurSel() > 4)||(GetCurSel() < 0) ) { return; } PItemList pItem = m_vecItemList[GetCurSel()]; CPen m_penLeft; CPen m_penRight; CRect rcLeft,rcMid,rcRight; rcLeft = rcMid = rcRight = rc; dMemDC.SetBkMode( TRANSPARENT ); //画第一段图标 rcLeft.right = rcLeft.left + 16; rcLeft.left += 1; rcLeft.top += 4; ::DrawIconEx( dMemDC.m_hDC,rcLeft.left,rcLeft.top,pItem->hIcon,16,16,NULL,NULL,DI_NORMAL ); //画第二段文本 rcMid.left = rcLeft.right + 10; rcMid.right = rc.right - 110; CFont* pOldFont = dMemDC.SelectObject( &m_font ); dMemDC.SetTextColor( pItem->clrLeft ); dMemDC.DrawText( pItem->strUrl,&rcMid,DT_VCENTER|DT_LEFT|DT_SINGLELINE ); //画第三段文本 rcRight.left = rcMid.right; dMemDC.SetTextColor( pItem->clrRight ); dMemDC.DrawText( pItem->strTitle,&rcRight,DT_VCENTER|DT_LEFT|DT_SINGLELINE ); dMemDC.SelectObject( pOldFont ); CRect rcEnd(rc); rcEnd.left = rc.right - 22; if( m_bDown ) { dMemDC.DrawFrameControl( &rcEnd,DFC_SCROLL,DFCS_SCROLLDOWN|DFCS_FLAT|DFCS_MONO|DFCS_PUSHED ); } else { dMemDC.DrawFrameControl( &rcEnd,DFC_SCROLL,DFCS_SCROLLDOWN|DFCS_FLAT|DFCS_MONO ); } pDC->BitBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, &dMemDC, rc.left ,rc.top, SRCCOPY); //恢复 dMemDC.SelectObject(pOldBmp); pOldBmp->DeleteObject(); dMemDC.DeleteDC(); } void CComboBoxCheck::OnPaint() { CPaintDC dc(this); // device context for painting OnNcPaint( &dc ); } void CComboBoxCheck::DrawContent( UINT iState,CRect rcClient, CDC* pDC,int itemID) { PItemList pItem = m_vecItemList[itemID]; CPen m_penLeft; CPen m_penRight; CRect rcLeft,rcMid,rcRight; rcLeft = rcMid = rcRight = rcClient; pDC->SetBkMode( TRANSPARENT ); if ( iState & ODS_SELECTED ) { //及时更新选择区域 UpdateRect(); } if ( itemID == m_selItem ) { CPen bgPen; bgPen.CreatePen( PS_SOLID,1,RGB( 141,178,227 ) ); CPen* pOldPen = pDC->SelectObject( &bgPen ); CBrush* pOldBrush = pDC->SelectObject( m_pBrsh ); pDC->RoundRect( &rcClient,CPoint( 5,5 ) ); pDC->SelectObject( pOldBrush ); pDC->SelectObject( pOldPen ); bgPen.DeleteObject(); } //画第一段图标 rcLeft.right = rcLeft.left + 16; rcLeft.top += 4; ::DrawIconEx( pDC->m_hDC,rcLeft.left,rcLeft.top,pItem->hIcon,16,16,NULL,NULL,DI_NORMAL ); //画第二段文本 rcMid.left = rcLeft.right + 10; rcMid.right = rcClient.right - 100; pDC->SetTextColor( pItem->clrLeft ); CFont* pOldFont = pDC->SelectObject( &m_font ); pDC->DrawText( pItem->strUrl,&rcMid,DT_VCENTER|DT_LEFT|DT_SINGLELINE ); //画第三段文本 rcRight.left = rcMid.right + 8; pDC->SetTextColor( pItem->clrRight ); pDC->DrawText( pItem->strTitle,&rcRight,DT_VCENTER|DT_LEFT|DT_SINGLELINE ); pDC->SelectObject( pOldFont ); CRect rcEnd( rcClient ); rcEnd.left = rcEnd.right - 18; rcEnd.top += 3; if ( itemID == m_selItem ) { if ( m_bFous ) { DrawIconEx( pDC->m_hDC,rcEnd.left,rcEnd.top,AfxGetApp()->LoadIcon( IDI_ICON6 ),16,16,NULL,NULL,DI_NORMAL ); } else { DrawIconEx( pDC->m_hDC,rcEnd.left,rcEnd.top,AfxGetApp()->LoadIcon( IDI_ICON7 ),16,16,NULL,NULL,DI_NORMAL ); } } } void CComboBoxCheck::OnLButtonDown(UINT nFlags, CPoint point) { m_bDown = TRUE; UpdateRect(); CComboBox::OnLButtonDown(nFlags, point); } void CComboBoxCheck::OnLButtonUp(UINT nFlags, CPoint point) { m_bDown = FALSE; UpdateRect(); CComboBox::OnLButtonUp(nFlags, point); } void CComboBoxCheck::OnCbnSelchange() { UpdateRect(); } LRESULT CComboBoxCheck::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if( WM_CTLCOLORLISTBOX == message) { HWND hListBox = (HWND)lParam; CListBox* pListBox = (CListBox*)FromHandle(hListBox); ASSERT(pListBox); int nCount = pListBox->GetCount(); if(CB_ERR != nCount) { CPoint pt; GetCursorPos(&pt); pListBox->ScreenToClient(&pt); CRect rc; for(int i=0; i<nCount; i++) { pListBox->GetItemRect(i, &rc); if(rc.PtInRect(pt)) { m_preSelItem = m_selItem; m_selItem = i; if ( m_selItem != m_preSelItem ) { CRect preRc; CRect rcFous( rc ); rcFous.left = rcFous.right - 18; pListBox->GetItemRect( m_preSelItem,&preRc ); pListBox->InvalidateRect( &preRc ); if ( rcFous.PtInRect( pt ) ) { m_bFous = TRUE; pListBox->InvalidateRect( &rc ); } else { m_bFous = FALSE; pListBox->InvalidateRect( &rc ); } } break; } } } } return CComboBox::WindowProc(message, wParam, lParam); }