Используйте WM_COPYDATA для отправки данных между процессами - PullRequest
18 голосов
/ 16 марта 2010

Я хочу отправить текст между процессами. Я нашел много примеров этого, но ни одного, на котором я мог бы работать. Вот что у меня есть:

для отправляющей части:

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.

Я хотел бы отправить текст между двумя процессами.

Как вы, вероятно, можете сказать, я только начинаю, я использую компилятор GNU GCC в Code :: Blocks, я пытаюсь избежать MFC и зависимостей.

Ответы [ 3 ]

20 голосов
/ 16 марта 2010

Пример использования сообщения см. http://msdn.microsoft.com/en-us/library/ms649009(VS.85).aspx.. Вы также можете посмотреть http://www.flounder.com/wm_copydata.htm.

Член dwData определен вами. Думайте об этом как о типе данных enum, который вы можете определить. Это то, что вы хотите использовать для определения того, что данные являются такой-то строкой.

Член 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...
}
2 голосов
/ 02 августа 2015
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;
}
1 голос
/ 15 октября 2015

Это не совсем ответ, но полезный совет при отладке 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 ++ - особенно в C #, этот API может быть действительно "забавным". ;)

...