Simple Way to Check All Dialog Controls for Changings

It is very difficult and toilsome to implement code that checks every single
control on a given dialog for changes; especially for complex dialogs. Normally you
have to check all fields when the dialog was closed (let’s say in OnOK) or have to
catch all events like EN_CHANGED or BN_CLICKED to notice a changing. But fortunately
the MFC provides a method to do such checkings in a very easy and compact way. This
magical function calls

ON_CONTROL_RANGE ( wNotifyCode, id1, id2, memberFxn )

Use this macro to map a contiguous range of control IDs to a single message
handler function for a specified Windows notification message. ClassWizard
does not support creating an ON_CONTROL_RANGE handler in the user interface,
so you must place the macro yourself. Be sure to put it outside the message
map //{{AFX_MSG_MAP delimiters. Once entered, ClassWizard will parse these
entries and allow you to browse them just like any other message map entries.

The BN_KILLFOCUS notification code is sent when a button loses the keyboard focus.
The button must have the BS_NOTIFY style to send this notification message.

Usage

  1. Add the message handlers declaration…

  2. BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    //{{AFX_MSG_MAP(CMyDlg)
    ON_WM_CREATE()
    //}}AFX_MSG_MAP

    ON_CONTROL_RANGE(EN_CHANGE, IDC_EDIT1, IDC_EDIT3, OnRangeUpdateED)
    ON_CONTROL_RANGE(BN_CLICKED , IDC_RADIO1, IDC_RADIO8, OnRangeUpdateRB)
    ON_CONTROL_RANGE(BN_KILLFOCUS , IDC_CHECK1, IDC_CHECK6, OnRangeUpdateCB)
    END_MESSAGE_MAP()

  3. Declare the function in your header file that way:

  4. class CMyDlg : public CDialog
    {
    public:
    BOOL m_bUpdateED;
    BOOL m_bUpdateRB;
    BOOL m_bUpdateCB;

    protected:
    // Generated message map functions
    //{{AFX_MSG(CMyDlg)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    virtual BOOL OnInitDialog();
    virtual void OnOK();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()

    virtual void OnRangeUpdateED(UINT nID);
    virtual void OnRangeUpdateRB(UINT nID);
    virtual void OnRangeUpdateCB(UINT nID);
    };

  5. And finally code your ‘OnRangeUpdate…’ functions that way:

  6. void CMyDlg::OnRangeUpdateED(UINT nID)
    {
    // extra check
    if ( SendDlgItemMessage(nID, EM_GETMODIFY, 0, 0) )
    m_bUpdateED = TRUE;
    else
    m_bUpdateED = FALSE;
    }

    void CMyDlg::OnRangeUpdateRB(UINT nID)
    {
    // for example
    if ( nID == IDC_RADIO3 )
    m_bUpdateRB = TRUE;
    else
    m_bUpdateRB = FALSE;
    }

    void CMyDlg::OnRangeUpdateCB(UINT nID)
    {
    // for example
    LRESULT lResult = SendDlgItemMessage(nID, BM_GETSTATE, 0, 0);
    if ( lResult == BST_CHECKED )
    m_bUpdateCB = TRUE;
    else
    m_bUpdateCB = FALSE;
    }

    void CMyDlg::OnOK()
    {
    if ( m_bUpdateRB )
    // …

    CDialog::OnOK();
    }

More by Author

Must Read