国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

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

  四、小結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 五原县| 松原市| 堆龙德庆县| 屏南县| 仁怀市| 太湖县| 喜德县| 塘沽区| 广水市| 抚州市| 建始县| 抚松县| 清丰县| 额济纳旗| 崇明县| 彰化市| 万源市| 修武县| 苗栗市| 大田县| 罗甸县| 阿拉善盟| 安西县| 桐城市| 车险| 丰都县| 米林县| 高阳县| 永修县| 且末县| 杭州市| 综艺| 乌鲁木齐市| 遵义市| 阳曲县| 乐昌市| 横山县| 阿拉尔市| 土默特右旗| 盐池县| 建水县|