亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在VC++應用程序中實現顏色選擇組合框

2019-11-17 05:10:13
字體:
來源:轉載
供稿:網友

  相信讀者朋友們對Office2000一定非常熟悉吧,它里面的東東可真不少,不管是活潑可愛的"大眼夾",還是各種平面造型的Windows控件都很受廣大用戶喜歡。那么這次就讓我們來模擬它做個十分常用的控件:"顏色組合框"。假如你現在正在做關于字處理類的軟件時這個"東東"一定對你有用。程序編譯運行后的界面效果如圖一所示:

在VC++應用程序中實現顏色選擇組合框(圖一)
圖一、顏色選擇組合框
  一、實現方法

  首先讓我們先來了解一下畫控件的基本原理和過程,也許這個才是本文的原意。大家都知道Windows中所有可視的東西都是畫出來的,那么這個畫畫的內部過程又是怎樣的呢?一般畫Windows控件的過程分為三大部分:一是在WM_MEASUREITEM消息影射函數中設置當前要畫的Item的大小尺寸;二是在WM_DRAWITEM消息影射函數中根據Item的大小尺寸來畫該Item(圖標/位圖/字符串等);三是在WM_PAINT消息映射函數中不斷的繪制當前的控件內容。下面我們針對CBSColorComboBox類的這幾個過程來做個簡單的介紹:

  在WM_MEASUREITEM消息影射函數中設定Item的大小尺寸的時候,我們只需要設置Item的高度即可。這里的高度我們設置為2倍的系統小圖標(SMALL ICON)的高度,其尺寸用::GetSystemMetrics(SM_CXSMICON)取得。

  Visual C++的程序開發人員可以在Item的矩形區域內畫各種各樣的信息,例如:圖標/位圖/字符串等等。那么有人會疑問:"我們用什么來畫?我們在哪里畫?又如何來畫呢?"。答案其實都在這個LPDRAWITEMSTRUCT結構中。hDC成員為設備上下文環境(HDC),獲得了該設備句柄也就意味著我們擁有了畫任何位圖/圖標/文本的能力;那么接下來的問題就是:我們在哪里來畫呢?答案也很簡單:獲得LPDRAWITEMSTRUCT結構中Item的矩形區域(rcItem),那么這就是你施展才華的空間了,要充分利用它哦!

  最后一步就是如何來畫的問題了,說白了就是如何分配每個元素的空間,如何在它們各自的空間上畫出你想要的東西。按照常規一般分別計算出ICON所占的矩形區域/文本所占的矩形區域/位圖的矩形區域,假如你還有其他元素那么也應該計算出該元素所占的矩形區域/位圖所占的矩形區域。接下來的一切都很簡單了,不外乎CDC類的幾個常用函數:畫圖標用DrawIcon()、畫位圖用BitBlt()、畫文字用DrawText()等函數。假如你覺得視覺上還不夠COOL,你還可以來設置各個Item的文本顏色,背景顏色,以及圖標的突起和凹陷的視覺效果。

  不過在上述過程中需要注重三個問題,一是為了消除不斷繪制所帶來的閃爍現象,需要在WM_ERASEBKGND消息響應中作些非凡處理;在WM_PAINT消息中直接把組合框的客戶區當成一幅位圖來不斷更新,而不是對ICON區域和文本區域分別重繪。二是每當用戶改變了組合框的當前內容后,在畫新的Item之前一定要記得清除前次組合框內的內容。三是假如想選擇更多的顏色,那么只要選擇組合框中的最后一個Item(More Colors)即可,這個Item是為用戶自定義顏色而專門設置的。

  二、編程步驟

  1、啟動Visual C++6.0,生成一個基于對話框的項目,將該項目命名為"WW";

  2、使用Class Wizard新建一個類CBSColorComboBox,其基類選擇為CComboBox類;

  3、在程序的對話框中放置一個ComboBox控件,使用CLASSWIZARD添加相應的CComboBox類成員變量,然后將該成員變量的類型修改為CBSColorComboBox;

  4、添加代碼,編譯運行程序。 三、程序代碼

//////////////////////////////////////////////////////////////CBSColorComboBox類的頭文件;
#if !defined(_BS_BSCOLORCB)
#define _BS_BSCOLORCB
#include

//系統常用顏色的自定義名稱
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; //當前選中的顏色
  CListm_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();
   }
  }
 }
}

  四、小結

  上面的代碼也適用于菜單等大多數控件的自畫過程,其實本書在前面一些實例中也已經講述了控件自畫的內容,讀者朋友們可以結合起來一起學習,相信一定能夠把控件的自畫這一內容把握的一清二楚的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美在线国产| 26uuu日韩精品一区二区| 欧美美女18p| 日韩视频免费大全中文字幕| 欧美激情视频一区| 日本中文字幕不卡免费| 国产欧美日韩精品在线观看| 2019国产精品自在线拍国产不卡| 欧美成人小视频| 91精品久久久久久久久久久久久| 国产精品久久久久久超碰| 欧美精品激情在线观看| 亚洲欧美一区二区三区久久| 日韩精品亚洲视频| 中文字幕亚洲无线码在线一区| 亚洲精品电影在线观看| 8x海外华人永久免费日韩内陆视频| 日本久久精品视频| 国产亚洲成av人片在线观看桃| 日本免费在线精品| 久久精品久久久久久| 秋霞午夜一区二区| 欧美黄色三级网站| 法国裸体一区二区| 成人h视频在线观看播放| 欧美一区二区大胆人体摄影专业网站| 欧美孕妇毛茸茸xxxx| 亚洲一级片在线看| 日韩欧美精品在线观看| 国产精品久久久久久久久久东京| 欧美日韩综合视频| 热re91久久精品国99热蜜臀| 亚洲综合在线小说| 九九精品在线播放| 色综合久综合久久综合久鬼88| 亚洲美女在线视频| 欧美—级a级欧美特级ar全黄| 国产精品高清网站| 亚洲在线观看视频网站| 亚洲视频在线视频| 俺去亚洲欧洲欧美日韩| 黑人巨大精品欧美一区免费视频| 日韩av在线免费看| 日韩精品在线免费| 国产精品成人av在线| 欧美视频在线观看免费| 亚洲www在线观看| 成人黄色片在线| 久久久久九九九九| 亚洲免费人成在线视频观看| 欧美性jizz18性欧美| 中文字幕欧美国内| 91精品国产成人www| 2018日韩中文字幕| 91久久精品国产91久久| 亚洲剧情一区二区| 亚洲香蕉成视频在线观看| 日韩高清人体午夜| 日韩成人中文字幕| 日本伊人精品一区二区三区介绍| 91精品在线国产| 97视频色精品| 97不卡在线视频| 日韩精品免费一线在线观看| 亚洲影院色在线观看免费| 97香蕉超级碰碰久久免费的优势| 最新国产精品亚洲| 精品视频久久久久久久| 国产精品高潮呻吟视频| 国产情人节一区| 狠狠色狠狠色综合日日小说| 亚洲欧洲中文天堂| 国产欧美婷婷中文| 日韩欧美国产视频| 欧美成人国产va精品日本一级| 国产视频精品久久久| 国产精品jizz在线观看麻豆| 91精品视频免费| 日韩中文有码在线视频| 欧美日韩第一视频| 日韩成人在线观看| 91精品国产91久久久久久最新| 欧美天天综合色影久久精品| 亚洲综合在线播放| 91精品久久久久久久久不口人| 91精品国产777在线观看| 久久综合九色九九| 欧美有码在线观看视频| 亚洲国产高潮在线观看| 久久久久久亚洲精品| 欧美电影免费观看大全| 日韩欧美主播在线| 日韩亚洲在线观看| 成人av在线网址| 色综合久久88色综合天天看泰| 日本老师69xxx| 日韩在线视频免费观看高清中文| 欧美日产国产成人免费图片| 7777免费精品视频| 亚洲新中文字幕| 秋霞成人午夜鲁丝一区二区三区| 亚洲人成网在线播放| 欧美日韩久久久久| 欧美最猛性xxxxx(亚洲精品)| 亚洲**2019国产| 久久天天躁狠狠躁夜夜爽蜜月| 欧美极度另类性三渗透| 日韩69视频在线观看| 亚洲国产毛片完整版| 一区二区三区视频在线| 中文字幕亚洲在线| 亚洲品质视频自拍网| 亚洲精品一区二区三区不| 日韩精品免费观看| 久久精品国产欧美亚洲人人爽| 高清欧美性猛交xxxx| 亚洲天堂免费在线| 亚洲免费视频观看| 91成人精品网站| 国产视频999| 久久久精品影院| 欧美午夜精品伦理| 亚洲欧美精品中文字幕在线| 国产精品成人一区二区| 国产美女直播视频一区| 欧美乱大交xxxxx另类电影| 51ⅴ精品国产91久久久久久| 欧美激情亚洲视频| 久久精品国产欧美亚洲人人爽| 在线精品视频视频中文字幕| 久久好看免费视频| 国产男人精品视频| 久久免费成人精品视频| 国产精品久久av| www.亚洲免费视频| 91精品久久久久久久久久| 欧美电影在线观看完整版| 欧美一级bbbbb性bbbb喷潮片| 深夜福利一区二区| 国产成人免费av| 国产精品入口免费视| 欧美黑人巨大精品一区二区| 欧美视频精品一区| 亚洲国产成人精品久久| 中文字幕在线精品| 91色琪琪电影亚洲精品久久| 日韩一区二区久久久| 亚洲第一天堂无码专区| 久久久久久久香蕉网| 琪琪第一精品导航| 亚洲欧美精品在线| 国产成人精品a视频一区www| 91欧美精品成人综合在线观看| 亚洲国产日韩精品在线| 97精品久久久| 奇米一区二区三区四区久久| 中文字幕日韩专区| 91免费福利视频| 日韩精品在线视频| 精品亚洲夜色av98在线观看| 青青草国产精品一区二区| 久久国产精品久久精品| 精品爽片免费看久久| 国产99久久精品一区二区 夜夜躁日日躁|