搜狐首页-新闻-体育-娱乐-财经-IT-汽车-房产-家居-女人-TV-ChinaRen-邮件-博客-BBS-搜狗 

搜狐数码频道 > 搜狐学院·数字艺术 > 程序开发 > VB/VB.NET
如何在 VC++ 应用程序中实现颜色选择组合框
时间:2006年01月04日09:54 我来说两句  

 
来源:比特网(原天极网)
  三、程序代码

//////////////////////////////////////////////////////////////CBSColorComboBox类的头文件;
#if !defined(_BS_BSCOLORCB)
#define _BS_BSCOLORCB
#include <afxtempl.h>
//系统常用颜色的自定义名称
const static char* strColorName[] =
{
 "crSCROLLBAR","crBACKGROUND","crACTIVECAPTION", "crINACTIVECAPTION", "crMENU", "crWINDOW", "crWINDOWFRAME",  "crMENUTEXT", "crWINDOWTEXT", "crCAPTIONTEXT", "crACTIVEBORDER","crINACTIVEBORDER", "crAPPWORKSPACE",  "crHIGHLIGHT", "crHIGHLIGHTTEXT", "crBTNFACE", "crBTNSHADOW", "crGRAYTEXT", "crBTNTEXT",  "crINACTIVECAPTIONTEXT",
 "crBTNHIGHLIGHT","cr3DDKSHADOW", "cr3DLIGHT", "crINFOTEXT", "crINFOBK",
 "crHOTLIGHT","crGRADIENTACTIVECAPTION", crGRADIENTINACTIVECAPTION"
};

typedef struct BSCBITEM
{
 int iIndex;
 COLORREF crColor;
 LPCTSTR lpCaption;
}BSCBITEM, *LPBSCBITEM;

class CBSColorComboBox : public CComboBox
{
 DECLARE_DYNCREATE(CBSColorComboBox)
 public:
  CBSColorComboBox();
  virtual ~CBSColorComboBox();
  BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
  //初始化组合框(第一个被调用的函数)
  void InitBSColorCB(void);
  //得到当前的颜色值或R/G/B值
  COLORREF GetColor();
  void GetRGBValue(int* R, int* G, int* B);
 public:
  //{{AFX_VIRTUAL(CBSColorComboBox)
   public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
  //}}AFX_VIRTUAL
 protected:
  bool m_bOverControl; //鼠标的状态(是否处于按钮上)
  int iIconX, iIconY; //SMALL ICON的大小尺寸
  COLORREF m_crColor; //当前选中的颜色
  CList<LPBSCBITEM, LPBSCBITEM> m_crItem;

  void OnCBPaint(CDC* pDC);
  LPBSCBITEM GetItem(int iIndex = 0);
 protected:
  //{{AFX_MSG(CBSColorComboBox)
   afx_msg BOOL OnEraseBkgnd(CDC* pDC);
   afx_msg void OnPaint();
   afx_msg void OnTimer(UINT nIDEvent);
   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
   afx_msg void OnSelchange();
   afx_msg void OnSelendok();
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};
#endif // !defined(_BS_BSCOLORCB)

///////////////////////////////////////////////////////////////CBSColorComboBox的实现文件;
#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;

 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();
   }
  }
 }
}

  四、小结

  上面的代码也适用于菜单等大多数控件的自画过程,其实本书在前面一些实例中也已经讲述了控件自画的内容,读者朋友们可以结合起来一起学习,相信一定能够把控件的自画这一内容掌握的一清二楚的。
[上一页] [1] [2]

(责任编辑:luwei)


我来说两句 全部跟贴 精华区 辩论区

用户:  匿名发表:  隐藏地址:
唯一能打出【范特西】的输入法!

设为辩论话题      


精彩图片新闻


激情四溢沙滩宝贝


数码公社专栏

相关链接





搜狐短信 小灵通 性感丽人 言语传情
三星图铃专区
[周杰伦] 千里之外
[誓 言] 求佛
[王力宏] 大城小爱
[王心凌] 花的嫁纱
精品专题推荐
短信企业通秀百变功能
浪漫情怀一起漫步音乐
同城约会今夜告别寂寞
敢来挑战你的球技吗?
 精彩生活 

星座运势 每日财运
花边新闻 魔鬼辞典
情感测试 生活笑话


今日运程如何?财运、事业运、桃花运,给你详细道来!!!





菊花台
迷迭香
青青河边草
丁香花
原来你也在这里
爱如空气
不要再来伤害我

公社热图


·北美惊现若干神秘UFO/图
·范冰冰真空写真露点[图]
·传说中国内第一美女车模


频道精彩推荐

·胡锦涛访问俄罗斯
·伊前副总统被绞刑
·邓小平南巡15周年
·在尼遭绑架中国人获救
·2007两会专题报道
·世乒赛 刘翔 篮球
·欧洲冠军联赛 体育彩票
·保时捷 天语SX4 凯美瑞
·标致206 荣威 长安奔奔
·搜狗紫光拼音输入法下载






不怕不怕
吉祥三宝
桃花朵朵开
千里之外
大城小爱
梁祝
迷糊娃娃可爱粉红卡通
四季美眉给你最想要的

news
搜狐分类 ·搜狐招商


创意就是这么简单
女星豪乳尺码大曝光
·现场抓拍明星着透视装
·芙蓉二代横空出世
·央视女主持辞职拍艳照
·徐若瑄15岁全裸写真曝光
·拍摄:娱乐圈性交易过程
·抓拍模特海滩宽衣解带
·外国女生流行拍的艺术照
·台湾十大波霸照片大比拼
·网络美女全裸人体摄影
·范冰冰终于还是脱了

推荐企业
2006年世界电信展 诺基亚 瑞星 联想 摩托罗拉 三星 清华紫光 金山 索尼爱立信 索尼
给编辑写信



设置首页 - 搜狗输入法 - 支付中心 - 搜狐招聘 - 广告服务 - 客服中心 - 联系方式 - 保护隐私权 - About SOHU - 公司介绍 - 全部新闻 - 全部博文
Copyright © 2018 Sohu.com Inc. All Rights Reserved. 搜狐公司 版权所有
搜狐不良信息举报邮箱:jubao@contact.sohu.com