gusucode.com > 颜色选择组合框C++源码程序 > 颜色选择组合框/BSColorComboBox/BSColorComboBox/BSColorComboBox.cpp
/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 文件:BSColorComboBox.cpp 版权:Devia@163.com(Blue Sky) 保留 描述:本程序主要完成颜色选择组合框。 作者:李晓飞(Devia_Li) 2003.01.15 联系:(Tel)13512524180 (E_mail)lixiaofei@163.net @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ #include "stdafx.h" #include "BSColorComboBox.h" //################################################################ CBSColorComboBox::CBSColorComboBox() { //当前鼠标是否在对象上 m_bOverControl = false; //小图标尺寸 iIconX = ::GetSystemMetrics(SM_CXSMICON); iIconY = ::GetSystemMetrics(SM_CYSMICON); } //################################################################ CBSColorComboBox::~CBSColorComboBox() { while(!m_crItem.IsEmpty()) { LPBSCBITEM lpItem = m_crItem.RemoveHead(); delete lpItem; } } //################################################################ BOOL CBSColorComboBox::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) { DWORD dw = dwStyle; //dw |= CBS_OWNERDRAWVARIABLE; if( !CComboBox::Create(dw, rect, pParentWnd, nID) ) return false; CFont * font = CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)); SetFont(font); return true; } //################################################################ IMPLEMENT_DYNCREATE(CBSColorComboBox, CComboBox) BEGIN_MESSAGE_MAP(CBSColorComboBox, CComboBox) //{{AFX_MSG_MAP(CBSColorComboBox) ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_TIMER() ON_WM_MOUSEMOVE() ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange) ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendok) //}}AFX_MSG_MAP END_MESSAGE_MAP() //################################################################ void CBSColorComboBox::InitBSColorCB(void) { int iMinColor = COLOR_SCROLLBAR, iMaxColor = COLOR_BTNHIGHLIGHT; if(WINVER >= 0x0400) iMaxColor = COLOR_INFOBK; if(WINVER >= 0x0500) iMaxColor = 28; //初始化CB颜色列表框的Item(常见的SysColor值) for(int iLoop = iMinColor; iLoop <= iMaxColor; ++iLoop) { LPBSCBITEM lpItem = new BSCBITEM; lpItem->iIndex = AddString(strColorName[iLoop]); lpItem->crColor = ::GetSysColor(iLoop); lpItem->lpCaption = strColorName[iLoop]; // if(m_crItem.IsEmpty()) m_crItem.AddHead(lpItem); else m_crItem.AddTail(lpItem); } //该Item是为了用户自定义颜色而设置 LPBSCBITEM lpItem = new BSCBITEM; lpItem->iIndex = AddString("More Colors"); lpItem->crColor = RGB(213, 233, 249); lpItem->lpCaption = "More Colors"; if(m_crItem.IsEmpty()) m_crItem.AddHead(lpItem); else m_crItem.AddTail(lpItem); //初始化当前颜色 m_crColor = m_crItem.GetHead()->crColor; } //################################################################ BOOL CBSColorComboBox::OnEraseBkgnd(CDC* pDC) { ASSERT(pDC->GetSafeHdc()); return false; } //################################################################ void CBSColorComboBox::OnPaint() { CPaintDC dc(this); OnCBPaint(&dc); } //################################################################ void CBSColorComboBox::OnCBPaint(CDC* pDC) { ASSERT(pDC->GetSafeHdc()); //绘制客户区 CDC dMemDC; dMemDC.CreateCompatibleDC(pDC); dMemDC.SetMapMode(pDC->GetMapMode()); //画动作 CBitmap mNewBmp; RECT rc; GetClientRect(&rc); mNewBmp.CreateCompatibleBitmap(pDC, rc.right - rc.left, rc.bottom - rc.top); CBitmap* pOldBmp = dMemDC.SelectObject(&mNewBmp); //子类可以以friend方式来访问父类的protected成员变量和函数 CWnd::DefWindowProc(WM_PAINT, (WPARAM)dMemDC.m_hDC, 0); 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(); GetWindowRect(&rc); ScreenToClient(&rc); pDC->DrawEdge(&rc, (m_bOverControl ? BDR_RAISEDINNER : BDR_SUNKENINNER), BF_RECT); } //################################################################ void CBSColorComboBox::OnTimer(UINT nIDEvent) { if(nIDEvent == 888 && IsWindowEnabled()) { CPoint point; ::GetCursorPos(&point); CRect rect; GetWindowRect(&rect); if(rect.PtInRect(point)) { m_bOverControl = true; } else { m_bOverControl = false; KillTimer(nIDEvent); } } CComboBox::OnTimer(nIDEvent); } //################################################################ void CBSColorComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight = iIconY + 5; } //################################################################ void CBSColorComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS) { ASSERT(lpDIS->CtlType == ODT_COMBOBOX); //画笔 CDC* pDC = CDC::FromHandle(lpDIS->hDC); ASSERT(pDC->GetSafeHdc()); //绘制区 RECT rc = lpDIS->rcItem; RECT rcIcon(rc), rcTxt(rc); //当前的Item索引号 LPBSCBITEM lpItem = GetItem(lpDIS->itemID); if(lpItem != NULL) { //画颜色Icon rcIcon.right = rcIcon.left + iIconX; rcIcon.top += (rc.bottom - rc.top - iIconY) / 2; rcIcon.bottom = rcIcon.top + iIconY; pDC->FillSolidRect(rcIcon.left, rcIcon.top, rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, lpItem->crColor); pDC->DrawEdge(&rcIcon, BDR_RAISEDINNER, BF_RECT); //开始画文字 int nOldBkMode = pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); rcTxt.left = rcIcon.right + 5; rcTxt.top = rcIcon.top; pDC->DrawText(lpItem->lpCaption, &rcTxt, DT_VCENTER | DT_END_ELLIPSIS | DT_NOCLIP | DT_SINGLELINE); pDC->SetBkMode(nOldBkMode); } } //################################################################ void CBSColorComboBox::OnMouseMove(UINT nFlags, CPoint point) { m_bOverControl = true; SetTimer(888, 100, NULL); CComboBox::OnMouseMove(nFlags, point); } //################################################################ LPBSCBITEM CBSColorComboBox::GetItem(int iIndex) { //当前的Item索引号 POSITION pos = m_crItem.FindIndex(iIndex); if(pos) { LPBSCBITEM lpItem = m_crItem.GetAt(pos); ASSERT(lpItem); return lpItem; } else return (LPBSCBITEM)NULL; } //################################################################ COLORREF CBSColorComboBox::GetColor() { if(IsWindowEnabled()) return m_crColor; else { return (m_crColor = GetItem(this->GetCurSel())->crColor); } } //################################################################ void CBSColorComboBox::GetRGBValue(int* R, int* G, int* B) { *R = GetRValue((DWORD)m_crColor); *G = GetGValue((DWORD)m_crColor); *B = GetBValue((DWORD)m_crColor); } //################################################################ void CBSColorComboBox::OnSelchange() { int iIndex = GetCurSel(); if(iIndex != CB_ERR && iIndex >= 0) { CDC* pDC = this->GetDC(); //绘制区 RECT rc; int iScrollX = ::GetSystemMetrics(SM_CXVSCROLL); GetClientRect(&rc); pDC->FillSolidRect(rc.left + 2, rc.top + 2, rc.right - rc.left - iScrollX - 4, rc.bottom - rc.top - 2, ::GetSysColor(COLOR_WINDOW)); RECT rcIcon(rc), rcTxt(rc); //当前的Item索引号 LPBSCBITEM lpItem = GetItem(iIndex); if(lpItem != NULL) { m_crColor = lpItem->crColor; //画颜色Icon rcIcon.left += 2; rcIcon.right = rcIcon.left + iIconX; rcIcon.top += (rc.bottom - rc.top - iIconY) / 2; rcIcon.bottom = rcIcon.top + iIconY; pDC->FillSolidRect(rcIcon.left, rcIcon.top, rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, lpItem->crColor); pDC->DrawEdge(&rcIcon, BDR_RAISEDINNER, BF_RECT); //开始画文字 int nOldBkMode = pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); rcTxt.left = rcIcon.right + 5; rcTxt.top = rcIcon.top; CFont* font = CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)); pDC->SelectObject(font); pDC->DrawText(lpItem->lpCaption, &rcTxt, DT_VCENTER | DT_END_ELLIPSIS | DT_NOCLIP | DT_SINGLELINE); pDC->SetBkMode(nOldBkMode); } pDC->DeleteDC(); } } //################################################################ void CBSColorComboBox::OnSelendok() { int iIndex = this->GetCurSel(); LPBSCBITEM lpTmpItem = GetItem(iIndex); if(lpTmpItem != NULL) { if(lpTmpItem->lpCaption == "More Colors") { CColorDialog crDlg(RGB(255, 0, 0), CC_FULLOPEN); int iRet = crDlg.DoModal(); if(iRet == IDOK) { m_crColor = crDlg.GetColor(); LPBSCBITEM lpItem = m_crItem.GetTail(); ASSERT(lpItem); lpItem->crColor = m_crColor; Invalidate(); } } } }