2010年11月4日 星期四

Button Array

我想建一個如下圖所示的對話盒界面。


當我在Resource Edit中double click [Method 1]的check box,Visual Studio 會自動幫我們加入相對應的click message函式

afx_msg void OnBnClickedCheckMethod1();

與其Message Map

ON_BN_CLICKED(IDC_CHECK_METHOD_1, &CSetCompareMethodDlg:: OnBnClickedCheckMethod1)

我程式中的功能會將此時的相對應Method元件設為enable或disable

void CSetCompareMethodDlg::OnBnClickedCheckMethod1()
{
    if(CButton* pCheck = (CButton*)GetDlgItem(IDC_CHECK_METHOD_1))
    {
        m_pObj[0]->Enable((pCheck->GetCheck() == 0) ? false : true);
    }
}

以我的例子而言,我要做8個非常類似的函式,其中只有ID與index不同。這並不會造成我們什麼困擾只是程式的一點怪味而已。

那,該如何讓這個動作變得優雅呢。

關鍵在於能否讓UI的動作包含ID。我們可以用ON_COMMAND_EX取代ON_BN_CLICKED來改寫。

1. 在class宣告中加入

afx_msg BOOL OnBnClickedCheckMethodEX(UINT uid);

2. 把

ON_BN_CLICKED(IDC_CHECK_METHOD_1, &CSetCompareMethodDlg:: OnBnClickedCheckMethod1)

改寫為

ON_COMMAND_EX(IDC_CHECK_METHOD_1, &CSetCompareMethodDlg::OnBnClickedCheckMethodEX)

同樣的動作把IDC_CHECK_METHOD_2 ~IDC_CHECK_METHOD_8都用ON_COMMAND_EX取代

3. 實作OnBnClickedCheckMethodEX

BOOL CSetCompareMethodDlg:: OnBnClickedCheckMethodEX(UINT uid)
{
    if(CButton* pCheck = (CButton*)GetDlgItem(uid))
    {
        // m_pObj[index]->Enable((pCheck->GetCheck() == 0) ? false : true);
    }

    return TRUE;
}

4. 現在的問題是如何把uid和index對應起來,有2種方法可行。如果你無法更動Resource.h的話。

BOOL CSetCompareMethodDlg:: OnBnClickedCheckMethodEX(UINT uid)
{
    const UINT nCheckID[8] = {
        IDC_CHECK_METHOD_1, IDC_CHECK_METHOD_2, IDC_CHECK_METHOD_3, IDC_CHECK_METHOD_4,
        IDC_CHECK_METHOD_4, IDC_CHECK_METHOD_6, IDC_CHECK_METHOD_7, IDC_CHECK_METHOD_8
    };

    for(int index=0 ; index<8 ; index++)
    {
        if(uid == nCheckID[index])
        {
            if(CButton* pCheck = (CButton*)GetDlgItem(uid))
            {
                pObj[index]->Enable((pCheck->GetCheck() == 0) ? false : true);
            }

            return TRUE;
        }
    }
    return FALSE;
}

如果你可以更動Resource.h的話,我會先到Resource.h中把ID做排序

#define IDC_CHECK_METHOD_1 1004
#define IDC_CHECK_METHOD_2 1005
#define IDC_CHECK_METHOD_3 1006
#define IDC_CHECK_METHOD_4 1007
#define IDC_CHECK_METHOD_5 1008
#define IDC_CHECK_METHOD_6 1009
#define IDC_CHECK_METHOD_7 1010
#define IDC_CHECK_METHOD_8 1011

然後函式能寫的更簡捷

BOOL CSetCompareMethodDlg::OnBnClickedCheckMethodEX(UINT uid)
{
    int index = uid - IDC_CHECK_METHOD_1;

    if(CButton* pCheck = (CButton*)GetDlgItem(uid))
    {
        pObj[index]->Enable((pCheck->GetCheck() == 0) ? false : true);

        return TRUE;
    }

    return FALSE;
}

當然要改ID你必需要很小心很小心。

沒有留言:

張貼留言