【问题标题】:Is it safe to use CString::GetString() with CWnd::SendMessage()?将 CString::GetString() 与 CWnd::SendMessage() 一起使用是否安全?
【发布时间】:2021-11-07 06:37:10
【问题描述】:

我有这个代码:

GetParent()->SendMessage(UWM_DELETE_NAME_HISTORY_MSG, (WPARAM)strName.GetBufferSetLength(_MAX_PATH));
strName.ReleaseBuffer();

这样更改对我来说安全吗:

GetParent()->SendMessage(UWM_DELETE_NAME_HISTORY_MSG, (WPARAM)strName.GetString());

与此相关,使用static_cast<WPARAM>(strName.GetString())是否正确?


为了完成,这是我的自定义消息处理程序:

LRESULT CChristianLifeMinistryEditorDlg::OnDeleteNameHistory(WPARAM wParam, LPARAM lParam)
{
    auto szName = (LPCTSTR)wParam;

    m_History.erase(szName);

    for (auto& kv : m_mapWeekendHistData)
        kv.second.erase(szName);

    return 0;
}

【问题讨论】:

  • 这取决于 UWM_DELETE_NAME_HISTORY_MSG 的消息处理程序的作用。
  • 标题说PostMessage,问题问SendMessage,下定决心,Send safe时Post可能不安全
  • static_cast<WPARAM>(strName.GetString()) 不会编译。您需要reinterpret_cast 才能从指针转到 WPARAM。是的,您需要对标准 Windows 消息执行大量 reinterpret_cast<LPARAM>(string) 处理,这些消息将 char* 作为 Lparam。

标签: visual-c++ casting mfc c-strings postmessage


【解决方案1】:

SendMessage 是一个阻塞调用。一旦它返回,它就不再需要访问它的参数。考虑到这一点

GetParent()->SendMessage(UWM_DELETE_NAME_HISTORY_MSG, (WPARAM)strName.GetString());

是安全的(就SendMessage 调用而言)。

您仍然需要小心UWM_DELETE_NAME_HISTORY_MSG 消息(可能是自定义消息)的实现者。如果实现存储了一个指针并在处理程序运行完成后使用它,那么这是一个需要解决的问题。

一般来说,如果您实现消息处理程序,您应该遵循 Windows API 的核心原则。最终有两种实现方式:

  • 存储客户端提供数据的副本(例如SetWindowTextW)。
  • 返回对先前值的引用,以防 API 获得客户端提供的数据的所有权(例如 SelectObject)。

【讨论】:

  • 谢谢。为了完整性,我添加了自定义消息处理程序。我认为现在一切都好。唯一的区别是我使用了reinterpret_cast<WPARAM>
【解决方案2】:

在标题中回答您的问题:

将 CString::GetString() 与 CWnd::POstMessage() 一起使用是否安全?

不,不是 - 在处理消息时,CString 的内容可能会被重新分配或删除。

【讨论】:

  • 我的标题是说 SendMessage。很抱歉我的疏忽。
  • @AndrewTruckle 哦,那就在 cmets 中回答了。
猜你喜欢
  • 2012-07-26
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 2012-10-21
  • 2011-12-04
  • 1970-01-01
相关资源
最近更新 更多