`
isiqi
  • 浏览: 16053844 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Visual C++进程间数据通信的实现

阅读更多

Visual C++进程间数据通信的实现

2006-01-19 08:43 作者: 刘涛 出处: 天极开发 责任编辑:方舟
  在Windows系统中,各个应用程序(进程)之间常常需要交换、传递数据,这就要解决进程间的数据通信问题。在最初的16位Windows3.x系统中,所有Windows应用程序共享单一地址,任何进程都能够对这一共享地址空间的数据进行读写操作。随着Windwos98、WindowsNT、Windows2000等32位的操作系统的出现,规定每个进程都有自己的地址空间,一个Windows进程不能存取另一个进程的私有数据,也就是说,虽然两个进程可以用具有相同值的指针寻址,但所读写的只是它们各自的数据,这样就减少了进程之间的相互干扰。那么上述技术的采用是否意味着各个应用程序之间不能进行数据交换了呢?答案当然是否定的,强大的Windows系统早已为我们设计了很多方案来解决进行间的通信问题,这里我们只探讨如何通过动态数据交换(DDE)方法实现进程间的数据通信。

  本实例程序功能如下,服务器端有两个数据项,一个是输入的字符串,另一个是定时增加的整数。运行该程序的两个实例后,两个程序就可以建立DDE连接,实现数据的传递,并将另外一个实例传送过来的数据显示出来。下图为程序编译运行后的效果图:


图一、DDE方法实现进程间数据通信程序的界面效果图

  一、实现方法

  自从微软推出Windows操作系统以来,动态数据交换(DDE)就已经成为Windows的部分,并且很多Windwos应用程序都使用了DDE技术来实现进程之间的数据交换。DDE是建立在Windows内部消息系统、全局和共享全局内存基础上的一种协议,用来协调Windows应用程序之间的数据交换和命令调用,它已经成为应用程序之间通信的一种常用方法。

  DDE应用程序可以分为四种类型:客户类型、服务器类型、客户/服务器类型和监视器。DDE会话发生在客户应用程序和服务器应用程序之间。客户应用程序从服务器应用程序请求数据或服务,服务器应用程序响应客户应用程序的数据或服务请求。客户/服务器应用程序是既可以发出请求,又可以提供信息,监视器应用程序则是用语调试的目的。

  DDE协议使用三级树型命名:服务(SERVICE)、主题(TOPIC)和数据项(ITEM)来标识DDE所要传送的数据单元。服务使应用程序具有了提供给其他程序的数据交换能力;主题类似于目录,是建立会话连接的参数:ITEM才是DDE具体通信时要传送的数据内容,比如一个数据或一个字符串。

  动态交换管理库(DDEML)提供了DDE和应用程序级协议。使用DDEML开发的应用程序无论是在运行一致性方面还是在应用程序相互通信方面性能均优于没有使用DDEML的应用程序。而且DDEML的应用使得开发支持DDE的应用程序容易了许多。

  建立DDE会话后,客户程序和服务器程序可以通过三种链接方式进行数据交换,分别是:1、冷链接:客户程序申请数据,服务器程序立即给客户程序发送数据;2、温链接:服务器程序通知客户程序数据数据项发生了改变,但是并没有将已发生的值发送给客户程序。3、热链接:当数据项发生变化时,服务器程序立即把变化后的值发送给客户程序,这是最常用、最方便的方法,下面的例子就使用的这种方法。

  DDE会话初始化

  使用API函数DdeInitialize(),在DDEML中注册应用。

  会话建立

  服务器:注册服务DdeNameService.

  客户:连接DdeConnect.

  会话过程

  类似于Windows的消息循环,会话的过程就是事务处理的过程。客户通过DdeClientTransaction()来发出事务请求,通过DDE回调函数,服务器处理客户事务请求,返回DdeCreateDataHandle来发送数据,同时客户可以调用DdeGetData()获取数据。

  会话结束

  可由服务方或客户方来终止会话,推出程序时要注消服务,释放资源,调用DdeUninitialize()。

  二、编程步骤

  1、启动Visual C++6.0,新建一个基于对话框的MFC应用程序,取名为DDEdemo,添加两个Group Box控件并分别在其上放置编辑控件IDC_EDIT、静态控件ID_STATIC1、ID_STATIC2、 ID_STATIC3,用Wizard添加对应成员变m_edit(CString类型),添加并将其Caption置空,最后的界面如图一所示;

  2、使用CLASSWIZARD添加对话框函数,分别为WM_DESTORY、WM_INITDIALOG、WM_TIMER及IDC_EDIT的EN_CHANGE消息建立对应函数;

  3、在DDEdemoDlg.CPP中加入#include "ddel.h"以使用DDEML函数。并添加以下宏定义和全局变量:

#define NITEM 2 //定义ITEM的数量;
const char szApp[]="Server"; //server DDE服务名;
const char szTopic[]="Topic";//Server DDE目录名;
const char *pszItem[NITEM]={"Item1","Item2"};//SERVER ITEM名称字符串数组;
int count=0;//记数,在Static1中显示;
CString ServerData[NITEM];//存放服务器中的数据项内容;
HCONV hConv=0; //会话句柄;
DWORD idlnst=0; //DDEML实例句柄;
HWND hWnd; //窗口句柄;
HANDLE hlnst; //实例句柄;
HSZ hszApp=0; //SERVER服务字符串句柄;
HSZ hszTopic=0; //SERVER目录字符串句柄;
HSZ hszItem[NITEM]; //Server ITEM字符串句柄;
BOOL bConnect; // 建立连接标志;

  4、输入代码,编译运行程序。
三、程序代码

//////////////////////////////////////DDE回调函数;
HDDEDATA CALLBACK DdeCallback(UINT wType,UINT wFmt,HCONV hConv,HSZ Topic,HSZ Item,
HDDEDATA hData,DWORD lData1,DWORD lData2)
{
 int I ;
 char tmp[255];
 switch(wType)
 {
  case XTYP_ADVSTART:
  case XTYP_CONNECT://请求连接;
   return ((HDDEDATA)TRUE);//允许;
  case XTYP_ADVDATA: //有数据到来;
   for(I=0;I<NITEM;I++)
    if(Item==hszItem[I])
    {
     DdeGetData(hData,(PBYTE)tmp,255,0);//取得数据;
     switch(I)
     {
      case 0:
       SetDlgItemText(hWnd,IDC_STATIC2,tmp);
       break;
      case 1:
       SetDlgItemText(hWnd,IDC_STATIC3,tmp);
       break;
     }
    }
   return ((HDDEDATA)DDE_FACK);//回执;
  case XTYP_ADVREQ:
  case XTYP_REQUEST://数据请求;
   for(I=0;I<NITEM;I++)
    if(Item==hszItem[I])
     return(DdeCreateDataHandle(idlnst,(PBYTE)(LPCTSTR)ServerData[I],
       ServerData[I].GetLength()+1,0,Item,wFmt,0));
 }
 return(0);
}

///////////////////////////////////////////////////// CddedemoDlg.cpp
CDdedemoDlg::CDdedemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDdedemoDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CDdedemoDlg)
  m_edit = _T("");
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDdedemoDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CDdedemoDlg)
  DDX_Text(pDX, IDC_EDIT1, m_edit);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDdedemoDlg, CDialog)
//{{AFX_MSG_MAP(CDdedemoDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_WM_TIMER()
 ON_WM_DESTROY()
 ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////////////////////////////CDdedemoDlg message handlers
BOOL CDdedemoDlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 // Add "About..." menu item to system menu.
 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 // TODO: Add extra initialization here
 hWnd=m_hWnd;
 if (DdeInitialize(&idlnst,(PFNCALLBACK)DdeCallback,APPCMD_FILTERINITS|
CBF_FAIL_EXECUTES|CBF_SKIP_CONNECT_CONFIRMS|CBF_FAIL_SELFCONNECTIONS|
CBF_FAIL_POKES,0))
 {
  MessageBox("DDE SERVER初始化失败!");
  return FALSE;
 }
 hlnst=AfxGetApp()->m_hInstance;
 //创建DDE string
 hszApp=DdeCreateStringHandle(idlnst,szApp,0);
 hszTopic=DdeCreateStringHandle(idlnst,szTopic,0);
 for(int I=0;I<NITEM;I++)
  hszItem[I]=DdeCreateStringHandle(idlnst,pszItem[I],0);
  //注册服务;
  DdeNameService(idlnst,hszApp,0,DNS_REGISTER);
  bConnect=FALSE;
  SetTimer(1,1000,NULL);//开始定时;
  return TRUE; // return TRUE unless you set the focus to a control
}

void CDdedemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDdedemoDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;
  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDdedemoDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CDdedemoDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 count++;
 ServerData[1].Format("%d",count);
 SetDlgItemText(IDC_STATIC1,ServerData[1]);
 DdePostAdvise(idlnst,hszTopic,hszItem[1]);//通知更新;
 if(!bConnect)//如果没有建立连接
 {
  hConv=DdeConnect(idlnst,hszApp,hszTopic,NULL);
  //连接服务器端;
  if(hConv) //如果建立成功
  {
   DWORD dwResult;
   bConnect=TRUE;
   for(int I=0;I<NITEM;I++)
    DdeClientTransaction(NULL,0,hConv,hszItem[I],CF_TEXT,XTYP_ADVSTART,
TIMEOUT_ASYNC,&dwResult);
  }
 }
 CDialog::OnTimer(nIDEvent);
}

void CDdedemoDlg::OnDestroy()
{
 CDialog::OnDestroy();
 // TODO: Add your message handler code here
 KillTimer(1);//销毁定时;
 DdeNameService(idlnst,0,0,DNS_UNREGISTER);//注销服务;
 DdeFreeStringHandle(idlnst,hszApp);
 DdeFreeStringHandle(idlnst,hszTopic);
 for(int I=0;I<NITEM;I++)
  DdeFreeStringHandle(idlnst,hszItem[I]);
  DdeUninitialize(idlnst);
}

void CDdedemoDlg::OnChangeEdit1()
{
 // TODO: If this is a RICHEDIT control, the control will not
 // send this notification unless you override the CDialog::OnInitDialog()
 // function and call CRichEditCtrl().SetEventMask()
 // with the ENM_CHANGE flag ORed into the mask.
 // TODO: Add your control notification handler code here
 UpdateData();
 ServerData[0]=m_edit;
 DdePostAdvise(idlnst,hszTopic,hszItem[0]); //通知DDE更新该数据项目;
}

  四、小结

  Windows提供了很多方法来实现进程之间的通信,相互传递数据,如通过系统剪贴板方法、共享DLL方法、管道方法等,这些方法的存在保证了程序的健壮性和鲁棒性(稳定性),有兴趣的读者可以自行参考有关资料。
三、程序代码

//////////////////////////////////////DDE回调函数;
HDDEDATA CALLBACK DdeCallback(UINT wType,UINT wFmt,HCONV hConv,HSZ Topic,HSZ Item,
HDDEDATA hData,DWORD lData1,DWORD lData2)
{
 int I ;
 char tmp[255];
 switch(wType)
 {
  case XTYP_ADVSTART:
  case XTYP_CONNECT://请求连接;
   return ((HDDEDATA)TRUE);//允许;
  case XTYP_ADVDATA: //有数据到来;
   for(I=0;I<NITEM;I++)
    if(Item==hszItem[I])
    {
     DdeGetData(hData,(PBYTE)tmp,255,0);//取得数据;
     switch(I)
     {
      case 0:
       SetDlgItemText(hWnd,IDC_STATIC2,tmp);
       break;
      case 1:
       SetDlgItemText(hWnd,IDC_STATIC3,tmp);
       break;
     }
    }
   return ((HDDEDATA)DDE_FACK);//回执;
  case XTYP_ADVREQ:
  case XTYP_REQUEST://数据请求;
   for(I=0;I<NITEM;I++)
    if(Item==hszItem[I])
     return(DdeCreateDataHandle(idlnst,(PBYTE)(LPCTSTR)ServerData[I],
       ServerData[I].GetLength()+1,0,Item,wFmt,0));
 }
 return(0);
}

///////////////////////////////////////////////////// CddedemoDlg.cpp
CDdedemoDlg::CDdedemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDdedemoDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CDdedemoDlg)
  m_edit = _T("");
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDdedemoDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CDdedemoDlg)
  DDX_Text(pDX, IDC_EDIT1, m_edit);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDdedemoDlg, CDialog)
//{{AFX_MSG_MAP(CDdedemoDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_WM_TIMER()
 ON_WM_DESTROY()
 ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////////////////////////////CDdedemoDlg message handlers
BOOL CDdedemoDlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 // Add "About..." menu item to system menu.
 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 // TODO: Add extra initialization here
 hWnd=m_hWnd;
 if (DdeInitialize(&idlnst,(PFNCALLBACK)DdeCallback,APPCMD_FILTERINITS|
CBF_FAIL_EXECUTES|CBF_SKIP_CONNECT_CONFIRMS|CBF_FAIL_SELFCONNECTIONS|
CBF_FAIL_POKES,0))
 {
  MessageBox("DDE SERVER初始化失败!");
  return FALSE;
 }
 hlnst=AfxGetApp()->m_hInstance;
 //创建DDE string
 hszApp=DdeCreateStringHandle(idlnst,szApp,0);
 hszTopic=DdeCreateStringHandle(idlnst,szTopic,0);
 for(int I=0;I<NITEM;I++)
  hszItem[I]=DdeCreateStringHandle(idlnst,pszItem[I],0);
  //注册服务;
  DdeNameService(idlnst,hszApp,0,DNS_REGISTER);
  bConnect=FALSE;
  SetTimer(1,1000,NULL);//开始定时;
  return TRUE; // return TRUE unless you set the focus to a control
}

void CDdedemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDdedemoDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;
  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDdedemoDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CDdedemoDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 count++;
 ServerData[1].Format("%d",count);
 SetDlgItemText(IDC_STATIC1,ServerData[1]);
 DdePostAdvise(idlnst,hszTopic,hszItem[1]);//通知更新;
 if(!bConnect)//如果没有建立连接
 {
  hConv=DdeConnect(idlnst,hszApp,hszTopic,NULL);
  //连接服务器端;
  if(hConv) //如果建立成功
  {
   DWORD dwResult;
   bConnect=TRUE;
   for(int I=0;I<NITEM;I++)
    DdeClientTransaction(NULL,0,hConv,hszItem[I],CF_TEXT,XTYP_ADVSTART,
TIMEOUT_ASYNC,&dwResult);
  }
 }
 CDialog::OnTimer(nIDEvent);
}

void CDdedemoDlg::OnDestroy()
{
 CDialog::OnDestroy();
 // TODO: Add your message handler code here
 KillTimer(1);//销毁定时;
 DdeNameService(idlnst,0,0,DNS_UNREGISTER);//注销服务;
 DdeFreeStringHandle(idlnst,hszApp);
 DdeFreeStringHandle(idlnst,hszTopic);
 for(int I=0;I<NITEM;I++)
  DdeFreeStringHandle(idlnst,hszItem[I]);
  DdeUninitialize(idlnst);
}

void CDdedemoDlg::OnChangeEdit1()
{
 // TODO: If this is a RICHEDIT control, the control will not
 // send this notification unless you override the CDialog::OnInitDialog()
 // function and call CRichEditCtrl().SetEventMask()
 // with the ENM_CHANGE flag ORed into the mask.
 // TODO: Add your control notification handler code here
 UpdateData();
 ServerData[0]=m_edit;
 DdePostAdvise(idlnst,hszTopic,hszItem[0]); //通知DDE更新该数据项目;
}

  四、小结

  Windows提供了很多方法来实现进程之间的通信,相互传递数据,如通过系统剪贴板方法、共享DLL方法、管道方法等,这些方法的存在保证了程序的健壮性和鲁棒性(稳定性),有兴趣的读者可以自行参考有关资料。

分享到:
评论

相关推荐

    进程间通过剪贴板进行消息通信.visual c++

    多进程间通信通过剪贴板进行消息通信.rar

    visual c++ MFC之Lesson17进程间通信

    visual c++ MFC之Lesson17进程间通信

    Visual C++ 进程与线程

    Visual C++ 进程与线程 相关源代码,涵盖终止当前进程,获取系统进程,终止指定进程,在程序中启动程序,使用事件对象同步进程,在两个执行程序间进行数据通信,使用工作线程,正常终止线程,异常终止进程,使用线程...

    VC利用管道和多线程实现进程间通信

    visual c++利用管道和线程实现进程间通信

    通过共享内存实现多进程间的通信,共享数据

    visual c++ vc通过共享内存实现多进程间的通信,共享数据

    Visual C++2010开发权威指南(共三部分).part1.rar

    第一部分 Visual C++ 2010开发与新特性 第1章 Visual C++ 2010开发环境简介 1 1.1 Visual C++ 2010简介 1 1.2 Visual C++ 2010下载安装指南 1 1.3 Visual C++ 2010主要特点与新特性 3 1.4 Visual C++ 2010开发环境...

    《Visual C++范例大全》随书光盘 第十一章

    第11章 实例257——使用Win32 API创建、销毁线程(控制进度条) 实例258——创建MFC用户界面线程 实例259——创建MFC工作者线程,进行耗时计算 实例260——设置线程的... 实例277——通过消息机制实现进程间的通信

    Visual C++实践与提高——串口通信与工程应用篇1

    9.3 通信实现思路 234 9.3.1 功能描述 234 9.3.2 通信事件的处理方法 235 9.3.3 各种操作状态的含义 235 9.4 界面设计 237 9.4.1 主界面设计 237 9.4.2 设置对话框设计 238 9.5 程序设计 239 9.5.1 变量/函数声明 ...

    Visual C++2010开发权威指南.part07

    16.1.9 进程间通信的示例 632 16.4 命名管道通信 637 16.4.1 CreateNamedPipe()函数 637 16.4.2 ConnectNamedPipe()函数 639 16.4.3 DisconnectNamedPipe() 16.1.9 函数 640 16.4.4 WaitNamedPipe()函数 640 16.4.5 ...

    Visual C++程序开发范例宝典(光盘) 第八部分

    实例052 在ListBox控件间实现数据交换 实例053 列表项的提示条 2.4 ComboBox控件典型实例 实例054 将数据表中的字段添加到ComboBox控件 实例055 带查询功能的ComboBox控件 实例056 自动调整组合框的宽度 实例...

    Visual C++通用范例开发金典(第三卷/共三卷)

    注:第一卷的描述写错了,总共是三卷压缩包 Visual C++通用范例开发... 10.3 进程间通信  10.4 本章小结  第11章 动态链接库和ActiveX控件  11.1 动态链接库  11.2 ActiveX控件  11.3 本章小结  索引  参考文献

    VISUAL C++MFC扩展编程实例

    3.1 进程间通信 43 3.1.1 通信策略 43 3.1.2 同步和异步通信 44 3.2 窗口消息 44 3.2.1 打开和关闭 44 3.2.2 读与写 45 3.2.3 回顾 45 3.3 动态数据交换 46 3.3.1 客户/服务器 46 3.3.2 打开和关闭 46 3.3.3 读和写 ...

    VISUAL C++MFC编程实例

    本书通过85个实例全面讲述了应用MFC进行Visual C++编程的思想。每个实例均以编写一个应用程序要走的步骤编写。全书共分四部分进行介绍,第一部分是基础知识,第二部分讲述用户界面的实例,第三部分讲述MFC内部处理...

    Visual C++通用范例开发金典(第一卷、共两卷)

    Visual C++通用范例开发金典(附光盘)/开发专家 ... 10.3 进程间通信  10.4 本章小结  第11章 动态链接库和ActiveX控件  11.1 动态链接库  11.2 ActiveX控件  11.3 本章小结  索引  参考文献

    Visual C++通用范例开发金典(分卷二/共三卷)

    注:分卷一的说明写错了,总共三卷压缩包 Visual C++通用范例开发... 10.3 进程间通信  10.4 本章小结  第11章 动态链接库和ActiveX控件  11.1 动态链接库  11.2 ActiveX控件  11.3 本章小结  索引  参考文献

    Visual C++编程技巧精选500例.pdf

    181 如何在两个执行程序间进行数据通信? 182 如何使用工作线程? 183 如何正常终止线程? 184 如何异常终止线程? 185 如何获取线程退出码? 186 如何使用线程优先级? 187 如何使用用户界面线程? 188 如何实现多线程多...

    利用sendMessage实现进程间通信

    来源 visual c++开发范例,IDE:vs2010. 分为 a.server(接收消息,显示接收到的数值). b.client(打开server进程,向server主窗体发送消息). //得到主窗口 HWND CMyJC006ClientDlg::GetServerMainWnd() { HWND hWnd; ...

    源码+电子书本Visual C++ MFC编程实例

    13.4 例66 在数据类中实现串行化 229 13.5 例67 串行化SDI或MDI文档 235 13.6 例68 按要求串行化 240 13.7 例69 透明地更新串行化的文档 242 13.8 例70 串行化多态类 246 13.9 例71 串行化数据集 248 13.10 例72 ...

Global site tag (gtag.js) - Google Analytics