【问题标题】:In VC++ Notification Callbacks Can NMHDR* be NULL?在 VC++ 通知回调中 NMHDR* 可以为 NULL 吗?
【发布时间】:2020-07-17 12:35:18
【问题描述】:

以下是取自https://docs.microsoft.com/en-us/cpp/mfc/reference/clistctrl-class?view=vs-2019 的一些示例代码。在我看到的所有示例中,它都没有检查 NMHDR* 是否为空。可以为null还是保证不为null?

void CListCtrlDlg::OnDblClk(NMHDR* pNMHDR, LRESULT* pResult)
{
    UNREFERENCED_PARAMETER(pResult);
    LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pNMHDR;
    LVHITTESTINFO lvhti;

    // Clear the subitem text the user clicked on.
    lvhti.pt = pia->ptAction;
    m_myListCtrl.SubItemHitTest(&lvhti);

    if (lvhti.flags & LVHT_ONITEMLABEL)
    {
        m_myListCtrl.SetItemText(lvhti.iItem, lvhti.iSubItem, NULL);
    }
}

【问题讨论】:

  • 我猜不可能吧?我不确定它是否为空是否有意义。但是显式测试它的开销很小,而且您始终可以安装 MFC 源代码并检查调用它的代码,看看是否会生成 null。

标签: c++ visual-c++ mfc


【解决方案1】:

如果您显示的处理程序(例如 CListCtrlDlg::OnDblClk 函数)被 MFC 框架调用,以响应相关的 WM_NOTIFY 消息,则 @ 987654323@ 参数将NULL

但是,可能手动调用这样的处理函数,在这种情况下,该参数可以具有调用 code(r) 愿意赋予它的任何值。

因此,就长期安全性和/或维护而言 - 尤其是在使用您几乎无法控制的其他程序员访问和/或修改的代码库时 - 您可能希望检查指针的有效性。

【讨论】:

  • 顺便说一下,“为了更好的长期安全性”我会选择相反的:不要检查nullptr。只需根据有效假设采取行动,即此论点永远不可能是 nullptr,并无条件地取消引用它。如果有人实施了错误的更改(例如直接调用通知处理程序),则让您的程序立即崩溃。这有两个好处:编辑会立即获得反馈,并且反馈是他们不能(意外)忽略的那种。
  • @IInspectable 我不能也不会质疑你的理念。完全没有。我只是说可能得到nullptr 第一个参数;这甚至可以作为一项功能实现,其中“其他程序员”已经为该nullptr 添加了相关检查并相应地处理它。例如,在另一个控件中模拟双击的按钮单击。
  • “模拟双击” 已经有问题了。要么注入真正的双击(使用SendInput),要么触发双击的效果(使用 UI 自动化或类似模式)。这也不仅仅是哲学:它是我在许多 MFC 代码库中使用并引入的。即使在最初遭到怨恨的那些时候,它也成功地拒绝了快速和肮脏的黑客攻击(又名技术债务),并为每个合理的用例提供了完全的保真度。
  • @IInspectable 同样,我在上一条评论中给出的“示例用法”的可疑性没有争议。另外,我已经编辑了我的答案,因此它不太倾向于建议以任何方式覆盖框架是可以接受的。一如既往,我感谢您富有洞察力的 cmets。
猜你喜欢
  • 1970-01-01
  • 2016-10-11
  • 2011-04-15
  • 2012-07-06
  • 2016-10-17
  • 2010-11-10
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多