Search code examples
visual-c++mfcsetfocus

Detect when dialog sets focus to various combo controls using PreTranslateMessage


I have a CDialog and I am trying to override PreTranslateMessage like this:

BOOL CWeekendMeetingDlg::PreTranslateMessage(MSG* pMsg)
{

    if (pMsg->message == WM_SETFOCUS)
    {
        if (::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_CHAIRMAN &&
            ::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_OPEN_PRAYER &&
            ::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WT_CLOSE_PRAYER &&
            ::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WEEKEND_HOST &&
            ::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WEEKEND_COHOST &&
            ::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_READER)
        {
            if (m_gridAssignHist.GetRowCount() != 1)
            {
                m_gridAssignHist.SetRowCount(1);
            }
        }
    }

    return CDialog::PreTranslateMessage(pMsg);
}

It is not working. What I want to do is reset my CGridCtrl row count to 1 when other controls gain focus (eg: edit combo). But if I put a breakpoint inside the first if it is never intercepted.

At the moment the only thing I can think of is to renumber all of the combo IDs on the dialog so they are sequential and then use a command range for OnSetFocus and detect in that handler. But there are also some CEdit controls.

Can't I use PTM though and avoid that? For me it seems it would be the easiest.

Here is the dialog:

enter image description here

At the moment I have 7 combo OnSetFocus handlers. When they fire the display specific assignment history in the grid on the right.

So if the user moves to any other control on the dialog, the assignment history control will not apply. And that was why i wanted to reset the history to just the header row. And I was hoping to do this with PTM.


Solution

  • Child control notifications are received in the parent dialog via WM_COMMAND messages. Overriding MFC dialog's OnCommand catches those notifications (CBN_SETFOCUS, EN_SETFOCUS etc).

    void DoSomething()
    {   /* ... */ }
    
    BOOL CWeekendMeetingDlg::OnCommand(WPARAM wParam, LPARAM /*unused*/)
    {
        switch (HIWORD(wParam))
        {
        case CBN_SETFOCUS:
            switch (LOWORD(wParam))
            {
            case IDC_COMBO_PT_CHAIRMAN:
            // ...more combobox IDCs
                DoSomething();
                break; // or return TRUE to bypass any message map handlers
            }
            break;
    
        case EN_SETFOCUS:
            switch (LOWORD(wParam))
            {
            case IDC_EDIT_WHATEVER:
            // ...more editbox IDCs
                DoSomething();
                break;
            }
            break;
    
        // ...more notification codes
        }
        return CDialog::OnCommand(wParam, lParam);
    }