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

Posted

技术标签:

【中文标题】将 CString::GetString() 与 CWnd::SendMessage() 一起使用是不是安全?【英文标题】: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。 【参考方案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 中回答了。

以上是关于将 CString::GetString() 与 CWnd::SendMessage() 一起使用是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

php [将产品与社交共享插件集成]将社交共享插件与WooCommerce集成 - Sharedaddy

php [将产品与社交共享插件集成]将社交共享插件与WooCommerce集成 - Sharedaddy

php [将产品与社交共享插件集成]将社交共享插件与WooCommerce集成 - 分享此功能

php [将产品与社交共享插件集成]将社交共享插件与WooCommerce集成 - 分享此功能

php [将产品与社交共享插件集成]将社交共享插件与WooCommerce集成 - 分享此功能

将 Apollo for iOS 与现有项目集成?