使用 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);
}
我有一个 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);
}