现在的位置: 首页 > 综合 > 正文

MFC内置的位图按钮CBitmapButton

2013年11月19日 ⁄ 综合 ⁄ 共 10587字 ⁄ 字号 评论关闭

使用VC++6中的CBitmapButton类,可以做出效果非常好的图形按钮来。

使用方法也非常简单:

1.在对话框上拖放一个普通的按钮控件;

2.声明一个CBitmapButton类的实例;不要使用ClassWizard映射;   //也就是在类向导不能添加变量

3.调用CBitmapButton类实例的LoadBitmaps方法,载入四幅位图。这四幅位图分别对应按钮

的四种状态:正常(U)状态,按下(D)状态,获得输入(F)状态,禁止(X)状态。    
其中参数:    
     
nIDBitmapResource是位图按钮正常状态(U)下的位图的资源ID。         
     
 nIDBitmapResourceSel是位图按钮按下状态(D)下的位图的资源ID。      
     
nIDBitmapResourceFocus是位图按钮获得输入状态(F)下的位图的资源ID。       
      
nIDBitmapResourceDisabled是位图按钮禁止状态(X)下的位图的资源ID。      
     
4.使用CBitmapButton::SubclassDlgItem关联到想要的按钮。其中第一个参数是要关联的按

钮的ID,第二个参数是要关联的按钮所在的窗口的指针,一般来说,传给它this就行了;

5.使用CBitmapButton::SizeToContent函数使按钮适合图片大小;

6.在对话框编辑器(或称窗体编辑器吧 :-) )中,把关联的按钮控件的Owner draw属性选

上。

好了,现在运行你的程序,是不是发现按钮变成图形按钮了,而且效果还不错呢。

不过唯一的遗憾是,现在软件界面流行那种Hover按钮,就是鼠标移到按钮上时,按钮图片

会显示发亮、上移的效果,鼠标移出按钮则按钮恢复原状,而CBitmapButton类只有如上面所说的四种效果图片,

不包含鼠标移到按钮上时的显示图片;我想到了一种办法:利用 lpszBitmapResourceFocus(位图

按钮获得焦点时的位图),当鼠标移动到按钮上的时候,用代码使按钮获得焦点,当鼠标移

出按钮时,用代码使按钮失去焦点,这样就间接的实现了HoverButton,效果还不错;

//实现Hover效果的处理代码:///////////////////////////////////////////////
//在初始化对话框的时候要用SetTimer函数设置一个定时器,200ms足矣;/////////
void CCBitmapButtonDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 if (1==nIDEvent)
 {
  POINT p;
  GetCursorPos(&p);
  CString s;
  CWnd *hwnd;
  s.Format("%d",hwnd=WindowFromPoint(p));
  this->GetDC()->DrawText(s,CRect(10,10,100,100),0);
  CWnd *hwnd2=GetDlgItem(IDC_BUTTON1);
  if (hwnd2 == hwnd)//如果鼠标在按钮上
  {
   if (GetFocus()!=hwnd2)//如果按钮无焦点,那么设置焦点
    hwnd2->SetFocus() ;
  }
  else//如果鼠标不在按钮上;
  {
   if (GetFocus() == hwnd2 )//如果按钮有焦点,那么去焦点;
    GetDlgItem(IDC_EDIT1)->SetFocus();
  }
  
 }
 CDialog::OnTimer(nIDEvent);
}

------------------------------------------------------------------------------------------------

 

 

看了几种带皮肤按钮的实现方案,比如自绘按钮http://blog.csdn.net/JamesXing/archive/2008/01/10/2033891.aspx,使用wince GWES的APIhttp://blog.csdn.net/JamesXing/archive/2008/01/10/2033896.aspx,一个自绘不规则按钮的实例http://topic.csdn.net/u/20101118/13/53b2087a-82c2-4cf0-8c45-3a38f87f820c.html,以及用MFC里的CBitmapButton加上自编写入文字功能http://topic.csdn.net/u/20070611/09/d59ec937-70b1-49f2-b8df-ff44a87b1a04.html。第一种思路清晰,可以增强很多画笔区域等概念,但频繁使用画笔,对于GDI概念不熟的我可能容易造成资源泄漏;第二种占用嵌入式系统资源少,但需要重新开发;第三种应用场合灵活,可用于各种形状的按钮,缺点同一;第四种相对简单,但按钮形式单一只能为一张图片的形式没有透明效果。时间所限,我这个菜鸟准备从第四种方案着手。先尝试CBitmapButton的使用。

按钮一般有四种状态:up/normal, down/select, focus(意为首选,可能为画面中只有一个按钮,或上次选择的就是此按钮。对于windows来说,就是button上有一个虚线框的情况), disable。第一种是必须有的,后三种可选。因此,至少需要准备button的一张图片。CBitmapButton的使用中,装载按钮图片有两种方法:AutoLoad()和LoadBitmaps()。

AutoLoad()法,该法将四种状态下的图片自动装载到BitmapButton中。

1)在Dialog中拖入button控件,设置ownerdraw为true,caption为MYIMAGE(例),ID为IDC_MYIMAGE。

2)将四张图片添加到bitmap资源,命名为"MYIMAGEU", "MYIMAGED", "MYIMAGEF", "MYIMAGEX",对应button四种状态,名称中需要加入分号

3)在头文件中手动添加对象CBitmapButton m_cBtn;

4)在对话框的OnInitDialog()中添加m_cBtn.AutoLoad(IDC_MYIMAGE, this);完成

LoadBitmaps()法。该法手动指定button每种状态的图片,优点是可以不提供不需要的状态,如focus,且多个button可以使用同样的图片,在资源中只需装载一次,节省空间。

1)在Dialog中拖入button控件,设置ownerdraw为true,ID任意(例:IDC_BUTTNO4)。

2)将所需图片添加到bitmap资源中,ID任意(例:IDB_BTNU,IDB_BTND)。

3)在头文件中手动添加对象CBitmapButton m_cBtn;

4)在OnInitDialog()中添加 m_cBtn.SubclassDlgItem(IDC_BUTTON4, this); //关联按钮和对话框

m_cBtn.LoadBitmaps(IDB_BTNU, IDB_BTND); m_cBtn.SizeToContent();//调整大小. 完成

下一步就是继承CBitmapButton类,重载DrawItem实现文字写入。

-------------------------------------------------------------------------------------------------

 

CBitmapButton

 

 

类CBitmapButton用于创建用位图而不是文本做标签的按钮控件。CBitmapButton对象最多可包括4个位图,分别代表按钮所处的不同状态:未按下(或正常)、按下(或选中)、获得焦点和被禁止存取。只有第一个位图是必须的,其它三个可以不提供。
位图按钮图像包括图像本身以及图像的边框。边框在表示按钮的不同状态时很有用。例如,按钮获得焦点时的位图与未按下(或正常)状态的位图相同,但是在边框中要么嵌入了由间断线组成的矩形,要么嵌入了由粗实线组成的矩形。禁止存取状态的按钮的位图通常和正常状态的一样,但是颜色的对比度较小,就象变灰的菜单选项一样。
这些位图的尺寸可以不同,但都当成和正常状态下位图一样的大小处理。
不同的应用对位图有不同的组合应用。如下所示:
未按下
按下 获得焦点 禁止存取 应用
类Bitmap      
没有设置WS_TABSTOP的按钮    
带有所有状态的对话框按钮
设置WS_TABSTOP风格的对话框按钮  
在创建一个位图按钮控件时,设置BS_OWNERDRAW则指明按钮是自定义的(用户自己绘制的)。这样,Windows就会为该按钮发送WM_MEASUREITEM和WM_DRAWITEM消息,由框架处理这些消息并维护按钮的外观。
在窗口的客户区创建一个位图按钮的步骤如下:
1.
为按钮创建1到4个位图。
2. 构造CBitmapButton对象。
3. 调用Create函数创建Windows按钮控件,并把它加到CBitmapButton对象上。
4. 调用成员函数LoadBitmaps加载位图资源。
在对话框控件中包含位图按钮的步骤如下:
1.
为按钮创建1到4个位图。
2. 创建一个对话框模板,其中有一个自定义的按钮放在需要位图按钮的位置。模板中按钮的大小无关紧要。
3. 把按钮的标题设置为“MYIMAGE”一类的字符串,并为按钮定义一个类似于IDC_MYIMAGE的代号。
4. 在应用的资源脚本中,分别为每个给该按钮创建的图像一个ID,ID的值为在步骤3中的标题后加上如下的一个字母——U、D、F或X,分别代表正常、按下、获得焦点和禁止存取状态下的按钮。例如,标题设为“MYIMAGE”时,ID就应该是字符串("MYIMAGEU"、"MYIMAGED"、"MYIMAGEF"和"MYIMAGEX")。位图的ID必须用引号括起来,否则资源编辑器就会为资源赋上一个整数值,MFC在加载图像时就会失败。
5. 在应用的对话框类(从类CDialog继承而来)中加上一个CBitmapButton成员对象。
6. 在CDialog对象的OnInitDialog例程中调用CBitmapButton对象的AutoLoad函数,参数是按钮的ID和CDialog对象的this指针。
如果想处理Windows的通知消息,如位图按钮控件发给它的父对象(通常是从CDialog继承来的)的BN_CLICKED消息,就要在从CDialog继承来的对象中加入消息映射入口以及处理每个消息的成员函数。CBitmapButton对象发出的通知和CButton对象发出的通知一样。
类CToolBar对位图对象的实现有些不同。

 

 

 

 

使用VC++6中的CBitmapButton类,可以做出效果非常好的图形按钮来。

使用方法也非常简单:

1.在对话框上拖放一个普通的按钮控件;

2.声明一个CBitmapButton类的实例;不要使用ClassWizard映射;   //也就是在类向导不能添加变量

3.调用CBitmapButton类实例的LoadBitmaps方法,载入四幅位图。这四幅位图分别对应按钮

的四种状态:正常(U)状态,按下(D)状态,获得输入(F)状态,禁止(X)状态。    
其中参数:    
     
nIDBitmapResource是位图按钮正常状态(U)下的位图的资源ID。         
     
 nIDBitmapResourceSel是位图按钮按下状态(D)下的位图的资源ID。      
     
nIDBitmapResourceFocus是位图按钮获得输入状态(F)下的位图的资源ID。       
      
nIDBitmapResourceDisabled是位图按钮禁止状态(X)下的位图的资源ID。      
     
4.使用CBitmapButton::SubclassDlgItem关联到想要的按钮。其中第一个参数是要关联的按

钮的ID,第二个参数是要关联的按钮所在的窗口的指针,一般来说,传给它this就行了;

5.使用CBitmapButton::SizeToContent函数使按钮适合图片大小;

6.在对话框编辑器(或称窗体编辑器吧 :-) )中,把关联的按钮控件的Owner draw属性选

上。

好了,现在运行你的程序,是不是发现按钮变成图形按钮了,而且效果还不错呢。

不过唯一的遗憾是,现在软件界面流行那种Hover按钮,就是鼠标移到按钮上时,按钮图片

会显示发亮、上移的效果,鼠标移出按钮则按钮恢复原状,而CBitmapButton类只有如上面所说的四种效果图片,

不包含鼠标移到按钮上时的显示图片;我想到了一种办法:利用 lpszBitmapResourceFocus(位图

按钮获得焦点时的位图),当鼠标移动到按钮上的时候,用代码使按钮获得焦点,当鼠标移

出按钮时,用代码使按钮失去焦点,这样就间接的实现了HoverButton,效果还不错;

//实现Hover效果的处理代码:///////////////////////////////////////////////
//在初始化对话框的时候要用SetTimer函数设置一个定时器,200ms足矣;/////////
void CCBitmapButtonDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 if (1==nIDEvent)
 {
  POINT p;
  GetCursorPos(&p);
  CString s;
  CWnd *hwnd;
  s.Format("%d",hwnd=WindowFromPoint(p));
  this->GetDC()->DrawText(s,CRect(10,10,100,100),0);
  CWnd *hwnd2=GetDlgItem(IDC_BUTTON1);
  if (hwnd2 == hwnd)//如果鼠标在按钮上
  {
   if (GetFocus()!=hwnd2)//如果按钮无焦点,那么设置焦点
    hwnd2->SetFocus() ;
  }
  else//如果鼠标不在按钮上;
  {
   if (GetFocus() == hwnd2 )//如果按钮有焦点,那么去焦点;
    GetDlgItem(IDC_EDIT1)->SetFocus();
  }
  
 }
 CDialog::OnTimer(nIDEvent);
}

------------------------------------------------------------------------------------------------

 

 

看了几种带皮肤按钮的实现方案,比如自绘按钮http://blog.csdn.net/JamesXing/archive/2008/01/10/2033891.aspx,使用wince GWES的APIhttp://blog.csdn.net/JamesXing/archive/2008/01/10/2033896.aspx,一个自绘不规则按钮的实例http://topic.csdn.net/u/20101118/13/53b2087a-82c2-4cf0-8c45-3a38f87f820c.html,以及用MFC里的CBitmapButton加上自编写入文字功能http://topic.csdn.net/u/20070611/09/d59ec937-70b1-49f2-b8df-ff44a87b1a04.html。第一种思路清晰,可以增强很多画笔区域等概念,但频繁使用画笔,对于GDI概念不熟的我可能容易造成资源泄漏;第二种占用嵌入式系统资源少,但需要重新开发;第三种应用场合灵活,可用于各种形状的按钮,缺点同一;第四种相对简单,但按钮形式单一只能为一张图片的形式没有透明效果。时间所限,我这个菜鸟准备从第四种方案着手。先尝试CBitmapButton的使用。

按钮一般有四种状态:up/normal, down/select, focus(意为首选,可能为画面中只有一个按钮,或上次选择的就是此按钮。对于windows来说,就是button上有一个虚线框的情况), disable。第一种是必须有的,后三种可选。因此,至少需要准备button的一张图片。CBitmapButton的使用中,装载按钮图片有两种方法:AutoLoad()和LoadBitmaps()。

AutoLoad()法,该法将四种状态下的图片自动装载到BitmapButton中。

1)在Dialog中拖入button控件,设置ownerdraw为true,caption为MYIMAGE(例),ID为IDC_MYIMAGE。

2)将四张图片添加到bitmap资源,命名为"MYIMAGEU", "MYIMAGED", "MYIMAGEF", "MYIMAGEX",对应button四种状态,名称中需要加入分号

3)在头文件中手动添加对象CBitmapButton m_cBtn;

4)在对话框的OnInitDialog()中添加m_cBtn.AutoLoad(IDC_MYIMAGE, this);完成

LoadBitmaps()法。该法手动指定button每种状态的图片,优点是可以不提供不需要的状态,如focus,且多个button可以使用同样的图片,在资源中只需装载一次,节省空间。

1)在Dialog中拖入button控件,设置ownerdraw为true,ID任意(例:IDC_BUTTNO4)。

2)将所需图片添加到bitmap资源中,ID任意(例:IDB_BTNU,IDB_BTND)。

3)在头文件中手动添加对象CBitmapButton m_cBtn;

4)在OnInitDialog()中添加 m_cBtn.SubclassDlgItem(IDC_BUTTON4, this); //关联按钮和对话框

m_cBtn.LoadBitmaps(IDB_BTNU, IDB_BTND); m_cBtn.SizeToContent();//调整大小. 完成

下一步就是继承CBitmapButton类,重载DrawItem实现文字写入。

-------------------------------------------------------------------------------------------------

 

CBitmapButton

 

 

类CBitmapButton用于创建用位图而不是文本做标签的按钮控件。CBitmapButton对象最多可包括4个位图,分别代表按钮所处的不同状态:未按下(或正常)、按下(或选中)、获得焦点和被禁止存取。只有第一个位图是必须的,其它三个可以不提供。
位图按钮图像包括图像本身以及图像的边框。边框在表示按钮的不同状态时很有用。例如,按钮获得焦点时的位图与未按下(或正常)状态的位图相同,但是在边框中要么嵌入了由间断线组成的矩形,要么嵌入了由粗实线组成的矩形。禁止存取状态的按钮的位图通常和正常状态的一样,但是颜色的对比度较小,就象变灰的菜单选项一样。
这些位图的尺寸可以不同,但都当成和正常状态下位图一样的大小处理。
不同的应用对位图有不同的组合应用。如下所示:
未按下
按下 获得焦点 禁止存取 应用
类Bitmap      
没有设置WS_TABSTOP的按钮    
带有所有状态的对话框按钮
设置WS_TABSTOP风格的对话框按钮  
在创建一个位图按钮控件时,设置BS_OWNERDRAW则指明按钮是自定义的(用户自己绘制的)。这样,Windows就会为该按钮发送WM_MEASUREITEM和WM_DRAWITEM消息,由框架处理这些消息并维护按钮的外观。
在窗口的客户区创建一个位图按钮的步骤如下:
1.
为按钮创建1到4个位图。
2. 构造CBitmapButton对象。
3. 调用Create函数创建Windows按钮控件,并把它加到CBitmapButton对象上。
4. 调用成员函数LoadBitmaps加载位图资源。
在对话框控件中包含位图按钮的步骤如下:
1.
为按钮创建1到4个位图。
2. 创建一个对话框模板,其中有一个自定义的按钮放在需要位图按钮的位置。模板中按钮的大小无关紧要。
3. 把按钮的标题设置为“MYIMAGE”一类的字符串,并为按钮定义一个类似于IDC_MYIMAGE的代号。
4. 在应用的资源脚本中,分别为每个给该按钮创建的图像一个ID,ID的值为在步骤3中的标题后加上如下的一个字母——U、D、F或X,分别代表正常、按下、获得焦点和禁止存取状态下的按钮。例如,标题设为“MYIMAGE”时,ID就应该是字符串("MYIMAGEU"、"MYIMAGED"、"MYIMAGEF"和"MYIMAGEX")。位图的ID必须用引号括起来,否则资源编辑器就会为资源赋上一个整数值,MFC在加载图像时就会失败。
5. 在应用的对话框类(从类CDialog继承而来)中加上一个CBitmapButton成员对象。
6. 在CDialog对象的OnInitDialog例程中调用CBitmapButton对象的AutoLoad函数,参数是按钮的ID和CDialog对象的this指针。
如果想处理Windows的通知消息,如位图按钮控件发给它的父对象(通常是从CDialog继承来的)的BN_CLICKED消息,就要在从CDialog继承来的对象中加入消息映射入口以及处理每个消息的成员函数。CBitmapButton对象发出的通知和CButton对象发出的通知一样。
类CToolBar对位图对象的实现有些不同。

 

 

 

 

使用VC++6中的CBitmapButton类,可以做出效果非常好的图形按钮来。

使用方法也非常简单:

1.在对话框上拖放一个普通的按钮控件;

2.声明一个CBitmapButton类的实例;不要使用ClassWizard映射;   //也就是在类向导不能添加变量

3.调用CBitmapButton类实例的LoadBitmaps方法,载入四幅位图。这四幅位图分别对应按钮

的四种状态:正常(U)状态,按下(D)状态,获得输入(F)状态,禁止(X)状态。    
其中参数:    
     
nIDBitmapResource是位图按钮正常状态(U)下的位图的资源ID。         
     
 nIDBitmapResourceSel是位图按钮按下状态(D)下的位图的资源ID。      
     
nIDBitmapResourceFocus是位图按钮获得输入状态(F)下的位图的资源ID。       
      
nIDBitmapResourceDisabled是位图按钮禁止状态(X)下的位图的资源ID。      
     
4.使用CBitmapButton::SubclassDlgItem关联到想要的按钮。其中第一个参数是要关联的按

钮的ID,第二个参数是要关联的按钮所在的窗口的指针,一般来说,传给它this就行了;

5.使用CBitmapButton::SizeToContent函数使按钮适合图片大小;

6.在对话框编辑器(或称窗体编辑器吧 :-) )中,把关联的按钮控件的Owner draw属性选

上。

好了,现在运行你的程序,是不是发现按钮变成图形按钮了,而且效果还不错呢。

不过唯一的遗憾是,现在软件界面流行那种Hover按钮,就是鼠标移到按钮上时,按钮图片

会显示发亮、上移的效果,鼠标移出按钮则按钮恢复原状,而CBitmapButton类只有如上面所说的四种效果图片,

不包含鼠标移到按钮上时的显示图片;我想到了一种办法:利用 lpszBitmapResourceFocus(位图

按钮获得焦点时的位图),当鼠标移动到按钮上的时候,用代码使按钮获得焦点,当鼠标移

出按钮时,用代码使按钮失去焦点,这样就间接的实现了HoverButton,效果还不错;

//实现Hover效果的处理代码:///////////////////////////////////////////////
//在初始化对话框的时候要用SetTimer函数设置一个定时器,200ms足矣;/////////
void CCBitmapButtonDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 if (1==nIDEvent)
 {
  POINT p;
  GetCursorPos(&p);
  CString s;
  CWnd *hwnd;
  s.Format("%d",hwnd=WindowFromPoint(p));
  this->GetDC()->DrawText(s,CRect(10,10,100,100),0);
  CWnd *hwnd2=GetDlgItem(IDC_BUTTON1);
  if (hwnd2 == hwnd)//如果鼠标在按钮上
  {
   if (GetFocus()!=hwnd2)//如果按钮无焦点,那么设置焦点
    hwnd2->SetFocus() ;
  }
  else//如果鼠标不在按钮上;
  {
   if (GetFocus() == hwnd2 )//如果按钮有焦点,那么去焦点;
    GetDlgItem(IDC_EDIT1)->SetFocus();
  }
  
 }
 CDialog::OnTimer(nIDEvent);
}

抱歉!评论已关闭.