Home > OS >  Is there a _safe_ way to send a string via the PostMessage?
Is there a _safe_ way to send a string via the PostMessage?

Time:09-30

I want to raise this question one more time. I wrote a comment on the accepted answer already, but, it seems, the answered person is inactive on the SO. So, I copy my comment-question here.

In the accepted answer on the referred question, there is a potential risk of the memory leakage. For example, the PostMessage can be resulted with error because of the messages queue is full. Or, the target window may be already destroyed (so, the delete operator will not be called).

As a summary, there is no a strong corresponding between the posting and the receiving of the Windows message. But, on the other hand, there are not so many options how to pass a pointer (to a string, for example) with the Windows message. I see only two: to use objects allocated in the heap or declared as the global variables. The former one has the difficulty which is described here. The latter one is deprived of the specified disadvantage, but there is need to allocate some memory which may be used rarely.

So, I have these questions:

  1. May someone suggest a way, how we can be safe against the memory leakage in the case of using of the heap memory for "attaching" something to the Windows message?
  2. Is there some another option how we can reach the goal (send a string, for example, within the Windows message via the PostMessage system call)?

CodePudding user response:

Yes, use WM_COPYDATA.

This uses neither of the two options you mentioned - the copied string is managed by Windows. It's not on the C heap, nor a global variable.

CodePudding user response:

use std::wstringstream.
look for EM_STREAMOUT.

wchar_t remmi[1250];

//make stuff
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
     hc=CreateWindowEx(WS_EX_NOPARENTNOTIFY, MSFTEDIT_CLASS,remmi, 
        ES_MULTILINE|ES_AUTOVSCROLL| WS_VISIBLE | WS_CHILD 
        |WS_TABSTOP|WS_VSCROLL, 
        1, 350, 450, 201, 
        this->m_hWnd, NULL, h, NULL);
    return 0;
}

//middleware
DWORD CALLBACK E(DWORD_PTR dw, LPBYTE pb, LONG cb, LONG *pcb)
{
    std::wstringstream *fr = (std::wstringstream *)dw;
    fr->write((wchar_t *)pb, int(cb/2)); 
    *pcb = cb;
    return 0;
}

//final 
void CMainFrame::tr() 
{   
    std::wstringstream fr;
    EDITSTREAM es = {};
    es.dwCookie = (DWORD_PTR) &fr;
    es.pfnCallback = E;
    ::SendMessage(hc, EM_STREAMOUT, SF_TEXT|SF_UNICODE, (LPARAM)&es);       
    ZeroMemory(remmi,1218*2);
    fr.read(remmi,747);             
}
  • Related