zoukankan      html  css  js  c++  java
  • 进程间通信最简单的方式就是发送WM_COPYDATA消息

    发送WM_COPYDATA消息:

    SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)&CopyData);

    其中的CopyData为COPYDATASTRUCT结构类型,该结构定义如下:

    typedef struct tagCOPYDATASTRUCT {

    DWORD dwData;  // Specifies data to be passed to the receiving application.

    DWORD cbData;  //Specifies the size, in bytes, of the data pointed to by the lpData member.

     PVOID lpData;    // Pointer to data to be passed to the receiving application. can be NULL.

    } COPYDATASTRUCT, *PCOPYDATASTRUCT;

     

    注意:该消息只能由SendMessage()来发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。此外如果lpData指向一个带有指针或某一拥有虚函数的对象时,也要小心处理。

    如果传入的句柄不是一个有效的窗口或当接收方进程意外终止时,SendMessage()会立即返回,因此发送方在这种情况下不会陷入一个无穷的等待状态中。

    返回值问题,MSDN上说如果接收方处理了,返回TRUE,否则返回FALSE,但是本人在实验时,都是返回0(接收方已经处理)。

    接收WM_COPYDATA消息:

    只要用COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;就可以了。接收方应认为这些数据是只读的。

    由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待中,所以接收方应当尽快处理WM_COPYDATA消息。

    以一个简单的例子来说明如何使用WM_COPYDATA消息,有二个程序,一个用来发送表示当前时间信息的字符串,另一个接收数据后显示到编辑框中。例子中有几点要注意:

    1.如何得到当前控制台窗口句柄?VS2008下可以直接使用HWND GetConsoleWindow(void);函数。

    2.使用char *ctime(const time_t *timer);将一个time_t类型转化成一个字符串时,函数会在字符串末尾加下'\n',因为发送前要将这个'\n'去掉。

    发送消息的程序代码(VS2008下编译通过):

    #include <windows.h>

    #include <time.h>

    #include <conio.h>

    #include <stdio.h>

    int main()

    {

           const char szDlgTitle[] = "RecvMessage";

     

           HWND hSendWindow = GetConsoleWindow ();

           if (hSendWindow == NULL)

                  return -1;

           HWND hRecvWindow = FindWindow(NULL, szDlgTitle);

           if (hRecvWindow == NULL)

                  return -1;

     

           char szSendBuf[100];

           time_t  timenow;

           COPYDATASTRUCT CopyData;

     

           for (int i = 0; i < 10; i++)

           {

                  time(&timenow);

                  sprintf(szSendBuf, "%s", ctime(&timenow));//注意,ctime()返回的字符串后面带了'\n'

                  CopyData.dwData = i;

                  CopyData.cbData = strlen(szSendBuf);

                  szSendBuf[CopyData.cbData - 1] = '\0';

                  CopyData.lpData = szSendBuf;

     

                  SendMessage(hRecvWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)&CopyData);

                  printf("%s\n", szSendBuf);

                  Sleep(1000);

           }

           return 0;

    }

    接收消息程序代码(VC6.0下编译通过):

    程序中的IDC_EDIT_RECVMESSAGE为编辑框的ID。

    #include "stdafx.h"

    #include "resource.h"

    #include <stdio.h>

    BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

    int APIENTRY WinMain(HINSTANCE hInstance,

                         HINSTANCE hPrevInstance,

                         LPSTR     lpCmdLine,

                         int       nCmdShow)

    {

          // TODO: Place code here.

           DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);

           return 0;

    }

    BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

    {

           const char szDlgTitle[] = "RecvMessage";

           static HWND s_hEditShowRecv;

     

           switch (message)

           {

           case WM_INITDIALOG:

                  SetWindowText(hDlg, szDlgTitle);

                  s_hEditShowRecv = GetDlgItem(hDlg, IDC_EDIT_RECVMESSAGE);

                  return TRUE;

     

           case WM_COMMAND:

                  switch (LOWORD(wParam))

                  {

                  case IDOK:

                  case IDCANCEL:

                         EndDialog(hDlg, LOWORD(wParam));

                         return TRUE;

                  }

                  break;

     

           case WM_COPYDATA:

                  {

                         COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;

                         char szBuffer[300];

     

                         memset(szBuffer, 0, sizeof(szBuffer));

                         sprintf(szBuffer, "dwData:%d cbData:%d\r\nlpData:0x%08x = %s\r\n\r\n",

                                pCopyData->dwData, pCopyData->cbData,

                                (PVOID)pCopyData->lpData, (char*)pCopyData->lpData);

                         //在编辑框中追加数据

                         SendMessage(s_hEditShowRecv, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); // (0, -1)表示全选, (-1,任意)表示全不选

                         SendMessage(s_hEditShowRecv, EM_REPLACESEL, FALSE, (LPARAM)szBuffer);

                         SendMessage(s_hEditShowRecv, EM_SCROLLCARET, 0, 0);

                  }

                  return TRUE;

           }

           return FALSE;

    }

  • 相关阅读:
    Java DbUtils简介
    Java JDBC 操作二进制数据、日期时间
    Java JDBC事务
    Java JDBC结果集的处理
    Java 使用properties配置文件加载配置
    Java JDBC的使用
    CSS3
    CSS 基础样式
    CSS 样式的使用方式、选择器
    HTML 表单
  • 原文地址:https://www.cnblogs.com/fwycmengsoft/p/6642871.html
Copyright © 2011-2022 走看看