以更有效的方式启用或禁用控件






4.90/5 (14投票s)
2002年4月17日
2分钟阅读

70282

711
使用 STL bitset 类创建优雅的解决方案来解决常见问题。
引言
最近我在做一个项目,其中一个对话框上有许多控件。此对话框可以根据不同的用户交互显示,并且在不同的交互中,此对话框的某些控件变为启用状态,而另一些控件变为禁用状态。
为此,我必须根据一些变量来决定哪些控件将被启用或禁用。例如:
if( m_bButton ) { GetDlgItem( IDC_BUTTON1 )->EnableWindow(TRUE); GetDlgItem( IDC_BUTTON2 )->EnableWindow(TRUE); GetDlgItem( IDC_EDIT2 )->EnableWindow(FALSE); GetDlgItem( IDC_EDIT3 )->EnableWindow(FALSE); GetDlgItem( IDC_COMBO1 )->EnableWindow(FALSE); GetDlgItem( IDC_COMBO2 )->EnableWindow(FALSE); } else if( m_bEdit ) { GetDlgItem( IDC_BUTTON1 )->EnableWindow(FALSE); GetDlgItem( IDC_BUTTON2 )->EnableWindow(FALSE); GetDlgItem( IDC_EDIT2 )->EnableWindow(TRUE); GetDlgItem( IDC_EDIT3 )->EnableWindow(TRUE); GetDlgItem( IDC_COMBO1 )->EnableWindow(FALSE); GetDlgItem( IDC_COMBO2 )->EnableWindow(FALSE); } else if( m_bCombo ) { GetDlgItem( IDC_BUTTON1 )->EnableWindow(FALSE); GetDlgItem( IDC_BUTTON2 )->EnableWindow(FALSE); GetDlgItem( IDC_EDIT2 )->EnableWindow(FALSE); GetDlgItem( IDC_EDIT3 )->EnableWindow(FALSE); GetDlgItem( IDC_COMBO1 )->EnableWindow(TRUE); GetDlgItem( IDC_COMBO2 )->EnableWindow(TRUE); }
上面的解决方案很好,但是使用上述解决方案存在两个明显的问题
- 代码重复:有很多代码重复用于启用或禁用各种控件。
- 代码维护:如果将来添加了一个控件,那么我们必须更新所有启用或禁用控件的函数中的控件状态。很有可能我们会忘记在某些地方更新它。
通过使用 STL 的 bitset
类可以获得更有效的解决方案。使用 bitset 类,我们可以保存由多个位组成的序列,它提供了一种紧凑有效的方式来保存一组项目(我们问题中的控件)的标志。
在演示项目中,有两个命令按钮、两个编辑控件和两个组合框,它们将在用户单击相应的单选按钮时启用或禁用。最初,所有控件都被禁用。当用户单击标记为“启用按钮”的单选按钮时,将启用按钮,而其他控件将保持禁用状态。其他单选按钮的工作方式类似。现在,为了解决这个问题,我们将在对话框类中声明一个 bitset 类的对象,如下所示
bitset<16> m_bitControls;
请记住包含以下两行以使用 bitset 类#include <bitset> using namespace std;现在为对话框上的六个控件定义宏,如下所示
#define BUTTON_ONE 0 #define BUTTON_TWO 1 #define EDIT_CTRL_ONE 2 #define EDIT_CTRL_TWO 3 #define COMBO_ONE 4 #define COMBO_TWO 5上面提到的宏将用作 bitset 对象中的索引值。
现在,在初始化列表中初始化 bitset 对象,如下所示
m_bitControls(0)
上面一行会将所有 16 位设置为 O。添加一个成员函数,该函数将根据 bitset 对象的值启用或禁用控件。此函数的代码如下
void CDialogAppDlg::enableORdisableCtrls()
{
GetDlgItem( IDC_BUTTON1 )->EnableWindow(m_bitControls[BUTTON_ONE]);
GetDlgItem( IDC_BUTTON2 )->EnableWindow(m_bitControls[BUTTON_TWO]);
GetDlgItem( IDC_EDIT2 )->EnableWindow(m_bitControls[EDIT_CTRL_ONE]);
GetDlgItem( IDC_EDIT3 )->EnableWindow(m_bitControls[EDIT_CTRL_TWO]);
GetDlgItem( IDC_COMBO1 )->EnableWindow(m_bitControls[COMBO_ONE]);
GetDlgItem( IDC_COMBO2 )->EnableWindow(m_bitControls[COMBO_TWO]);
}
现在,在单击单选按钮的处理函数之一中添加以下代码。m_bitControls[BUTTON_ONE] = TRUE; m_bitControls[BUTTON_TWO] = TRUE; m_bitControls[EDIT_CTRL_ONE] = FALSE; m_bitControls[EDIT_CTRL_TWO] = FALSE; m_bitControls[COMBO_ONE] = FALSE; m_bitControls[COMBO_TWO] = FALSE; enableORdisableCtrls();上面的代码将设置第一位和第二位,并重置最后四位。之后,执行
enableORdisble
函数。此代码将启用两个按钮控件,并禁用两个编辑控件和两个组合框。有关其他两个处理程序,请参见本文的代码。此技术为以上两个问题提供了解决方案
- 代码重复:现在只有一个函数具有启用和禁用控件的代码。
- 代码维护:由于只有一个函数,因此代码维护不是一项繁重的工作。