2

I tried to use WM_COPYDATA to send a string from one window to another. The messaages gets received perfectly by my receiving window. Except the string I send does not stay intact.

Here is my code in the sending application:

 HWND wndsend = 0;
 wndsend = FindWindowA(0, "Receiving window");
 if(wndsend == 0)
 {
    printf("Couldn't find window.");
 }

TCHAR* lpszString = (TCHAR*)"De string is ontvangen";
COPYDATASTRUCT cds;
cds.dwData = 1; 
cds.cbData = sizeof(lpszString);
cds.lpData = (TCHAR*)lpszString;
SendMessage(wndsend, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)(LPVOID)&cds);

And this is the code in the receiving application:

 case WM_COPYDATA :
    COPYDATASTRUCT* pcds;
    pcds = (COPYDATASTRUCT*)lParam;
    if (pcds->dwData == 1)
    {
        TCHAR *lpszString;
        lpszString = (TCHAR *) (pcds->lpData);
        MessageBox(0, lpszString, TEXT("clicked"), MB_OK | MB_ICONINFORMATION);
    }

    return 0;

Now what happens is that the messagebox that gets called outputs chinese letters.

My guess is that I didn't convert it right, or that I don't actually send the string but just the pointer to it, which gives a totally different data in the receiver's window. I don't know how to fix it though.

  • You are using `TCHAR` as the data type in both cases. Is the build type (ANSI/Unicode) for the two applications the same? – Jon Jan 27 '14 at 12:24
  • 1
    (TCHAR*) is the wrong way to declare a TCHAR literal. Use the _T(...) macro. – David Heffernan Jan 27 '14 at 12:31
  • @Jon I plan on using my code in a dll later on that could be called by both ANSI/Unicode built applications, this is why I chose to use TCHAR. – Jerome smith Jan 27 '14 at 12:53
  • @Jeromesmith: Bad idea, just stick to Unicode. We're no longer living in an age where saving 20 bytes on a string is worth maintaining 2 incompatible versions of your program. – MSalters Jan 27 '14 at 14:02
  • @MSalters is right. If you really want to expose functions for ansi and wide do so in the same dll. But it's better just to offer Unicode. – David Heffernan Jan 27 '14 at 14:55

2 Answers2

3

sizeof(lpszString) is the size of the pointer, but you need the size in bytes of the buffer. You need to use:

sizeof(TCHAR)*(_tcsclen(lpszString)+1)

The code that reads the string should take care not to read off the end of the buffer by reading the value of cbData that is supplied to it.

Remember that sizeof evaluates at compile time. Keep that thought to the front of your mind when you use it and if ever you find yourself using sizeof with something that you know to be dynamic, take a step back.

As an extra, free, piece of advice I suggest that you stop using TCHAR and pick one character set. I would recommend Unicode. So, use wchar_t in place of TCHAR. You are already building a Unicode app.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

Also, lpData is a pointer to the actual data, and cbData should be the size of the data, but you're actually setting the size of the pointer. Set it to the length of the string instead (and probably the terminating 0 character too: strlen(lpszString)+1

Steven Don
  • 2,436
  • 15
  • 14