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

Visual c++ 使用PreTranslateMessage检测对话框何时将焦点设置为各种组合控件,visual-c++,mfc,setfocus,Visual C++,Mfc,Setfocus,我有一个CDialog,我正试图覆盖PreTranslateMessage,如下所示: BOOL CWeekendMeetingDlg::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_SETFOCUS) { if (::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_CHAIRMAN && ::GetDlgCt

我有一个
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并避免它吗?对我来说,这似乎是最简单的

以下是对话框:

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

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


因此,如果用户移动到对话框上的任何其他控件,则分配历史记录控件将不适用。这就是为什么我想将历史记录重置为标题行。我希望通过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\u命令
消息接收子控件通知。重写MFC对话框的
OnCommand
会捕获这些通知(,等等)


您可以直接使用。@dxiv,对不起,这就是我的意思,我已经为我的特定组合实现了这些消息处理程序。我想我找到了一个解决办法。不知道为什么用复数来表示“处理者”。CBN_SETFOCUS将在父窗口(对话框)中被捕获,并且在您的情况下,所有子ID只需要一个处理程序。@dxiv是的,我明白了,但我仍然要检测其他类型的控件。我认为计时器是一个足够简单的解决方案。我不确定这一点,但它太长了,无法发表评论,所以我将它作为一个答案发布。谢谢,我会试试这个。看起来我需要为下拉列表的组合框处理CBN_下拉列表,为按钮处理BN_设置焦点。我会更新你的。