在Windows編程中,我們經常要對控制項進行狀態切換。例如,根據複選框的狀態進行其餘控制項狀態的變換:
CButton m_chkDate; // 與一個Check Box複選框控制項關聯
CDateTimeCtrl m_dateFrom; // 與一個日期控制項關聯
CDateTimeCtrl m_dateTo; // 與一個日期控制項關聯 現在要達到的效果是:在使用者選中複選框時,將兩個日期控制項啟用;而當取消選中複選框時,兩個日期控制項不可用。普通的程式員會使用if…else來實現:// 日期複選框事件相應函數
void CRentDlg::OnCheckDate()
{
//根據複選框的選中狀態,分兩種情況進行設定
if (m_chkDate.GetCheck())
{
m_dateFrom.EnableWindow(true);
m_dateTo.EnableWindow(true);
}
else
{
m_dateFrom.EnableWindow(false);
m_dateTo.EnableWindow(false);
}
}
這種實現方式可以很好地運行,但是這是一種非常糟糕的代碼。
通常,一個控制項只有兩種狀態(非0即1),所以我們完全可以設立一個狀態標誌,利用該狀態標誌去改變不同控制項的狀態,代碼如下所示:
// 日期複選框事件相應函數
void CRentDlg::OnCheckDate()
{
bool bState = ((m_chkDate.GetCheck() == BST_CHECKED) ? true : false); // 擷取複選框狀態
m_dateFrom.EnableWindow(bState); // 與狀態標誌一致
m_dateTo.EnableWindow(bState);
}
在上面的代碼中,如果要使m_dataTo控制項的狀態與m_dateFrom的狀態相反,可以這樣寫:
m_dateTo.EnableWindow(!bState); // 對狀態標誌取反
查看了一下MSDN,發現CButton的GetCheck()方法會返回三種狀態,分別是:
#define BST_UNCHECKED 0x0000
#define BST_CHECKED 0x0001
#define BST_INDETERMINATE 0x0002
所以在擷取複選框狀態時以下代碼雖然在大多數情況下沒有問題,但是其邏輯是不嚴密的:
bool bState = m_chkDate.GetCheck();