位图按钮是由MFC提供的几种附加控件之一。在前一节的过程中,我们可以使用一个位图来代替文本作为下压按钮的标签。而在位图按钮中,我们可以使用多达四个位图来分别代表按钮处于四种不同的状态(凸起、按下、获得焦点或被禁止)下的显示。而且,使用位图按钮还可以去除掉令人讨厌的按钮黑边。而使用位图按钮并不复杂,但是相比起标准的按钮控件(它由Windows自身所提供)而言有一些特殊。下面的过程描述了位图按钮的使用,它们在MFC中使用类CBitmapButton封装。
1. 使用AppWizard创建新的基于对话框的MFC工程BitmapButton。
2. 使用资源编辑器绘制一个标准按钮,将其ID设为IDC_CLICKHERE,标题文本设为CLICKHERE,然后在Styles选项卡中将Owner draw属性设置为真。
3. 向工程中添加四个位图资源。
图6. 25 位图按钮IDC_CLICKHERE所使用的四个位图资源
所添加的四个位图资源的ID的设置取决于在第一步中的标题文本的设置:按钮未按下去时使用的位图添加了后缀"U";按钮按下去时使用的位图添加了后缀"D";按钮拥有焦点时使用的位图添加了后缀"F";按钮被禁止时使用的位图添加了后缀"X"。需要注意的是,由于这些位图资源的ID为字符串,因此在使用属性对话框设置其ID时一定要加了双引号,否则资源编辑器会将该ID值看作代表一个整型量的符号。
4. 在对话框类CBitmapButtonDlg(这里我们沿用上一节中的示例程序)中添加类型为CBitmapButton的新的成员变量m_bnClickhere。
5. 在OnInitDialog成员函数中的return语句前添加下面的代码:
m_bnClickhere.AutoLoad(IDC_CLICKHERE, this);
CRect rect1,rect2;
CButton *pClickhere=(CButton*)GetDlgItem(IDC_CLICKHERE);
GetClientRect(&rect1);
pClickhere->GetWindowRect(&rect2);
ScreenToClient(&rect2);
pClickhere->MoveWindow(rect2.left,(rect1.Height()-rect2.Height())/2,
rect2.Width(),rect2.Height());
其中第一个参数IDC_CLICKHERE是位图按钮的资源ID,第二个参数为指向该位图按钮的父窗口的CWnd对象的指针,这里即类CBitmapButtonDlg的this指针。类CBitmapButton的成员函数AutoLoad完成以下几步工作:
(1) 将按钮与CBitmapButton对象相关联;
(2) 自动加载按钮所使用的位图,条件是这些位图资源满足步骤2中的命名约定;
(3) 自动改变控件的大小以适合所加载的位图资源。
接下来的几行代码将位图按钮在对话框中进行垂直居中。首先类CWnd的成员函数GetClientRect返回了对话框的客户区矩形,接着,类CWnd的成员函数GetWindowRect返回了控件IDC_CLICKHERE的窗口矩形,然后使用类CWnd的成员函数ScreenToClient将rect2由屏幕坐标转换为对话框的客户坐标,这是因为类CWnd的成员函数MoveWindow在移动子窗口时将使用父窗口的客户区坐标,而不是使用屏幕坐标。
6. 按图6.26添加下面的下压按钮IDC_DISABLE,将其标题设置为“禁止使用(&X)”。
图6. 26 位图按钮示例程序对话框的设计
7. 将所有下压按钮的Tab stop属性(位于General选项卡中)设置为真。并按图6.26调整各控件的大小位置。其中按钮CLICKHERE的大小的无关紧要的,我们只需要保证对话框左边是否有足够的空间来显示按钮所使用的位图即可。
8. 为按钮IDC_DISABLE的BN_CLICKED命令编写下面的命令处理函数:
void CBitmapButtonDlg::OnDisable()
{
CButton *pClickhere=(CButton*)GetDlgItem(IDC_CLICKHERE);
static int bIsEnabled=pClickhere->IsWindowEnabled();
if (bIsEnabled)
{
pClickhere->EnableWindow(FALSE);
SetDlgItemText(IDC_DISABLE,"允许使用(&E)");
}
else
{
pClickhere->EnableWindow(TRUE);
SetDlgItemText(IDC_DISABLE,"禁止使用(&X)");
}
bIsEnabled=!bIsEnabled;
}
上面的代码实现两个功能,即当位图按钮的状态为允许时,单击按钮IDC_DISABLE将其状态设置为不允许;在相反的状态下,单击按钮IDC_DISABLE将其状态设置为允许。由于实现该过程的代码比较简单,因此我们在这里不作详细的讲述。
编译并运行上面的示例程序,其结果如图6.27所示。
反复单击位图按钮和禁止使用按钮,以观察位图按钮在不同状态下的外观的改变。还可以使用TAB键改变按钮的输入焦点,以观察位图按钮获得输入焦点和失去输入焦点时的不同外观。
图6. 27 位图按钮示例程序