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个comboOnSetFocus
处理程序。当它们触发时,在右侧的网格中显示特定的分配历史记录
因此,如果用户移动到对话框上的任何其他控件,则分配历史记录控件将不适用。这就是为什么我想将历史记录重置为标题行。我希望通过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_设置焦点。我会更新你的。