分享

VC 位图按钮CBitmapButton的使用

 学海无涯GL 2013-09-30

系统环境:Windows 7
软件环境:Visual C++ 2008 SP1
本次目的:使用位图按钮,并且设置按钮的鼠标悬停效果

      在用MFC开发时,界面是比较不好开发的一块。VC中自带了CBitmapButton类,但是用途不多,网上很多Button类的派生类蛮实用的,但是若是简单的位图按钮用自带的CBitmapButton就可以实现了,以下是效果图:

步骤一:新建基于对话框工程,放置一个按钮,可以适当调整大小,设置其Owner Draw属性为TRUE,右键为按钮添加变量,改变其变量类型为CBitmapButton,按确定完成;

步骤二:导入按钮位图,这里四幅图大小要一致,以下是四种状体的按钮,若读者要实验这次的设计的话,可以右键另存为,然后用“画图”把png格式的另存为bmp格式的。在资源视图,右键“添加资源”,“导入”以下图片:

步骤三:初始化工作,在对话框的OnInitDialog()函数里面添加以下代码:

  1. m_btButton.LoadBitmaps(IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4);   //载入   
  2. m_btButton.SizeToContent();  //使按钮适应图片大小  

步骤四:为控制位图按钮的可用、不可用添加代码,这是为了验证第四种状态的按钮:

  1. void CTestDlg::OnBnClickedButton2()  
  2. {     
  3.     m_btButton.EnableWindow(0);  
  4. }  
  5. void CTestDlg::OnBnClickedButton3()  
  6. {     
  7.     m_btButton.EnableWindow();  
  8. }  

步骤五:到这里已经完成了位图按钮的实现,编译运行可以看到结果。但是鼠标滑过的时候,按钮并不会感应到焦点的存在。这里用定时器捕获焦点在按钮上,并且改变此时的按钮状体为第三种图片。首先为窗体添加OnTimer()事件,在OnTimer()函数里面填写如下代码:

  1. void CTestDlg::OnTimer(UINT_PTR nIDEvent)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值   
  4.     if (1==nIDEvent)  
  5.      {  
  6.       POINT p;  
  7.       GetCursorPos(&p);     
  8.       CWnd *hwnd;  
  9.       hwnd=WindowFromPoint(p);        //检索窗口中包含指定的点;点必须指定屏幕坐标在屏幕上的一个点。      
  10.       CWnd *hwnd2=GetDlgItem(IDC_BUTTON1);  
  11.       if (hwnd2 == hwnd)         //如果鼠标在按钮上   
  12.       {  
  13.        if (GetFocus()!=hwnd2)        //如果按钮无焦点,那么设置焦点   
  14.         hwnd2->SetFocus() ;  
  15.       }  
  16.       else          //如果鼠标不在按钮上;   
  17.       {  
  18.        if (GetFocus() == hwnd2 )                  //如果按钮有焦点,那么去焦点;   
  19.         GetDlgItem(IDC_BUTTON2)->SetFocus();      //这里的IDC_BUTTON2为你想跳转到的控件ID号   
  20.       }     
  21.      }  
  22.     CDialog::OnTimer(nIDEvent);  
  23. }  

最后在对话框的OnInitDialog()函数里面添加开启定时器,时间间隔200ms足够了。

  1. SetTimer(1,200,NULL);  

完成后,运行就可实现与文章开头所示的图片一样的效果。




利用CBitmapButton类实现位图按钮的两种方法:
方法一:
 1、在资源编辑的时候选中按钮的 Owner draw 属性,不需要选择 Bitmap 属性.
       按钮右键-->Styles-->Owner draw

 2、在程序中定义一个CBitmapButton成员变量。
        注意:不能使用ClassWizard为按钮映射一个CButton变量,然后改为CBitmapButton,
        这么做并不能将按钮直接映射为CBitmapButton类的对象,反而会出现初始化错误

3、使用CBitmapButton::LoadBitmaps装载各种状态的图片,
     使用CBitmapButton::SubclassDlgItem关联到想要的按钮,
     使用CBitmapButton::SizeToContent函数使按钮适合图片大小。
     注意Loadbitmaps一定要在关联到按钮之前进行!

      附:添加资源Bitmap的方法:Insert菜单-->Resource -->Resource type:Bitmap-->Import, 
                之后选择所需的图片就可以了

 方法一的例子:
    首先,选中按钮的owner Draw属性,在资源中加载两副*.bmp格式的位图,
  然后在对话框类中加入:
 1CBitmapButton m_btnX1;
 2//定义变量,必须放在函数外面才能正常实现
 3
 4BOOL CXXXXXXX::OnInitDialog()
 5{
 6CDialog::OnInitDialog();
 7
 8m_btnX1.LoadBitmaps(IDB_XXXX_UP,IDB_XXXX_DOWN);
 9//这里是两副位图,鼠标按下和弹起,
10//  也可以只加一个ID资源;
11m_btnX1.SubclassDlgItem(IDC_DASEN_X1,this);
12m_btnX1.SizeToContent();
13}

14
15文章引用自:http://blog.sina.com.cn/s/blog_44e571d70100080o.html 
16

方法二:使用CBitmapButton::AutoLoad函数关联到想要的按钮
需要注意:
A、使用CBitmapButton::AutoLoad函数之前不能使用CBitmapButton::LoadBitmaps装载
  各种状态的图片,否则会出错。
B、AutoLoad函数完成关联和改变按钮大小的功能。类似于上面CBitmapButton::SubclassDlgItem
   和CBitmapButton::SizeToContent函数的功能。
C、CBitmapButton::AutoLoad使用的位图是默认资源ID的,即它会自动装载相关资源位图。
  位图的资源ID格式为:
  "按钮Caption+U"、"按钮Caption+D"、"按钮Caption+F"、"按钮Caption+X",
  分别代表Up、Down、Focus、Disable状态。
  如资源编辑时,希望关联的按钮的Caption为Test,
  那么其默认装载的位图资源的ID为:"TestU"/"TestD"/"TestF"/"TestX",
  注意分号""也是其ID的一部分。
方法二例子:
首先,选中Caption为:"myBitmapButton"按钮的owner Draw属性
其次,添加两个位图资源,并修改其ID分别为:"myBitmapButtonU"和"myBitmapButtonD",这里只添加两个位图
然后在对话框类中加入:
1 CBitmapButton m_btnX1;//必须放在函数外面才能正常实现
2 BOOL CXXXXXXX::OnInitDialog()
3 {
4 CDialog::OnInitDialog();
5 
6 m_btnX1.AutoLoad(IDC_BUTTON1,this);//ID为IDC_BUTTON1的按钮的Caption为:myBitmapButton
7 }

至此两种方法就都结束了。



============================================================================================


在编程中,经常要用到按钮控件,大部分情况下,文字按钮就OK了,但有时为了更好的效果,需要用到图形按钮。

在MFC中,应用CBitmapButton就可以实现图形按钮。CBitmapButton类继承自CButton类。你可以为图形按钮指定四张图片,分别对应按钮的四种不同状态:

正常显示(Up),鼠标按下(Down),获得焦点(Focused),不可用(Disabled)。

正常显示(Up)状态的图片是必须的,其他三张图片是可选的。

还有,按钮的Style必须指定为BS_OWNERDRAW.。

以下是利用CBitmapButton实现图形按钮的实例:

第一种方法:

(一)在VC6下新建一对话框工程,在对话框界面上拉出一按钮控件

指定按钮的Style为Owner Draw,即程式中得BS_OWNERDRAW样式。

利用ClassWizard为按钮关联CButton类变量,然后将CButton类型手动改为CBitmapButton。

(二)导入指定按钮四种状态的图片

以下只导入了3张图片,分别对应Up,Down,Focused

(三)在对话框的OnInitDialog函数中添加如下代码

LoadBitmaps加载状态图片,注意顺序为Up,Down,Focused,Disabled。

1 // TODO: Add extra initialization here  
2 m_btnBitmap.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUSED); //Disabled状态的图片没有制作
3 m_btnBitmap.SizeToContent(); //调整按钮大小为图片大小

第二种方法:利用SubclassDlgItem

在界面中拉出一按钮控件后,不用关联变量,指定按钮的Style为Owner Draw,然后同上一样导入四张状态图片。创建CBitmapButton对象(注意不要创建函数的局部变量,否则在函数执行完毕时就销毁了),最好创建为对话框的成员变量,在对话框的OnInitDialog初始化函数中用LoadBitmaps加载图片,再利用SubclassDlgItem方法将该CBitmapButton与刚开始在界面上拉出的控件关联。按钮控件自动调整为和图片一样大小。

代码如下:

1 m_btnBitmap002.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUSED);  
2 m_btnBitmap002.SubclassDlgItem(IDC_BTN_TESTAUTO, this);
3 //CBitmapButton test; //不可这样定义局部变量再关联
4 //test.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUSED);
5 //test.SubclassDlgItem(IDC_BTN_TESTAUTO, this);

第三种方法:应用CBitmapButton的AutoLoad方法自动为按钮加载图片

BOOL AutoLoad(UINT nID, CWnd* pParent);

我们不用指定图片的ID,那么程序是采取怎样的规则去加载图片的呢?

规则:如果按钮控件的Caption为Test,则四张位图的ID应分别为“TestU”,“TestD”,“TestF”,“TestX”,分别对应Up,Down,Focused,Disabled状态。注意:""也是ID的一部分。

所以步骤为:
(一)在对话框中拉出按钮控件,Caption改为Test,指定按钮的Style为Owner Draw。

(二)定义对话框的成员变量CBitmapButton   m_btnBitmap003;

(三)导入四张状态位图,ID分别改为“TestU”,“TestD”,“TestF”,“TestX”。

(四)在对话框的OnInitDialog中调用AutoLoad方法

1 m_btnBitmap003.AutoLoad(IDC_BTNTEST, this);  

这种方法按钮也会自动调整为和位图一样大小。



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多