VC界面编程 按钮的美化

以前也是对windows有些研究的,只是近来搞C#把底层的东西忘了不少,现在连windows都有哪些消息都不知道了,以前能够娴熟的利用windows消息写出奇妙的东西,现在用mfc都不清楚mfc的消息路由有谁到谁了,这几天又做C++开发,原来的是wxWidgets用着不是很爽,基本都很多和mfc的一样,有点就是开源跨平台,缺点是资料太少,特别是中文的.所以就想把那些代码转成中文的.

现在也想预热下,温习下用mfc来开发东西,就把自己经过的点滴记下,一来自己日后忘了可以直接看,二来也可以为新手朋友们提供点有点用的东西吧.

 

按钮是比较常用的控件了,几乎每个windows桌面的窗口中都有,所以就先看看按钮怎么来美化下,其实美化下也就是添加点颜色、图片和效果。

当然了mfc中CBitmapButton已经可以做到好的效果,但是可能会不知道其中的实现的原理,为了能够为以后做点铺垫,所以自己动手来写个类似于CBitmapButton的类来

我这里命名CDynamicButton从CButton继承而来.记得好像以前美化是从DrawItem中来的,于是就重载了CButton的DrawItem方法,然后就如下来创建一个按钮:

为了测试先建一个基于对话框的工程,我在对话框的OnInitDialog中创建了pButton按钮

ExpandedBlockStart.gif 代码
BOOL CButtonDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    
//  设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    
//   执行此操作
    SetIcon(m_hIcon, TRUE);             //  设置大图标
    SetIcon(m_hIcon, FALSE);         //  设置小图标

    
//  TODO: 在此添加额外的初始化代码
    CDynamicButton  * pButton  =   new  CDynamicButton(IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4);
    pButton
-> Create(TEXT( " My Button " ),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW  |  WS_TABSTOP,CRect(CPoint( 10 , 10 ),CSize( 200 , 200 )), this , 601 );
    
return  TRUE;   //  除非将焦点设置到控件,否则返回 TRUE
}

 

 

因为要给不同的状态给按钮不同图片,所以这个

CDynamicButton的构造函数中获取四个图片的资源ID,从而来设置不同状态下的图片.一定要给按钮设为BS_OWNERDRAW样式才可以的,这样父窗口在重新绘制前就会给按钮发送重绘消息的.

如果在窗口中直接添加按钮控件,直接把按钮ID与按钮变量关联起来,把变量类型声明为 CDynamicButton,然后可以通过CDynamicButton中的几个设置bmp的方法,设置不同状态下的图片

也是为了能够直接在其他窗口中直接添加控件来使用这个类,所以这个类定义如下:

 

#pragma  once


//  CDynamicButton

class  CDynamicButton :  public  CButton
{
    DECLARE_DYNAMIC(CDynamicButton)

public :
    CDynamicButton();
    CDynamicButton(UINT nNormalResourceId,UINT nOverResourceI,UINT nDownResourceId,UINT nDisalbeResourceId);
    
virtual   ~ CDynamicButton();
    
void  SetNormalBmp(UINT nNormalResourceId);
    
void  SetOverBmp(UINT nNormalResourceId);
    
void  SetDownBmp(UINT nNormalResourceId);
    
void  SetDisableBmp(UINT nNormalResourceId);
protected :
    
void  DrawBitmap(CDC  * pDC,CRect  & rect,CBitmap  * pBmp);
private :
    CBitmap 
* m_pNormalBmp;
    CBitmap 
* m_pOverBmp;
    CBitmap 
* m_pDownBmp;
    CBitmap 
* m_pDisableBmp;

protected :
    DECLARE_MESSAGE_MAP()
public :
    afx_msg 
void  OnDrawItem( int  nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
    
virtual   void  DrawItem(LPDRAWITEMSTRUCT  /* lpDrawItemStruct */ );
    afx_msg 
void  OnMButtonDown(UINT nFlags, CPoint point);
    afx_msg 
void  OnBnKillfocus();
};

 

而相应的cpp文件我也一下贴出来再做说明了

 

ExpandedBlockStart.gif CDynamicButton.cpp
//  DynamicButton.cpp : 实现文件
//

#include 
" stdafx.h "
#include 
" Button.h "
#include 
" DynamicButton.h "


//  CDynamicButton

IMPLEMENT_DYNAMIC(CDynamicButton, CButton)

CDynamicButton::CDynamicButton()
{

}

CDynamicButton::CDynamicButton(UINT nNormalResourceId,UINT nOverResourceI,UINT nDownResourceId,UINT nDisalbeResourceId)
{
    m_pNormalBmp 
=   new  CBitmap();
    m_pNormalBmp
-> LoadBitmapW( nNormalResourceId);
    m_pOverBmp 
=   new  CBitmap();
    m_pOverBmp
-> LoadBitmapW( nOverResourceI);
    m_pDownBmp 
=   new  CBitmap();
    m_pDownBmp
-> LoadBitmapW( nDownResourceId);
    m_pDisableBmp 
=   new  CBitmap();
    m_pDisableBmp
-> LoadBitmapW( nDisalbeResourceId);
}

CDynamicButton::
~ CDynamicButton()
{
    m_pNormalBmp
-> DeleteObject();
    delete m_pNormalBmp;
}


BEGIN_MESSAGE_MAP(CDynamicButton, CButton)
    ON_WM_DRAWITEM()
    ON_WM_MBUTTONDOWN()
    ON_CONTROL_REFLECT(BN_KILLFOCUS, 
& CDynamicButton::OnBnKillfocus)
END_MESSAGE_MAP()



//  CDynamicButton 消息处理程序

void  CDynamicButton::SetNormalBmp(UINT nNormalResourceId)
{
    m_pNormalBmp 
=   new  CBitmap();
    m_pNormalBmp
-> LoadBitmapW( nNormalResourceId);
}

void  CDynamicButton::SetOverBmp(UINT nNormalResourceId)
{
    m_pOverBmp 
=   new  CBitmap();
    m_pOverBmp
-> LoadBitmapW( nNormalResourceId);
}

void  CDynamicButton::SetDownBmp(UINT nNormalResourceId)
{
    m_pDownBmp 
=   new  CBitmap();
    m_pDownBmp
-> LoadBitmapW( nNormalResourceId);
}

void  CDynamicButton::SetDisableBmp(UINT nNormalResourceId)
{
    m_pDisableBmp 
=   new  CBitmap();
    m_pDisableBmp
-> LoadBitmapW( nNormalResourceId);
}



void  CDynamicButton::OnDrawItem( int  nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    
//  TODO: 在此添加消息处理程序代码和/或调用默认值
    
// HBITMAP bmp = (HBITMAP)LoadImage(NULL, strFileName.GetBuffer(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); 
    
// ULONG_PTR btnState = lpDrawItemStruct->itemState;
    
// CString s;
    
// s.Format(_T("%d"),ODS_DEFAULT);
    
// MessageBox(s);
    
// if( btnState & ODS_DEFAULT ) // 默认的
    
// {
    
//     CDC *pDC = new CDC();
    
//     pDC->Attach(lpDrawItemStruct->hDC);
    
//     CDC mDC;
    
//     mDC.CreateCompatibleDC(pDC);
    
//     BITMAP bmpInfo;
    
//     m_pNormalBmp->GetBitmap(&bmpInfo);
    
//     mDC.SelectObject(*m_pNormalBmp);
    
//     CRect rect(lpDrawItemStruct->rcItem);

    
//     pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&mDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);

    
//     mDC.Detach();
    
//     mDC.DeleteDC();
    
// }
    
//

    
// CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

void  CDynamicButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

    
//  TODO:  添加您的代码以绘制指定项
    ULONG_PTR btnState  =  lpDrawItemStruct -> itemState;
    
/* CString s;
    s.Format(_T("%d"),btnState);
    MessageBox(s);
*/
    CDC 
* pDC  =   new  CDC();
    CRect rect(lpDrawItemStruct
-> rcItem);
    pDC
-> Attach(lpDrawItemStruct -> hDC);
    
if ( btnState  == 0  ) // 默认的
    {
        
        DrawBitmap(pDC,rect,m_pNormalBmp);
        
    }
    
// else if(btnState &    ODS_FOCUS)
    
// {
    
//     DrawBitmap(pDC,rect,m_pDownBmp);
    
// }
    
// else if(btnState & ODS_DEFAULT)
    
// {
    
//     DrawBitmap(pDC,rect,m_pNormalBmp);
    
// }
    
// else if(btnState & ODS_SELECTED)
    
// {
    
//     DrawBitmap(pDC,rect,m_pOverBmp);
    
// }

    
}

void  CDynamicButton::DrawBitmap(CDC  * pDC,CRect  & rect,CBitmap  * pBmp)
{
    CDC mDC;
    mDC.CreateCompatibleDC(pDC);
    BITMAP bmpInfo;
    pBmp
-> GetBitmap( & bmpInfo);
    mDC.SelectObject(
* pBmp);
    

    pDC
-> StretchBlt( 0 , 0 ,rect.Width(),rect.Height(), & mDC, 0 , 0 ,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);

    mDC.Detach();
    mDC.DeleteDC();
}

void  CDynamicButton::OnMButtonDown(UINT nFlags, CPoint point)
{
    
//  TODO: 在此添加消息处理程序代码和/或调用默认值
    CDC  * pDC  =  GetWindowDC();
    CRect rect;
    GetClientRect(
& rect);
    DrawBitmap(pDC,rect,m_pDownBmp);
    
// MessageBox(_T("aaa"));
    
// CButton::OnMButtonDown(nFlags, point);
}

void  CDynamicButton::OnBnKillfocus()
{
    CDC 
* pDC  =  GetWindowDC();
    CRect rect;
    GetClientRect(
& rect);
    (pDC,rect,m_pNormalBmp);
    
//  TODO: 在此添加控件通知处理程序代码

}

 

其中其实DrawBitmap的作用很大,每次都是它在画图,才是按钮显示不同的图片

我当初才接触的时候,就是对画图的这部门不够明白,现在其实想想,好看的界面都是画图画出来的,CDC这个设备上下文类,用几次就明白其中的东东了

由于好久没有弄这个mfc了,这个CDynamicButton并没有成功的,因为现在根本就不反应,只是能够简单的换下图片而已,背景效果还有待改进,明天还要上班,现在已经不早了,明晚有时间再搞吧

如果是新手看的,就看DrawBitmap就可以了,把这个搞懂,就可以画图,再个就是搞懂消息了,在哪个消息向应里画呢.这两样搞懂了,搞出好的界面就不难了

给我这个难看的东西截个图留念下,哈:

不早了睡觉觉了~~~~~~

转载于:https://www.cnblogs.com/20090802/archive/2009/12/03/1616617.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值