You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何OnCommand无法检测DTN_DATETIMECHANGE?能否用其实现该检测?

问题解答

首先明确:DTN_DATETIMECHANGE消息无法通过OnCommand函数捕获。

原因很直接:Windows控件的通知消息分为两类,分别通过WM_COMMAND和WM_NOTIFY两个核心消息传递:

  • WM_COMMAND负责传递简单控件的通知(比如组合框的CBN_SELCHANGE、编辑框的EN_CHANGE、按钮的BN_CLICKED),这类消息会被MFC的OnCommand函数处理。
  • WM_NOTIFY则用于传递更复杂的控件通知,包含额外的结构体数据(比如NMHDR),DateTimePicker控件的DTN_DATETIMECHANGE就属于这类,它只会被MFC的OnNotify函数处理,OnCommand根本接收不到这类消息。

替代实现方案

方案1:重写OnNotify统一处理

在对话框类中重写OnNotify函数,统一检测日期时间控件的变更通知:

BOOL CCongregationDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    NMHDR* pNMHDR = reinterpret_cast<NMHDR*>(lParam);
    if (IsWindowVisible() && pNMHDR->code == DTN_DATETIMECHANGE)
    {
        // 可选:区分不同的日期时间控件
        if (pNMHDR->idFrom == IDC_DTP_MEETING_TIME || pNMHDR->idFrom == IDC_DTP_LAST_INVITED)
        {
            IsModified(true);
            SetControlStates();
        }
    }
    return __super::OnNotify(wParam, lParam, pResult);
}

方案2:为每个控件单独绑定消息处理

通过MFC消息映射为每个日期时间控件单独绑定处理函数:

  1. 在对话框头文件中声明处理函数:
afx_msg void OnMeetingTimeChanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnLastInvitedChanged(NMHDR* pNMHDR, LRESULT* pResult);
  1. 在cpp文件中添加消息映射:
BEGIN_MESSAGE_MAP(CCongregationDlg, CDialog)
    // 其他已有消息映射
    ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DTP_MEETING_TIME, &CCongregationDlg::OnMeetingTimeChanged)
    ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DTP_LAST_INVITED, &CCongregationDlg::OnLastInvitedChanged)
END_MESSAGE_MAP()
  1. 实现处理函数:
void CCongregationDlg::OnMeetingTimeChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    IsModified(true);
    SetControlStates();
    *pResult = 0;
}

void CCongregationDlg::OnLastInvitedChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    IsModified(true);
    SetControlStates();
    *pResult = 0;
}

内容的提问来源于stack exchange,提问作者Andrew Truckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:32:41