65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (14投票s)

2002年4月17日

2分钟阅读

viewsIcon

70282

downloadIcon

711

使用 STL bitset 类创建优雅的解决方案来解决常见问题。

Sample Image - screen.jpg

引言

最近我在做一个项目,其中一个对话框上有许多控件。此对话框可以根据不同的用户交互显示,并且在不同的交互中,此对话框的某些控件变为启用状态,而另一些控件变为禁用状态。

为此,我必须根据一些变量来决定哪些控件将被启用或禁用。例如:

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);
}

上面的解决方案很好,但是使用上述解决方案存在两个明显的问题

  1. 代码重复:有很多代码重复用于启用或禁用各种控件。
  2. 代码维护:如果将来添加了一个控件,那么我们必须更新所有启用或禁用控件的函数中的控件状态。很有可能我们会忘记在某些地方更新它。

通过使用 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函数。此代码将启用两个按钮控件,并禁用两个编辑控件和两个组合框。有关其他两个处理程序,请参见本文的代码。

此技术为以上两个问题提供了解决方案

  1. 代码重复:现在只有一个函数具有启用和禁用控件的代码。
  2. 代码维护:由于只有一个函数,因此代码维护不是一项繁重的工作。
© . All rights reserved.