⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 colorbtn.cpp

📁 Visual C++图形用户界面开发指南 李博轩等编著 配套源码光盘
💻 CPP
字号:
// ColorBtn.cpp : implementation file

#include "stdafx.h"
#include "ColorBtn.h"

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

CColorBtn::CColorBtn()
{
    m_CurrentColor = RGB(255,255,255);

    m_ColorDlg.m_Parent = this;


    m_NullPen.CreateStockObject(NULL_PEN);
    m_BlackPen.CreateStockObject(BLACK_PEN);
    m_WhitePen.CreateStockObject(WHITE_PEN);

    m_NullBrush.CreateStockObject(NULL_BRUSH);
    m_BackBrush.CreateSolidBrush(GetSysColor(COLOR_3DFACE));
    m_DkGrayPen.CreatePen(PS_SOLID,1,RGB(128,128,128)); 

    m_ColorWellShape = RECTANGLE;

}

CColorBtn::~CColorBtn()
{
}


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

/////////////////////////////////////////////////////////////////////////////
// CColorBtn message handlers


void CColorBtn::DrawItem(LPDRAWITEMSTRUCT lpd)
{
    CBrush colorbrush;
    CDC DC;
    DC.Attach(lpd->hDC);
    int top,left,bottom,right;

    top    = lpd->rcItem.top;
    left   = lpd->rcItem.left;
    bottom = lpd->rcItem.bottom;
    right  = lpd->rcItem.right;
                
    colorbrush.CreateSolidBrush(m_CurrentColor);
    
    m_OldPen   = DC.SelectObject(&m_NullPen);
    m_OldBrush = DC.SelectObject(&m_BackBrush);

    DC.Rectangle(&lpd->rcItem);

    if (!(lpd->itemState & ODS_SELECTED))
    {
        DC.SelectObject(&m_BlackPen);
        DC.MoveTo(left,bottom-1);
        DC.LineTo(right-1,bottom-1);
        DC.LineTo(right-1,top);
        DC.SelectObject(&m_DkGrayPen);
        DC.MoveTo(left+1,bottom-2);
        DC.LineTo(right-2,bottom-2);
        DC.LineTo(right-2,top+1);
        DC.SelectObject(&m_WhitePen);
        DC.LineTo(left+1,top+1);
        DC.LineTo(left+1,bottom-2);    
    }
    else
    {
        DC.SelectObject(&m_DkGrayPen);            
        DC.MoveTo(left,bottom-1);
        DC.LineTo(left,top);
        DC.LineTo(right-1,top);
        DC.SelectObject(&m_WhitePen);
        DC.MoveTo(right-1,top-1);
        DC.LineTo(right-1,bottom-1);
        DC.LineTo(left+1,bottom-1);
        DC.SelectObject(&m_BlackPen);
        DC.MoveTo(left+1,bottom-2);
        DC.LineTo(left+1,top+1);
        DC.LineTo(right-2,top+1);

        left++;
        right++;
        bottom++;
        top++;
    }

    DC.SelectObject(&m_WhitePen); 
    DC.MoveTo(right-10,top+4);
    DC.LineTo(right-10,bottom-4);
    DC.SelectObject(m_DkGrayPen);
    DC.MoveTo(right-11,top+4);
    DC.LineTo(right-11,bottom-4);

    if (lpd->itemState & ODS_DISABLED)
        DC.SelectObject(m_DkGrayPen);
    else
        DC.SelectObject(m_BlackPen);
    
    DC.MoveTo(right-4,(bottom/2)-1);
    DC.LineTo(right-9,(bottom/2)-1);

    DC.MoveTo(right-5,(bottom/2));
    DC.LineTo(right-8,(bottom/2));

    if (lpd->itemState & ODS_DISABLED)    
    {
        DC.SetPixel(right-4,(bottom/2)-1,RGB(255,255,255));
        DC.SetPixel(right-5,(bottom/2),RGB(255,255,255));
        DC.SetPixel(right-6,(bottom/2)+1,RGB(255,255,255));
    }
    else
    {
        DC.SetPixel(right-6,(bottom/2)+1,RGB(0,0,0));
    }

    if (!(lpd->itemState & ODS_DISABLED))
    {
        DC.SelectObject(&colorbrush);
        DC.Rectangle(left+5,top+4,right-15,bottom-4);    
    }

    if (lpd->itemState & ODS_FOCUS)
    {
        int i;
        for (i=left+3;i<right-4;i+=2)
        {
            DC.SetPixel(i,top+3,RGB(0,0,0));
            DC.SetPixel(i,bottom-4,RGB(0,0,0));
        }

        for (i=top+3;i<bottom-4;i+=2)
        {
            DC.SetPixel(left+3,i,RGB(0,0,0));
            DC.SetPixel(right-4,i,RGB(0,0,0));
        }       
    }
    DC.SelectObject(m_OldPen);
    DC.SelectObject(m_OldBrush);

    DC.Detach();    
}


void CColorBtn::OnClicked() 
{
	if (m_ColorDlg.DoModal() == IDOK)
    {
        m_CurrentColor = m_ColorDlg.m_SelectedColor;
        InvalidateRect(NULL);
    }	
}

void CColorBtn::Serialize( CArchive& ar )
{
}

void CColorBtn::SetSelectedColor(COLORREF Color)
{
   m_CurrentColor = Color;
   InvalidateRect(NULL);
}

COLORREF CColorBtn::GetColor()
{
   return m_CurrentColor;
}


void CColorBtn::ClearColorWells()
{
   if(m_ColorDlg.m_Colors.GetSize() > 0)
      m_ColorDlg.m_Colors.RemoveAll();
}

void CColorBtn::AddColorWell(COLORREF Color)
{
   m_ColorDlg.m_Colors.Add(Color);
}

void CColorBtn::SetColorsFromArray(CArray<COLORREF, COLORREF&>* ColorArray)
{
   short array_size = ColorArray->GetSize();
   COLORREF local_color;
   m_ColorDlg.m_Colors.SetSize(array_size);

   for(short loop = 0; loop < array_size; loop++)
      {
      local_color = ColorArray->GetAt(loop);
      m_ColorDlg.m_Colors.SetAt(loop, local_color);
      }
}

void CColorBtn::SetBorderThickness(short Outer, short Inner)
{
   m_ColorDlg.m_OuterBorderThickness = Outer;
   m_ColorDlg.m_InnerBorderThickness = Inner;
}

void CColorBtn::SetDialogWidth(short Width)
{
   m_ColorDlg.m_DialogWidth = Width;
}

void CColorBtn::SetNumColorWellColumns(short NumCols)
{
   m_ColorDlg.m_NumColorWellColumns = NumCols;
}

void CColorBtn::SetColorWellHeight(short Height)
{
   m_ColorDlg.m_ColorWellHeight = Height;
}

void CColorBtn::MakeColorWellsIsotropic(BOOL Yes)
{
   if(Yes)
      m_ColorDlg.m_IsotropicWells = TRUE;
   else
      m_ColorDlg.m_IsotropicWells = FALSE;
}

void CColorBtn::SetColorWellShape(short Shape)
{
   switch(Shape)
      {
      case RECTANGLE:
      case ELLIPSE:
         m_ColorWellShape = Shape;
         break;
      default:
         m_ColorWellShape = RECTANGLE;
         break;
      }
}
   
short CColorBtn::GetColorWellShape()
{
   return m_ColorWellShape;
}

/////////////////////////////////////////////////////////////////////////////
// CColorBtnDlg dialog


CColorBtnDlg::CColorBtnDlg(CWnd* pParent /*=NULL*/)
{
	//{{AFX_DATA_INIT(CColorBtnDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
   m_SelectedColor = RGB(255,255,255);
   m_DialogWidth = 41;
   m_NumColorWellColumns = 4;
   m_ColorWellHeight = 9;
   m_OuterBorderThickness = 1;
   m_InnerBorderThickness = 1;
   m_StartingButtonID = 5000;
   m_IsotropicWells = TRUE;

   CreateDialogFromTemplate();
   
}

CColorBtnDlg::~CColorBtnDlg()
{
   GlobalUnlock(m_GlobalLock);
	GlobalFree(m_GlobalLock);
   
}

void CColorBtnDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CColorBtnDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CColorBtnDlg, CDialog)
	//{{AFX_MSG_MAP(CColorBtnDlg)
	ON_WM_LBUTTONDOWN()	
	ON_WM_LBUTTONUP()
    ON_WM_DRAWITEM()	
	//}}AFX_MSG_MAP
   // ON_COMMAND_RANGE(IDC_COLOR_WELL1,IDC_COLOR_WELL16,OnColor)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CColorBtnDlg message handlers

BOOL CColorBtnDlg::OnInitDialog() 
{
   CDialog::OnInitDialog();

   CRect dialog_rect, color_well_rect, parent_button_rect;
   short dialog_height, color_well_width;
   short num_buttons, num_rows;
   int tempx, tempy;

   if(m_Colors.GetSize() == 0)
      EndDialog(IDCANCEL);
   
   
   if(m_OuterBorderThickness < MIN_OUTER_BORDER)
      m_OuterBorderThickness = MIN_OUTER_BORDER;
   if(m_OuterBorderThickness > MAX_OUTER_BORDER)
      m_OuterBorderThickness = MAX_OUTER_BORDER;

   if(m_InnerBorderThickness < MIN_INNER_BORDER)
      m_InnerBorderThickness = MIN_INNER_BORDER;
   if(m_InnerBorderThickness > MAX_INNER_BORDER)
      m_InnerBorderThickness = MAX_INNER_BORDER;

   if(m_NumColorWellColumns < MIN_NUMCOLORWELLCOLS)
      m_NumColorWellColumns = MIN_NUMCOLORWELLCOLS;
   if(m_NumColorWellColumns > MAX_NUMCOLORWELLCOLS)
      m_NumColorWellColumns = MAX_NUMCOLORWELLCOLS;
   
   tempx = GetSystemMetrics(SM_CXDLGFRAME);

   color_well_width = (m_DialogWidth -
                       (2*tempx) -
                       (2*m_OuterBorderThickness) -
                       ((m_NumColorWellColumns-1) * m_InnerBorderThickness)) /
                       m_NumColorWellColumns;
   
   if(color_well_width < MIN_WELL_WIDTH)
      {
      color_well_width = MIN_WELL_WIDTH;
      }
   
   m_DialogWidth = ((2*m_OuterBorderThickness) +
                        (2*tempx) +
                        (m_NumColorWellColumns * color_well_width) +
                        ((m_NumColorWellColumns-1)* m_InnerBorderThickness));


   
   num_buttons = m_Colors.GetSize();
   num_rows = num_buttons/m_NumColorWellColumns;
   if( (num_rows * m_NumColorWellColumns) < num_buttons)
      {
      num_rows++;
      }

   tempy = GetSystemMetrics(SM_CYDLGFRAME);

   if(m_ColorWellHeight < MIN_WELL_HEIGHT)
      m_ColorWellHeight = MIN_WELL_HEIGHT;

   if(m_IsotropicWells)
      m_ColorWellHeight = color_well_width;

   dialog_height = (2*m_OuterBorderThickness) +
                     (2*tempy) +
                     (m_ColorWellHeight*num_rows) +
                     (m_InnerBorderThickness *(num_rows-1));
   
    
	 m_Parent->GetWindowRect(&parent_button_rect);
    
    SetWindowPos(NULL,
               parent_button_rect.left,
               parent_button_rect.bottom,
               m_DialogWidth,
               dialog_height,
               SWP_NOZORDER | SWP_DRAWFRAME);

    GetWindowRect(&dialog_rect);

   
    if (dialog_rect.bottom > GetSystemMetrics(SM_CYSCREEN))
    {   
        dialog_rect.top = parent_button_rect.top-(dialog_rect.bottom-dialog_rect.top);        
    }

    if (dialog_rect.right > GetSystemMetrics(SM_CXSCREEN))
    {
        dialog_rect.left = GetSystemMetrics(SM_CXSCREEN) - 
           (dialog_rect.right-dialog_rect.left);
    }

    SetWindowPos(NULL,dialog_rect.left,dialog_rect.top,0,0,SWP_NOSIZE|SWP_NOZORDER);

    CButton *temp_button;
    short column = 1, row = 1;
    short upperleft_x, upperleft_y;
    
    for(short loop = 0; loop < num_buttons; loop++)
       {
       if(column > m_NumColorWellColumns)
          {
          row++;
          column = 1;
          }
       upperleft_x = m_OuterBorderThickness +
                  (column-1)*(color_well_width + m_InnerBorderThickness);
       upperleft_y = m_OuterBorderThickness +
                  (row-1)*(m_ColorWellHeight + m_InnerBorderThickness);

       color_well_rect.SetRect(upperleft_x, 
                     upperleft_y, 
                     upperleft_x + color_well_width, 
                     upperleft_y + m_ColorWellHeight);

       temp_button = new CButton;
       temp_button->Create( "", BS_OWNERDRAW | BS_PUSHBUTTON| WS_TABSTOP | WS_CHILD | 
          WS_VISIBLE | WS_EX_CLIENTEDGE, 
          color_well_rect, this, m_StartingButtonID + loop );
       
       column++;
       }

   
    SetCapture();
	
	return TRUE; 
}

void CColorBtnDlg::EndDialog( int nResult ){
    ReleaseCapture();

    CDialog::EndDialog(nResult);
   
   CWnd *child = (CWnd*) GetTopWindow();
   while(child != NULL)
      {
      delete child;
      child = (CWnd*) GetTopWindow();
      }

}

void CColorBtnDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
    RECT r;

    POINT p;
    p.x = point.x;
    p.y = point.y;

    ClientToScreen(&p);

    GetWindowRect(&r);


    if (!PtInRect(&r,p))
    {

        EndDialog(IDCANCEL);
    }
    else
    {
        
        CWnd *child = ChildWindowFromPoint(point);
         
        if (child && child != this)
           {
           OnColor(child->GetDlgCtrlID()); 
           }
    }
	
	CDialog::OnLButtonDown(nFlags, point);
}

void CColorBtnDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpd) 
{
	CDC dc;
   CPen m_NullPen;
   CBrush brush;
   CPen *oldpen;
   CBrush *oldbrush;
   short shape;

   m_NullPen.CreateStockObject(NULL_PEN);
   brush.CreateSolidBrush(m_Colors.GetAt(nIDCtl-m_StartingButtonID));

   dc.Attach(lpd->hDC);

   oldpen = dc.SelectObject(&m_NullPen);
   oldbrush = dc.SelectObject(&brush);
   
   shape = ((CColorBtn*)m_Parent)->GetColorWellShape();
   switch(shape)
      {
      case CColorBtn::RECTANGLE:
         lpd->rcItem.right++;
         lpd->rcItem.bottom++;
         dc.Rectangle(&lpd->rcItem);
         break;
      case CColorBtn::ELLIPSE:
         lpd->rcItem.right++;
         lpd->rcItem.bottom++;
         dc.Ellipse(&lpd->rcItem);
         break;
      default:
         ASSERT(FALSE);
         break;
      }

   dc.SelectObject(oldpen);
   dc.SelectObject(oldbrush);

   dc.Detach();
	
}

void CColorBtnDlg::OnColor(UINT id){
    m_SelectedColor = m_Colors.GetAt(id-m_StartingButtonID);

    EndDialog(IDOK);}
void CColorBtnDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
    CWnd *child = ChildWindowFromPoint(point,CWP_ALL);
    
    if (child && child != this)
       {
       OnColor(child->GetDlgCtrlID());	
       }
	
	CDialog::OnLButtonUp(nFlags, point);
}

void CColorBtnDlg::CreateDialogFromTemplate()
{
	m_dlgTempl.cx = 40; 
	m_dlgTempl.cy = 80; 
	m_dlgTempl.style = DS_MODALFRAME | WS_POPUP;
	m_dlgTempl.dwExtendedStyle = 0;
	m_dlgTempl.x = 0;
	m_dlgTempl.y = 0;
	m_dlgTempl.cdit = 0; 

	int		total_length = 0;  

	try  
	{
		int buffer_size =  sizeof(DLGTEMPLATE) + (3 * sizeof(WORD));

		buffer_size = (buffer_size + 3) & ~3; 
		m_GlobalLock = GlobalAlloc(LHND, buffer_size);
		if (m_GlobalLock == NULL)
			AfxThrowMemoryException();

		BYTE*	buffer_ptr = (BYTE*)GlobalLock(m_GlobalLock);
		if (buffer_ptr == NULL)
		{
			GlobalFree(m_GlobalLock);
			AfxThrowMemoryException();
		}

		BYTE*	destination_ptr = buffer_ptr;
	
		memcpy(destination_ptr, &m_dlgTempl, sizeof(DLGTEMPLATE));
		destination_ptr += sizeof(DLGTEMPLATE);
		*(WORD*)destination_ptr = 0; 
		*(WORD*)(destination_ptr + 1) = 0;
      *(WORD*)(destination_ptr + 2) = 0; 
		destination_ptr += 3 * sizeof(WORD);
		
		ASSERT(destination_ptr - buffer_ptr == buffer_size); 

		InitModalIndirect((DLGTEMPLATE*)buffer_ptr);

		
	}
	catch(CException *e)
	{
	   AfxMessageBox("内存不足", MB_ICONEXCLAMATION | MB_OK);
      delete e;
      throw;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -