是否安全使用CString::GetString()与CWnd::SendMessage()?



我有这样的代码:

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;
}

SendMessage为阻塞呼叫。一旦返回,它就不再需要访问它的参数。考虑到这一点

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

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

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

一般来说,如果你实现一个消息处理程序,你应该遵循Windows API的核心原则。最终有两种实现:
  • 存储客户端提供的数据(如SetWindowTextW)的副本。
  • 如果API获得客户端提供的数据(如SelectObject)的所有权,则返回对前一个值的引用。

在标题中回答你的问题:

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

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

最新更新