从CButton派生一个选择颜色的颜色选择控件


#pragma once

// ColourPicker.h : header file

/
// CColourPicker window
void AFXAPI DDX_ColourPicker(CDataExchange *pDX, UINT nIDC, COLORREF& crColour);

class CColourPicker : public CButton
{
// Construction
public:
  CColourPicker();

public:
  COLORREF GetColour() { return( m_crColourBk ); };
  void SetColour(COLORREF color) { m_crColourBk = color; Invalidate(); }

// Attributes
private:
  COLORREF m_crColourBk, m_crColourText;

// Operations
public:

// Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CColourPicker)
public:
  virtual BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
  virtual void PreSubclassWindow(); 
  virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
  //}}AFX_VIRTUAL

// Implementation
public:
  virtual ~CColourPicker();

  // Generated message map functions
protected:
  //{{AFX_MSG(CColourPicker)
  afx_msg void OnClicked();
  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()

};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.



// ColourPicker.cpp : implementation file
//

#include "stdafx.h"
#include "ColourPicker.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void AFXAPI DDX_ColourPicker(CDataExchange *pDX, UINT nIDC, COLORREF& crColour)
{
  HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  ASSERT (hWndCtrl != NULL);                
  
  CColourPicker* pColourPicker = (CColourPicker*) CWnd::FromHandle(hWndCtrl);
  if (pDX->m_bSaveAndValidate)
  {
    crColour = pColourPicker->GetColour();
  }
  else // initializing
  {
    pColourPicker->SetColour(crColour);
  }
}

/
// CColourPicker

CColourPicker::CColourPicker()
{
  m_crColourText = RGB(0,0,0);
  m_crColourBk = RGB(255,255,255);
}

CColourPicker::~CColourPicker()
{
}


BEGIN_MESSAGE_MAP(CColourPicker, CButton)
  //{{AFX_MSG_MAP(CColourPicker)
  ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CColourPicker message handlers
BOOL CColourPicker::Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
  dwStyle |= BS_OWNERDRAW;
  return CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID);
}

void CColourPicker::PreSubclassWindow()
{
  CButton::PreSubclassWindow();
  ModifyStyle(0, BS_OWNERDRAW, 0);
}

void CColourPicker::OnClicked() 
{
  //CColorDialog m_ColorDlg( GetColour() );
  CColorDialog m_ColorDlg( GetColour(), 0, this );
  if(m_ColorDlg.DoModal() == IDOK)
  {
    SetColour( m_ColorDlg.GetColor() );
  }
}

void CColourPicker::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
  ASSERT(lpDrawItemStruct);
  
  CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
  CRect   rect    = lpDrawItemStruct->rcItem;
  UINT    state   = lpDrawItemStruct->itemState;
  DWORD   dwStyle = GetStyle();
  CString m_strText;

  CSize MarginSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  // Get size of dropdown arrow
  INT nArrowWidth = max(::GetSystemMetrics(SM_CXHTHUMB), 5*MarginSize.cx);
  INT nArrowHeight = max(::GetSystemMetrics(SM_CYVTHUMB), 5*MarginSize.cy);
  CSize ArrowSize(max(nArrowWidth, nArrowHeight), max(nArrowWidth, nArrowHeight));
  CRect m_ArrowRect(rect.right - ArrowSize.cx - MarginSize.cx, 
                      rect.top + MarginSize.cy, rect.right - MarginSize.cx,
                      rect.bottom - MarginSize.cy);

  CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));

  // Draw arrow
  //if (m_bActive) state |= ODS_SELECTED;
  pDC->DrawFrameControl(&m_ArrowRect, DFC_SCROLL, DFCS_SCROLLDOWN  | 
                        ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
                        ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));

  pDC->DrawEdge(rect, EDGE_SUNKEN, BF_RECT);

  // Must reduce the size of the "client" area of the button due to edge thickness.
  rect.DeflateRect(Margins.cx, Margins.cy);

  // Fill remaining area with colour
  rect.right -= m_ArrowRect.Width();

  CBrush brush((state & ODS_DISABLED)? ::GetSysColor(COLOR_3DFACE) : m_crColourBk);
  CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  pDC->SelectStockObject(NULL_PEN);
  pDC->Rectangle(rect);
  pDC->SelectObject(pOldBrush);

  // Draw the window text (if any)
  GetWindowText(m_strText);
  if (m_strText.GetLength())
  {
    pDC->SetBkMode(TRANSPARENT);
    if (state & ODS_DISABLED)
    {
      rect.OffsetRect(1,1);
      pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
      pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
      rect.OffsetRect(-1,-1);
      pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
      pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
    }
    else
    {
      pDC->SetTextColor(m_crColourText);
      pDC->DrawText(m_strText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
    }
  }

  // Draw focus rect
  if (state & ODS_FOCUS) 
  {
    rect.DeflateRect(1,1);
    pDC->DrawFocusRect(rect);
  }  
}

//测试CDlg1000Dlg.h

  // Dialog Data
  //{{AFX_DATA(CDlg1000Dlg)
  CColourPicker	m_ColorPickerButton;
  //}}AFX_DATA
  COLORREF crColorPicker;

void CDlg1000Dlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CDlg1000Dlg)
  DDX_Control(pDX, IDC_BUTTON1, m_ColorPickerButton);
  DDX_ColourPicker(pDX, IDC_BUTTON1, crColorPicker);
  //}}AFX_DATA_MAP
}

运行效果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是实现代码: 首先,我们需要创建一个自定义的对话框栏类,派生自CDialogBar: ``` class CMyDialogBar : public CDialogBar { DECLARE_DYNAMIC(CMyDialogBar) public: CMyDialogBar(); virtual ~CMyDialogBar(); protected: DECLARE_MESSAGE_MAP() private: // 用于存储按钮信息的结构体 struct ButtonInfo { CString text; // 按钮文本 COLORREF color; // 按钮背景颜色 }; std::vector<ButtonInfo> m_buttons; // 存储所有按钮信息的容器 public: // 添加一个按钮 void AddButton(const CString& text, COLORREF color); protected: virtual BOOL OnInitDialogBar(); virtual void DoDataExchange(CDataExchange* pDX); virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler); afx_msg void OnPaint(); }; ``` 在该类中,我们使用了一个vector容器m_buttons来存储所有按钮的信息,每个按钮信息包括文本和背景颜色。对外提供一个AddButton方法,用于添加一个按钮。 在类的实现文件中,我们需要实现AddButton方法: ``` void CMyDialogBar::AddButton(const CString& text, COLORREF color) { ButtonInfo info = { text, color }; m_buttons.push_back(info); } ``` 接下来,我们需要实现OnInitDialogBar方法,该方法在对话框栏创建时被调用。在该方法中,我们需要根据传入的按钮数量和信息,创建对应数量的按钮,并设置按钮的文本和背景颜色: ``` BOOL CMyDialogBar::OnInitDialogBar() { if (!CDialogBar::OnInitDialogBar()) return FALSE; // 计算按钮宽度 CRect rect; GetClientRect(&rect); int buttonWidth = rect.Width() / m_buttons.size(); // 创建每个按钮 for (int i = 0; i < m_buttons.size(); ++i) { CButton* button = new CButton(); button->Create(m_buttons[i].text, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, CRect(i * buttonWidth, 0, (i + 1) * buttonWidth, rect.Height()), this, 0); // 设置按钮背景颜色 CBrush brush(m_buttons[i].color); button->SetFace(&brush, TRUE); } return TRUE; } ``` 在该方法中,我们首先计算每个按钮的宽度,然后循环创建每个按钮,设置按钮的位置、文本和背景颜色。 接下来,我们需要实现OnPaint方法,该方法在对话框栏需要重绘时被调用。在该方法中,我们需要绘制每个按钮的边框: ``` void CMyDialogBar::OnPaint() { CPaintDC dc(this); // device context for painting // 绘制按钮边框 CRect rect; GetClientRect(&rect); int buttonWidth = rect.Width() / m_buttons.size(); for (int i = 0; i < m_buttons.size() - 1; ++i) { dc.MoveTo((i + 1) * buttonWidth, 0); dc.LineTo((i + 1) * buttonWidth, rect.Height()); } } ``` 最后,我们需要实现DoDataExchange和OnUpdateCmdUI方法,以便在需要更新控件状态时正确响应: ``` void CMyDialogBar::DoDataExchange(CDataExchange* pDX) { CDialogBar::DoDataExchange(pDX); } void CMyDialogBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) { CDialogBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler); } ``` 至此,我们的自定义对话框栏类CMyDialogBar就完成了。完整代码如下: ``` // MyDialogBar.h #pragma once #include <vector> class CMyDialogBar : public CDialogBar { DECLARE_DYNAMIC(CMyDialogBar) public: CMyDialogBar(); virtual ~CMyDialogBar(); protected: DECLARE_MESSAGE_MAP() private: // 用于存储按钮信息的结构体 struct ButtonInfo { CString text; // 按钮文本 COLORREF color; // 按钮背景颜色 }; std::vector<ButtonInfo> m_buttons; // 存储所有按钮信息的容器 public: // 添加一个按钮 void AddButton(const CString& text, COLORREF color); protected: virtual BOOL OnInitDialogBar(); virtual void DoDataExchange(CDataExchange* pDX); virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler); afx_msg void OnPaint(); }; // MyDialogBar.cpp #include "stdafx.h" #include "MyDialogBar.h" IMPLEMENT_DYNAMIC(CMyDialogBar, CDialogBar) CMyDialogBar::CMyDialogBar() { } CMyDialogBar::~CMyDialogBar() { } BEGIN_MESSAGE_MAP(CMyDialogBar, CDialogBar) ON_WM_PAINT() END_MESSAGE_MAP() void CMyDialogBar::AddButton(const CString& text, COLORREF color) { ButtonInfo info = { text, color }; m_buttons.push_back(info); } BOOL CMyDialogBar::OnInitDialogBar() { if (!CDialogBar::OnInitDialogBar()) return FALSE; // 计算按钮宽度 CRect rect; GetClientRect(&rect); int buttonWidth = rect.Width() / m_buttons.size(); // 创建每个按钮 for (int i = 0; i < m_buttons.size(); ++i) { CButton* button = new CButton(); button->Create(m_buttons[i].text, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, CRect(i * buttonWidth, 0, (i + 1) * buttonWidth, rect.Height()), this, 0); // 设置按钮背景颜色 CBrush brush(m_buttons[i].color); button->SetFace(&brush, TRUE); } return TRUE; } void CMyDialogBar::OnPaint() { CPaintDC dc(this); // device context for painting // 绘制按钮边框 CRect rect; GetClientRect(&rect); int buttonWidth = rect.Width() / m_buttons.size(); for (int i = 0; i < m_buttons.size() - 1; ++i) { dc.MoveTo((i + 1) * buttonWidth, 0); dc.LineTo((i + 1) * buttonWidth, rect.Height()); } } void CMyDialogBar::DoDataExchange(CDataExchange* pDX) { CDialogBar::DoDataExchange(pDX); } void CMyDialogBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) { CDialogBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值