使用 PreTranslateMessage 检测对话框何时将焦点设置到各种组合控件

Detect when dialog sets focus to various combo controls using PreTranslateMessage

我有一个 CDialog,我正在尝试像这样覆盖 PreTranslateMessage

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

它不工作。我想要做的是在其他控件获得焦点(例如:编辑组合)时将我的 CGridCtrl 行数重置为 1。但是,如果我在第一个 if 中放置一个断点,它就永远不会被拦截。

目前我唯一能想到的就是重新编号对话框中的所有组合 ID,以便它们是连续的,然后使用 OnSetFocus 的命令范围并在该处理程序中进行检测。但是也有一些CEdit控件。

我不能使用 PTM 并避免它吗?对我来说这似乎是最简单的。

对话框如下:

目前我有 7 个组合 OnSetFocus 处理程序。当他们触发时,在右侧的网格中显示特定的分​​配历史记录。

因此,如果用户移动到对话框中的任何其他控件,分配历史控件将不适用。这就是为什么我想将历史重置为 header 行。我希望用 PTM 做到这一点。

我在对话框中添加了一个 2 秒计时器:

void CWeekendMeetingDlg::OnTimer(UINT_PTR nIDEvent)
{
    if (nIDEvent == 1)
    {
        CWnd* pControl = GetFocus();
        if (pControl != nullptr)
        {
            CWnd* pParent = pControl->GetParent();
            if (pParent != nullptr)
            {
                int iCtrlID = pParent->GetDlgCtrlID();

                if (iCtrlID != IDC_COMBO_PT_CHAIRMAN &&
                    iCtrlID != IDC_COMBO_PT_OPEN_PRAYER &&
                    iCtrlID != IDC_COMBO_WT_CLOSE_PRAYER &&
                    iCtrlID != IDC_COMBO_WEEKEND_HOST &&
                    iCtrlID != IDC_COMBO_WEEKEND_COHOST &&
                    iCtrlID != IDC_COMBO_PT_READER)
                {
                    if (m_gridAssignHist.GetRowCount() != 1)
                    {
                        m_gridAssignHist.SetRowCount(1);

                        UpdateData(TRUE);
                        m_strAssignHistLabel = _T("Assignment:");
                        UpdateData(FALSE);
                    }
                }

            }

        }

    }

    CDialog::OnTimer(nIDEvent);
}

这似乎工作正常。

子控件通知通过 WM_COMMAND 消息在父对话框中接收。覆盖 MFC 对话框的 OnCommand 捕获这些通知(CBN_SETFOCUS, EN_SETFOCUS 等)。

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