title: Read lParam sent from c++ to C# as string
body: <p>I have a c++ application which uses <code>SendNotifyMessage</code> to redirect a <em>CB_FINDSTRINGEXACT</em> to C# code. Now, I want to change it to <em>WM_COPYDATA</em> but I can't make it work.</p>
  
  <p>C++ code:</p>
  
  <pre><code>static LRESULT CALLBACK GetMsgHookCallback(int code, WPARAM wparam, LPARAM lparam){
  if (code &gt;= 0)
  {
      UINT msg = 0;
      UINT msg2 = 0;
  
      msg = RegisterWindowMessage("WILSON_HOOK_GETMSG");
      msg2 = RegisterWindowMessage("WILSON_HOOK_GETMSG_PARAMS");
  
      HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_GETMSG");
  
      MSG* pMsg = (MSG*)lparam;
  
      if (msg != 0 &amp;&amp; pMsg-&gt;message != msg &amp;&amp; pMsg-&gt;message != msg2)
      {
          if (pMsg-&gt;message == CB_ADDSTRING)
          {
              SendNotifyMessage(dstWnd, msg, (WPARAM)pMsg-&gt;hwnd, pMsg-&gt;message);
              SendNotifyMessage(dstWnd, msg2, pMsg-&gt;wParam, pMsg-&gt;lParam); //plus more code...
  </code></pre>
  
  <p>Now, as my intention is to read the string in <code>pMsg-&gt;lParam</code> and I can't make it work from the c# side*, I'm trying to use WM_COPYDATA this way:</p>
  
  <pre><code>                SendNotifyMessage(dstWnd, msg, (WPARAM)pMsg-&gt;hwnd, pMsg-&gt;message);
              SendNotifyMessage(dstWnd, msg2, pMsg-&gt;wParam, pMsg-&gt;lParam);
  
              // Added code
              CString *message = (CString*)pMsg-&gt;lParam;
              COPYDATASTRUCT cpd;
              cpd.dwData = 0;
              cpd.cbData = message-&gt;GetLength();
              cpd.lpData = (void*)message-&gt;GetBuffer(cpd.cbData);
              ::SendMessage(dstWnd, WM_COPYDATA, (WPARAM)pMsg-&gt;hwnd, (LPARAM)&amp;cpd);
              SendNotifyMessage(dstWnd, WM_COPYDATA, (WPARAM)pMsg-&gt;hwnd, (LPARAM)&amp;cpd);
  </code></pre>
  
  <p>However, I never receive any <em>WM_COPYDATA</em> in my c# application*.</p>
  
  <p>Here is the C# part:</p>
  
  <pre><code>        int CB_FINDSTRINGEXACT = 0x0158;
      public const Int32 WM_COPYDATA = 0x4A;
      private void test(IntPtr Handle, IntPtr Message, IntPtr wParam, IntPtr lParam)
      {
  
          if (Message.ToInt32() == CB_FINDSTRINGEXACT)
          {
              String one = Marshal.PtrToStringAuto(lParam); // This gives accessviolationexception
              String dos = Marshal.PtrToStringAnsi(lParam);   // returns empty string
              Console.WriteLine("SOMETHING RECEIVED: "+one+". dos: "+dos+". tres: "+lParam.ToString()); // last part is only an intptr
          }
          if (Message.ToInt32() == WM_COPYDATA) // never true
              Console.WriteLine("COPYDATA: ");
      }
  </code></pre>
  
  <p>I've tried many solutions I've read but none seems to work. How do I read the lParam (which is a String really) from c++ in my c# function? I want to get the string.</p>
  
  <p>EDIT1:</p>
  
  <p>I've tried couple of ways to get WM_COPYDATA working but didn't succeed. Here they are:</p>
  
  <pre><code>                    // Test 1: c# never receives anything
                  COPYDATASTRUCT* copy_data = (COPYDATASTRUCT*)(pCwpStruct-&gt;lParam);
                  SendMessage(dstWnd, WM_COPYDATA, (WPARAM)pCwpStruct-&gt;hwnd, (LPARAM)&amp;copy_data);
                  SendNotifyMessage(dstWnd, WM_COPYDATA, (WPARAM)pCwpStruct-&gt;hwnd, (LPARAM)&amp;copy_data);
  
                  // Test 2: c# never receives anything
                  LPCTSTR lpszString = (LPCTSTR)pCwpStruct-&gt;lParam;
                  COPYDATASTRUCT cds;
                  cds.dwData = 0;
                  cds.cbData = sizeof(TCHAR)* (_tcslen(lpszString) + 1);
                  cds.lpData = (PVOID)lpszString;
                  SendMessage(dstWnd, WM_COPYDATA, (WPARAM)pCwpStruct-&gt;hwnd, (LPARAM)(LPVOID)&amp;cds);
                  SendNotifyMessage(dstWnd, WM_COPYDATA, (WPARAM)pCwpStruct-&gt;hwnd, (LPARAM)&amp;cds);
  </code></pre>