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