0

I have two windows applications. First one a windows forms application. The second one a console application. I have to send a message from the console application to the forms application. I registered broadcast message and using ::PostMessage function was able to send a numeric message to the forms application. But I am not able to send string message. Please find my code below:-

// Sending Message (Console Application)
#define RT_UI_MSG      (WM_USER+1)
UINT msg_id = RegisterWindowMessage("Test-UI");
LPTSTR lpszString = "Hello";
COPYDATASTRUCT cds;
cds.dwData = 1; // can be anything
cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
cds.lpData = &lpszString;
::PostMessage(HWND_BROADCAST, msg_id, WM_COPYDATA, (LPARAM)(LPVOID)&cds);
// Receiving Message (Forms Application)
BEGIN_MESSAGE_MAP(CRTUIDlg, CDialogEx)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_BN_CLICKED(IDOK, &CRTUIDlg::OnBnClickedOk)
   ON_REGISTERED_MESSAGE(temp, OnRTUIMsg)
   ON_BN_CLICKED(IDC_BUTTON1, &CRTUIDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

UINT temp = RegisterWindowMessage(L"Test-UI");
LRESULT CRTUIDlg::OnRTUIMsg(WPARAM wParam, LPARAM lParam)
{
    COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
    if (pcds->dwData == 1)
    {
        LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
        // do something with lpszString...
    }
    return 0;
}

Kindly help me understand what I am doing wrong and get this working

IInspectable
  • 46,945
  • 8
  • 85
  • 181
Sam
  • 113
  • 5
  • 13
  • I receive the message using this code in the forms application, but the received data is empty, the entire pointer pcds is empty. – Sam Apr 24 '17 at 19:31

2 Answers2

4

There is no way to PostMessage a WM_COPYDATA. The system needs to know when to free the internal buffer used to marshal the data. And this is known only when you send, not when you post a message.

See Why can't I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout?

IInspectable
  • 46,945
  • 8
  • 85
  • 181
alangab
  • 849
  • 5
  • 20
0

WM_COPYDATA states the following:

"The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data."

But you are including a pointer to the source application heap (lpszString) into the structure which is not supported, because the heap of the source application is not accessible to the target application. WM_COPYDATA will copy that pointer as is, it will not copy the string referenced by the pointer.

I suggest looking at the example in WM_COPYDATA, the example seems to do what you need but instead of passing a string from the heap, it copies the string into the stack using a char array.

This is the link to the example: https://msdn.microsoft.com/en-us/library/windows/desktop/ms649009(v=vs.85).aspx

blit
  • 396
  • 5
  • 12
  • 1
    That's a good point, but I don't think its relevant to the question. For what its worth, I think it can be fixed just by changing `cds.lpData = &lpszString;` to `cds.lpData = lpszString;`, as the poster has got the length (roughly) right. – pjcard Jan 30 '18 at 17:25