【问题标题】:Use WM_COPYDATA to send data between processes使用 WM_COPYDATA 在进程之间发送数据
【发布时间】:2011-01-27 21:50:33
【问题描述】:

我希望在进程之间发送文本。我找到了很多这样的例子,但没有一个我可以开始工作。这是我目前所拥有的:

对于发送部分:

COPYDATASTRUCT CDS;
CDS.dwData = 1;
CDS.cbData = 8;
CDS.lpData = NULL;
SendMessage(hwnd, WM_COPYDATA , (WPARAM)hwnd, (LPARAM) (LPVOID) &CDS);

接收部分:

case WM_COPYDATA:
COPYDATASTRUCT* cds = (COPYDATASTRUCT*) lParam;

我不知道如何构建COPYDATASTRUCT,我刚刚放入了一些似乎可以工作的东西。在调试WM_COPYDATA 的情况下执行时,我又不知道如何处理COPYDATASTRUCT

我想在两个进程之间发送文本。

您可能会说我刚刚开始,我在 Code::Blocks 中使用 GNU GCC 编译器,我试图避免 MFC 和依赖项。

【问题讨论】:

    标签: c++ windows ipc wm-copydata


    【解决方案1】:

    这不是真正的答案,而是调试时有用的提示SendMessage(WM_COPYDATA...

    Microsoft Spy++ 可能真的会派上用场。 你可以在这里找到它:

    c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\spyxx_amd64.exe
    c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\spyxx.exe
    
    1. 测试它是否在目标进程(窗口)[ctrl+f,Windows] 上运行。
    2. WM_COPYDATA 上的第二组消息过滤器。 ...和
    3. 'View\Always on top' 也很方便。

    快乐的 C++'ing - 特别是在 C# 中,API 可以是真正的“有趣”。 ;)

    【讨论】:

      【解决方案2】:
      Use the following code.
      
      //Message Sender Class( for the demonstration purpose put the following code in //button click event)
          CString strWindowTitle= _T("InterProcessCommunicationExample");
          CString dataToSend =_T("Originate from Windows");
      
          LRESULT copyDataResult;
          CWnd *pOtherWnd=CWnd::FindWindowW(NULL, strWindowTitle);
      
          if(pOtherWnd)
          {
              COPYDATASTRUCT cpd;
              cpd.dwData=0;
              cpd.cbData=dataToSend.GetLength();
              //cpd.cbData=_tcslen(dataToSend)+1;
              cpd.lpData=(void*)dataToSend.GetBuffer(cpd.cbData);
              AfxMessageBox((LPCTSTR)cpd.lpData);
              //cpd.lpData=(void*)((LPCTSTR)cpd.cbData);
              copyDataResult=pOtherWnd->SendMessage(WM_COPYDATA,(WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),(LPARAM) &cpd);
      
              dataToSend.ReleaseBuffer();
      
      
          }
          else
          {
              AfxMessageBox(L"Hwllo World");
      
          }
      
      
      //Message Receiver Process
      BOOL CMessageReceiverClass::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
      {
          CString copiedData=(LPCTSTR)(pCopyDataStruct->lpData);
          AfxMessageBox((LPCTSTR)(pCopyDataStruct->lpData));
      //  return CDialog::OnCopyData(pWnd, pCopyDataStruct);
          return TRUE;
      }
      

      【讨论】:

      • 这是 MFC 应用程序的正确解决方案。否则,目标应用程序不会响应“OnCopyData”回调函数。
      【解决方案3】:

      有关如何使用消息的示例,请参阅http://msdn.microsoft.com/en-us/library/ms649009(VS.85).aspx。您可能还想查看http://www.flounder.com/wm_copydata.htm

      dwData 成员由您定义。把它想象成你要定义的数据类型枚举。它是你想用来识别数据是这样那样的字符串的任何东西。

      cbData 成员是lpData 指向的数据的大小(以字节为单位)。在您的情况下,它将是字符串的大小(以字节为单位)。

      lpData 成员指向您要复制的数据。

      所以,要传输单个字符串....

      LPCTSTR lpszString = ...;
      COPYDATASTRUCT cds;
      cds.dwData = 1; // can be anything
      cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
      cds.lpData = lpszString;
      SendMessage(hwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)(LPVOID)&cds);
      

      然后,接收它....

      COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
      if (pcds->dwData == 1)
      {
          LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
          // do something with lpszString...
      }
      

      【讨论】:

      • 我知道第二个链接(到 flounder.com)使用 MFC,但您没有使用它,但我包含它只是为了说明您应该考虑传递的不仅仅是一个简单的字符串。跨度>
      • 谢谢,我搞定了。虽然我不得不将第一行更改为 LPTSTR lpszString 因为我收到了这个错误:invalid conversion from const void*' to void*'
      • 这个链接很有帮助:code.msdn.microsoft.com/windowsdesktop/…
      • 我可能会迟到,但您能解释一下为什么要将 &cds 投射到 LPVOID 上吗?
      • @Sossenbinder 这很公平——我想这不是真的必要,因为cds 会在堆栈上。演员阵容存在的原因有两个:(1)问题中存在。 (2) 强制转换确保它是一个远指针,这对于 16 位代码很重要:如果 cds 在数据段而不是堆栈段中,它可能是一个近指针。我想,现在额外的演员阵容基本上是历史的遗迹。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 2020-01-06
      相关资源
      最近更新 更多