3

I'm developing 4 applications (using founded examples in internet) with Visual Studio 2010: 2 in C++ MFC (named: SenderCpp and ReceiverCpp) and 2 in C# (named: SenderCsh and ReceiverCsh) to test the WM_DATACOPY interprocess communication.

My goal is to have the C++ application "SenderCpp" that send some data to the C# application "ReceiverCsh" and it doesn't work, no message is received by the "ReceiverCsh".

So:

  • SenderCpp->ReceiverCpp: works
  • SenderCsh->ReceiverCsh: works
  • SenderCpp->ReceiverCsh: not works

The SenderCpp code is:

void SendCopyData(HWND hFind)
{
    COPYDATASTRUCT cp;
    StackRecord record;

    record.CursorX = 1;
    record.CursorY = -1;

   _tcscpy(record.cmdline, L"Hello World!");
   cp.cbData = sizeof(record);
   cp.lpData = &record;
   cp.dwData = 12;
   SendMessage(hFind, WM_COPYDATA, NULL, (LPARAM)&cp);
}

void CCANDriverDlg::OnBnClickedButton2()
{
   HWND hWnd = ::FindWindow(NULL, CString("ReceiverCpp"));
   SendCopyData(hWnd);
}

void CCANDriverDlg::OnBnClickedButton1()
{
   HWND hWnd = ::FindWindow(NULL, CString("ReceiverCsh"));
   SendCopyData(hWnd);
}

The ReceiverCsh is:

 protected override void WndProc(ref Message m)
    {
        switch(m.Msg)
        {
            case WM_COPYDATA:
                // Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
                CopyDataStruct st = (CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(CopyDataStruct));
                //txtmessagereceive.Text = strData;

                CANMessage MsgIn = new CANMessage(8);
                MsgIn = (CANMessage)Marshal.PtrToStructure(st.lpData, typeof(CANMessage));

                // Decode the marshaled message
                txtmessagereceive.Text = "dwData = " + st.dwData.ToString() +"\r\n" +
                                        "cbData = " + st.cbData + " bytes\r\n" +
                                        "CANID = " + MsgIn.CANID.ToString() + "\r\n";
                for (int i=0; i<8; i++)
                {
                    txtmessagereceive.Text += String.Format("Data[{0}]={1}\r\n", i, MsgIn.Data[i]);
                }

                break;
            default:
                // let the base class deal with it
                base.WndProc(ref m);
                break;
        }
    }

Using Spy++ I see that monitoring the "ReceiverCsh" no message is displayed when the WM_COPYDATA is sent by SenderCpp instead the message is displayed when the ReceiverCpp is analyzed.

Have you some idea? Thanks.

mais76
  • 43
  • 2
  • 5
  • 3
    WM_COPYDATA is a fairly miserable way to exchange data. Finding the proper window handle is never that straight forward and UIPI is a constant headache. You make it a lot worse by omitting all error checking, a null check on the window handle is required. Do favor a named pipe or socket instead. – Hans Passant Feb 07 '13 at 17:00
  • Do you see _any_ window messages in your C# WndProc? Have you verified that the window handle value you send to on the C++ side is the same as on the WndProc form on the C# side? – 500 - Internal Server Error Feb 07 '13 at 17:36
  • Yes I verified that using Spy++. I put a breakpoint to see the returned value of the FindWindow() in both cases (OnBnClickedButton1 and 2) and they are consistent with the handle read on the Spy++. I insert also a brekpoint in the WndProc when Marshal.PtrToStructure() is called at the application never stops when C++ send the message. – mais76 Feb 08 '13 at 08:04

1 Answers1

0

I'm wondering if ReceiverCsh is a console application. In order to use the WndProc override, you need to have a message pump going to receive the external messages. Make sure this is the case.

See Handling Messages in Console Apps for more details

SwDevMan81
  • 48,814
  • 22
  • 151
  • 184