自定义的button

类名CBtnSkinA

 1.变量
(1)首先,需要做的bt是个三态按钮,因此必须定义一个变量,m_state来表明bt的状态。
typedef emun state{NORMAL,HOVER,DOWN} state;
state m_state;
(2)如果需要在图片上写文字,定义CFONT的对象。
CFont *m_font;
(3)如果按钮上需要覆盖图片的话,需定义一个CImage对象。
CImage img;
(4)同样我们需要两个COLOREF对象,表明颜色。
COLOREF m_fg,m_bg;
(5)我们还需要一个CDC,用来对内存进行操作;
CDC m_memDC;
2.方法
首先我们需要一个析构函数,用来对类进行初始化:
CBtnSkinA::CBtnSkinA()
{
    m_state = NORMAL;//按钮初始状态正常

    m_font = new CFont;//注意一定要先创建对象,然后才能调用其方法。
    m_font->CreatePointFont(90,_T("Arial"));//创建字体

    m_fg=RGB(0,0,0);
    m_bg=RGB(255,255,255);
}
还有另外一个用于善后的,删除指针所指向的空间
CBtnSkinA::~CBtnSkinA()
{
    delete m_font;
    m_memDC.DeleteDC();
}

首先需要按钮的状态:
void CBtnSkinA::DrawItem(LPDRAWITEMSTRUCT lpDIS)
//LPDRAWITEMSTRUCT是个指针指向DRAWITEMSTRUCT Structure
{
 UINT state = lpDIS->itemState; //通过LPDRAWITEMSTRUCT来获得按钮的状态

 m_state = NORMAL; //初始化按钮的状态为正常


 //判断按钮的状态
 if (state & ODS_FOCUS)
 {
  if (state & ODS_SELECTED)
  {
   m_state = DOWN;
  }
  else
  {
   if(m_bMouseOver)
    m_state = HOVER;
  }
 }
 else
 {
  m_state = NORMAL;
 }

 DrawButton();//确定按钮状态后进行绘制
}

void CBtnSkinA::DrawButton()
{
    CClient dc(this); //获得客户区的DC

    CRect rect;//用于获得客户区窗口大小的rect
    GetClientRect(&rect);

//绘制窗口
//    函数原型:HDC CreateCompatibleDC(HDC hdc);
//    参数:hdc:现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境。
//    函数原型:HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight);
//    参数:
//    hdc: 设备环境句柄。
//    nWidth:指定位图的宽度,单位为像素。
//    nHeight:指定位图的高度,单位为像素。
//返回值:如果函数执行成功,那么返回值是位图的句柄;如果函数执行失败,那么返回值为NULL。若想获取更多错误信息,用GetLastError

   CDC memDC;
   memDC.CreateComptibleDC(&dc);//在内存中建立一个与刚才建立的设备场景一致的设备场景

   CBitmap screen;
   screen.CreateComptibleBitmap(&dc,rect.width(),rect.height());//获得同窗口一样大小的图像
  
   memDC.SelectObect(&screen);
   screen.DeleteObject();  //注意及时删除指针对象  

   //画背景
   //Copies a bitmap from the source device context to this current device context.

   memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &m_memDC, 0, 0, SRCCOPY);

   memDC.SetBkMode(TRANSPARENT);//背景始终不变
  
   int sx,sy;
   int iw,ih;
   sy = rect.top;
   iw = img.Width();
   ih = img.Height();

   //根据图片的不同状态显示不同的图片 
   swith(m_state)
   {
 case NORMAL:
        sx = 0;
        if(img.IsNull())
     img.TransparentBlt(memDC,rect.left,rect.top,iw,ih,sx,sy,iw,ih,RGB(215,238,253));
 case HOVER
 sx = img.Width()/3;
 if(img.IsNull())
     img.TransparentBlt(memDC,rect.left,rect.top,iw,ih,sx,sy,iw,ih,RGB(215,238,253));
 case DOWN:
 sx = imgButton.GetWidth()*2/3;
 if(!imgButton.IsNull())
     imgButton.TransparentBlt(memDC,rect.left, rect.top,iw,ih,sx,sy,iw,ih,RGB(215,238,253));
     break;
 default:
     break;
    }

    dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
    memDC.DeleteDC();
   }
}

//自定义字体

void CBtnSkinA::DrawButtonText(CDC *DC, CRect R, CString str, COLORREF TextColor)
{
    COLOPREF prevColor = DC->SetTextColor(TextColor);//设置字体颜色,并保存原来的颜色
    DC->SetBkMode(TRANSPARENT); //设置背景模式
    DC->SelectObject(m_pFont); //选择字体
    DC->DrawText( str, str.GetLength(), R, DT_RIGHT|DT_VCENTER|DT_SINGLELINE);//写字
    DC->SetTextColor(prevColor);
}

//对鼠标的移动进行判断

void CBtnSkinA::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 //若m_bMouseOver为真时,显然不执行自定义的方法
 //若m_bMouseOver为false时,
 if(!m_bMouseOver&&m_bEnabled)     //如果鼠标不在按钮上面并且按钮的状态不是为无效状态
 {
  m_bMouseOver=true;  //类似于死锁的原理
  m_state = HOVER;

  CPoint point;//表示鼠标的位置
  CRect rect; //表示按钮的实际位置
  GetWindowRect(&rect); //获得按钮的窗口大小
  GetCursorPos(&point); //获得鼠标的位置
  if (!rect.PtInRect(point) && m_bMouseOver &&m_bEnabled) //
  {
   SetTimer(1,10,NULL);
   return;
  }

  DrawButton();
  
  SetTimer(1,10,NULL);
 }
 CButton::OnMouseMove(nFlags, point);//调用父类的方法
}
void CBtnSkinA::OnTimer(UINT_PTR nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 CPoint point;
 CRect rect;
 GetWindowRect(&rect); 
 GetCursorPos(&point);

 if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled)
 {
  KillTimer (1);
  m_bMouseOver=false;
  m_state = NORMAL;
  DrawButton();
 }

 CButton::OnTimer(nIDEvent);
}

void CBtnSkinA::PreSubclassWindow()//此方法用于窗口创建前进行重绘
{
 // TODO: 在此添加专用代码和/或调用基类
 SetOwnerDraw(true); //设置是否自己绘制窗口

 CButton::PreSubclassWindow();
}


void CBtnSkinA::SetOwnerDraw(bool IsDraw)
{
 if(IsDraw)
 {
  ModifyStyle(NULL, BS_OWNERDRAW); //设置窗口风格为自绘
  Invalidate();
 }
 else
 {
  ModifyStyle(BS_OWNERDRAW, NULL);
  Invalidate();
 }
}

void CBtnSkinA::SetImage(CString strName)
{
 imgButton.Load(strName);
}

void CBtnSkinA::SetImage(UINT nID)
{
 imgButton.LoadFromResource(AfxGetApp()->m_hInstance, nID );
}


BOOL CBtnSkinA::OnEraseBkgnd(CDC* pDC)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
     if(!m_bDCStored)
     {
       CRect  rect;
   GetClientRect(&rect);

          m_memDC.CreateCompatibleDC (pDC);
   CBitmap btScreen;
   btScreen.CreateCompatibleBitmap (pDC,rect.Width(),rect.Height());
   m_memDC.SelectObject (&btScreen);

          m_memDC.BitBlt (0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);

          m_bDCStored=true;

          CRgn rgn;
   rgn.CreateRectRgn (0, 0, rect.Width(), rect.Height());
   SetWindowRgn (rgn, TRUE);

         btScreen.DeleteObject();
      }
      return TRUE;// CButton::OnEraseBkgnd(pDC);//
}

BOOL CBtnSkinA::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 ::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_HAND));
 return TRUE;
 return CButton::OnSetCursor(pWnd, nHitTest, message);
}

void CBtnSkinA::SetColor(COLORREF fgcolor,COLORREF bgcolor)
{
 m_fg = fgcolor;
 m_bg = bgcolor;
 DrawButton();
}

void CBtnSkinA::SetTextPos(CPoint point)
{
 m_textPos = point;
 DrawButton();
}


CRect CBtnSkinA::GetRectInParent()
{
 CRect rcWindowParent;
 GetParent()->GetWindowRect(rcWindowParent);//client
 CRect rcWindow;
 GetWindowRect(&rcWindow);
 CRect rect;
 rect.left = rcWindow.left-rcWindowParent.left;
 rect.top = rcWindow.top-rcWindowParent.top;
 rect.right = rcWindow.right-rcWindowParent.left;
 rect.bottom = rcWindow.bottom-rcWindowParent.top;

 return rect;
}
void CBtnSkinA::OnEnable(BOOL bEnable)
{
 CButton::OnEnable(bEnable);

 

// TODO: 在此处添加消息处理程序代码
 if(bEnable)
  m_bEnabled = true;
 else
  m_bEnabled = false;
}

 

阅读更多
文章标签: button null structure bt
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭