// SkinListBox.cpp : 实现文件 // #include "stdafx.h" #include "Control.h" #include "SkinListBox.h" // CSkinListBox IMPLEMENT_DYNAMIC(CSkinListBox, CListBox) BEGIN_MESSAGE_MAP(CSkinListBox, CListBox) ON_WM_DESTROY() ON_WM_RBUTTONUP() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() //ON_WM_NCPAINT() ON_WM_ERASEBKGND() END_MESSAGE_MAP() CSkinListBox::CSkinListBox( void ) { m_pBackImgN = NULL; m_pSelectImg = NULL; m_pBackImgH = NULL; m_nHovenItem = 0; nItemHeight = 20; m_ItemStruct.clear(); } CSkinListBox::~CSkinListBox( void ) { } BOOL CSkinListBox::SetBackNormalImage( LPCTSTR lpszFileName, CONST LPRECT lpNinePart /*= NULL*/ ) { RenderEngine->RemoveImage(m_pBackImgN); m_pBackImgN = RenderEngine->GetImage(lpszFileName); if (m_pBackImgN != NULL) m_pBackImgN->SetNinePart(lpNinePart); return (m_pBackImgN != NULL) ? TRUE : FALSE; } BOOL CSkinListBox::SetSelectImage( LPCTSTR lpszFileName, CONST LPRECT lpNinePart /*= NULL*/ ) { RenderEngine->RemoveImage(m_pSelectImg); m_pSelectImg = RenderEngine->GetImage(lpszFileName); if (m_pSelectImg != NULL) m_pSelectImg->SetNinePart(lpNinePart); return (m_pSelectImg != NULL) ? TRUE : FALSE; } BOOL CSkinListBox::SetHovenImage( LPCTSTR lpszFileName, CONST LPRECT lpNinePart /*= NULL*/ ) { RenderEngine->RemoveImage(m_pBackImgH); m_pBackImgH = RenderEngine->GetImage(lpszFileName); if (m_pBackImgH != NULL) m_pBackImgH->SetNinePart(lpNinePart); return (m_pBackImgH != NULL) ? TRUE : FALSE; } void CSkinListBox::OnDestroy() { __super::OnDestroy(); RenderEngine->RemoveImage(m_pBackImgN); RenderEngine->RemoveImage(m_pBackImgH); RenderEngine->RemoveImage(m_pSelectImg); RemoveScorll(); } void CSkinListBox::OnNcPaint() { //如果资源没有就是不想绘制边框了 if ( m_pBackImgN == NULL ) { __super::OnNcPaint(); return; } CRect rcWindow; GetWindowRect(&rcWindow); CRect rcClient; GetClientRect(&rcClient); ClientToScreen(&rcClient); rcClient.OffsetRect(-rcWindow.left, -rcWindow.top); rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top); CDC *pWindowDC = GetWindowDC(); CMemoryDC MemDC(pWindowDC,rcWindow); DrawParentWndBg(GetSafeHwnd(),MemDC.GetSafeHdc()); if (m_pBackImgN != NULL && !m_pBackImgN->IsNull()) m_pBackImgN->Draw(&MemDC, rcWindow); pWindowDC->BitBlt(rcWindow.left,rcWindow.top,rcWindow.Width(),rcWindow.Height(),&MemDC,0,0,SRCCOPY); ReleaseDC(pWindowDC); } void CSkinListBox::OnRButtonUp(UINT nFlags, CPoint point) { CRect rcItem(0,0,0,0); SetSel(-1,FALSE); for (int i =0; iGetSafeHwnd() != NULL) ) return; pWnd->PostMessage(WM_COMMAND,GetDlgCtrlID(),0); __super::OnRButtonUp(nFlags, point); } void CSkinListBox::OnMouseMove(UINT nFlags, CPoint point) { CRect rcItem(0,0,0,0); //保存旧状态,为了防止在同一个节点下因过多的刷新消耗cpu资源 static int nOldIndex = -1; for (int i =0; ircItem; CDC * pDCControl=CDC::FromHandle(lpDrawItemStruct->hDC); //创建缓冲 CDC BufferDC; CBitmap ImageBuffer; BufferDC.CreateCompatibleDC(pDCControl); ImageBuffer.CreateCompatibleBitmap(pDCControl,rcItem.Width(),rcItem.Height()); //设置环境 BufferDC.SelectObject(&ImageBuffer); BufferDC.SelectObject(GetCtrlFont()); //获取字符 CString strString; GetText(lpDrawItemStruct->itemID,strString); //计算位置 CRect rcString; rcString.SetRect(4,0,rcItem.Width()-8,rcItem.Height()); //颜色定义 COLORREF crTextColor=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0)?m_colSelectText:m_colNormalText; //绘画背景 BufferDC.FillSolidRect(0,0,rcItem.Width(),rcItem.Height(),m_colBack); //节点选中 if ( (lpDrawItemStruct->itemState&ODS_SELECTED) != 0 ) { if ( m_pSelectImg!= NULL && !m_pSelectImg->IsNull() ) { m_pSelectImg->Draw(&BufferDC,CRect(0,0,rcItem.Width(),rcItem.Height())); } } //节点高亮 else if ( m_nHovenItem == lpDrawItemStruct->itemID ) { if ( m_pBackImgH!= NULL && !m_pBackImgH->IsNull() ) { m_pBackImgH->Draw(&BufferDC,CRect(0,0,rcItem.Width(),rcItem.Height())); } } //绘画字符 BufferDC.SetBkMode(TRANSPARENT); BufferDC.SetTextColor(crTextColor); BufferDC.DrawText(strString,&rcString,DT_VCENTER|DT_SINGLELINE); //绘画界面 pDCControl->BitBlt(rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height(),&BufferDC,0,0,SRCCOPY); //清理资源 BufferDC.DeleteDC(); ImageBuffer.DeleteObject(); } void CSkinListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { vector::iterator iter = m_ItemStruct.begin(); for (;iter != m_ItemStruct.end(); ++iter ) { lpMeasureItemStruct->itemHeight = iter->itemHeight; lpMeasureItemStruct->itemWidth = iter->itemWidth; } } bool CSkinListBox::IsSingleSel() { DWORD dwStyle = GetStyle(); if ( ((dwStyle&LBS_EXTENDEDSEL)!=0) || ((dwStyle&LBS_MULTIPLESEL)!=0) ) { return false; } return true; } void CSkinListBox::AddString(LPCTSTR lpszItem) { InsertItem(); __super::AddString(lpszItem); } int CSkinListBox::SetItemHeight( int nIndex, UINT cyItemHeight ) { if ( nIndex == -1 ) nItemHeight = cyItemHeight; vector::iterator iter = m_ItemStruct.begin(); for (;iter != m_ItemStruct.end(); ++iter ) { if ( iter->itemID == nIndex ) { iter->itemHeight = cyItemHeight; break; } } return __super::SetItemHeight(nIndex,cyItemHeight); } int CSkinListBox::DeleteString( UINT nIndex ) { vector::iterator iter = m_ItemStruct.begin(); for (;iter != m_ItemStruct.end(); ++iter ) { if ( iter->itemID == nIndex ) { m_ItemStruct.erase(iter); break; } } return __super::DeleteString(nIndex); } void CSkinListBox::InsertItem() { tagItemStruct ItemStruct; ZeroMemory(&ItemStruct,sizeof ItemStruct); CRect rcClient; GetClientRect(&rcClient); ItemStruct.itemID = m_ItemStruct.size(); ItemStruct.itemHeight = nItemHeight; ItemStruct.itemWidth = rcClient.Width(); m_ItemStruct.push_back(ItemStruct); } void CSkinListBox::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue ) { ISkinControl::SetAttribute(pstrName,pstrValue); // if( _tcscmp(pstrName, _T("itemheight")) == 0 ) // { // LPTSTR pstr = NULL; // SetItemHeight(-1,_tcstol(pstrValue, &pstr, 10)); // } // else if( _tcscmp(pstrName, _T("scrollimage")) == 0 ) { SetScrollImage(this,pstrValue); } } void CSkinListBox::ParseItem( CXmlNode *root ) { if( root == NULL ) return; int nAttributes = root->GetAttributeCount(); LPCTSTR pstrClass = NULL; LPCTSTR pstrName = NULL; LPCTSTR pstrValue = NULL; for( int i = 0; i < nAttributes; i++ ) { pstrClass = root->GetName(); pstrName = root->GetAttributeName(i); pstrValue = root->GetAttributeValue(i); if( _tcscmp(pstrClass, _T("bknormalimage")) == 0 ) { if( _tcscmp(pstrName, _T("value")) == 0 ) SetBackNormalImage(pstrValue); else if( _tcscmp(pstrName, _T("ninepart")) == 0 ) { LPTSTR pstr = NULL; CRect rc; rc.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); rc.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); if (m_pBackImgN != NULL) m_pBackImgN->SetNinePart(&rc); } } else if( _tcscmp(pstrClass, _T("selectimage")) == 0 ) { if( _tcscmp(pstrName, _T("value")) == 0 ) SetSelectImage(pstrValue); else if( _tcscmp(pstrName, _T("ninepart")) == 0 ) { LPTSTR pstr = NULL; CRect rc; rc.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); rc.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); if (m_pSelectImg != NULL) m_pSelectImg->SetNinePart(&rc); } } else if( _tcscmp(pstrClass, _T("hovenimage")) == 0 ) { if( _tcscmp(pstrName, _T("value")) == 0 ) SetHovenImage(pstrValue); else if( _tcscmp(pstrName, _T("ninepart")) == 0 ) { LPTSTR pstr = NULL; CRect rc; rc.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); rc.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); rc.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); if (m_pBackImgH != NULL) m_pBackImgH->SetNinePart(&rc); } } else if( _tcscmp(pstrClass, _T("item")) == 0 ) { if( _tcscmp(pstrName, _T("text")) == 0 ) AddString(pstrValue); } } } BOOL CSkinListBox::CreateControl( CWnd* pParentWnd ) { if( !Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS |WS_VSCROLL ,CRect(0,0,0,0),pParentWnd,0) ) return FALSE; SetFont(CFont::FromHandle(RenderEngine->GetDeaultFont())); m_pOwnWnd = this; return TRUE; } BOOL CSkinListBox::OnEraseBkgnd(CDC* pDC) { return TRUE; return __super::OnEraseBkgnd(pDC); }