使用 CString::GetString() 和 CWnd::SendMessage() 是否安全?
Is it safe to use CString::GetString() with 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;
}
回答标题中的问题:
Is it safe to use CString::GetString() with CWnd::POstMessage()?
不,不是 - CString
的内容可能会在处理邮件时重新分配或删除。
SendMessage
是阻塞调用。一旦它 returns,它就不再需要访问它的参数。考虑到这一点
GetParent()->SendMessage(UWM_DELETE_NAME_HISTORY_MSG, (WPARAM)strName.GetString());
是安全的(就 SendMessage
调用而言)。
您仍然需要注意 UWM_DELETE_NAME_HISTORY_MSG
消息(大概是自定义消息)的实现者。如果实现存储一个指针并在处理程序 运行 完成后使用它,那么这是一个需要解决的问题。
一般来说,如果您实现消息处理程序,您应该遵循Windows API 的核心原则。最终有两种实现:
- 存储客户提供的数据的副本(例如
SetWindowTextW
)。
- Return 对先前值的引用,以防 API 获得客户端提供的数据的所有权(例如
SelectObject
)。
我有这个代码:
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;
}
回答标题中的问题:
Is it safe to use CString::GetString() with CWnd::POstMessage()?
不,不是 - CString
的内容可能会在处理邮件时重新分配或删除。
SendMessage
是阻塞调用。一旦它 returns,它就不再需要访问它的参数。考虑到这一点
GetParent()->SendMessage(UWM_DELETE_NAME_HISTORY_MSG, (WPARAM)strName.GetString());
是安全的(就 SendMessage
调用而言)。
您仍然需要注意 UWM_DELETE_NAME_HISTORY_MSG
消息(大概是自定义消息)的实现者。如果实现存储一个指针并在处理程序 运行 完成后使用它,那么这是一个需要解决的问题。
一般来说,如果您实现消息处理程序,您应该遵循Windows API 的核心原则。最终有两种实现:
- 存储客户提供的数据的副本(例如
SetWindowTextW
)。 - Return 对先前值的引用,以防 API 获得客户端提供的数据的所有权(例如
SelectObject
)。