0

I have this code:

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

Is it safe for me to change it like this:

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

Related to this, is it correct to use static_cast<WPARAM>(strName.GetString())?


For completion, this is my custom message handler:

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;
}
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 3
    It depends on what the message handler for UWM_DELETE_NAME_HISTORY_MSG does. – Jim Rhodes Sep 10 '21 at 20:55
  • 2
    Title says PostMessage, and the question asks SendMessage, make up your mind, Post may be unsafe when Send safe – Alex Guteniev Sep 10 '21 at 20:59
  • 1
    `static_cast(strName.GetString())` won't compile. You'll need a `reinterpret_cast` to go from a pointer to a WPARAM. And yes, you need to do that sort of `reinterpret_cast(string)` quite a lot with standard Windows messages that take a `char*` for their Lparam. – Adrian Mole Sep 10 '21 at 21:58

2 Answers2

3

SendMessage is a blocking call. Once it returns, it no longer needs access to its arguments. With that in mind

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

is safe (as far as the SendMessage call is concerned).

You'd still need to be careful about the implementer of the UWM_DELETE_NAME_HISTORY_MSG message (which, presumably, is a custom message). If the implementation stores a pointer and uses it after the handler has run to completion, then that is an issue that needs to be resolved.

In general, if you implement a message handler, you should follow the Windows API's core principles. There are ultimately two implementation:

  • Store a copy of client-provided data (such as SetWindowTextW).
  • Return a reference to the previous value in case the API takes ownership of the client-provided data (such as SelectObject).
IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • Thanks. I have added my custom message handler for completeness. I think it is all OK now. The only difference being that I have used `reinterpret_cast`. – Andrew Truckle Sep 11 '21 at 15:56
0

To answer your question in the title:

Is it safe to use CString::GetString() with CWnd::POstMessage()?

No, it is not - the content of that CString may be reallocated or deleted by the time the message will be processed.

Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27