第十七章、进程间的通信

第十七章、进程间的通信

//每个进程拥有的4GB空间是私有的,一个进程不能访问另一个进程地址空间中的数据,这里介绍4种进程间的通信方式:剪贴板、匿名管道、命名管道、邮槽。

17.1剪贴板

//先建立一个对话框应用程序,命名为Clipboard,然后添加如图所示的控件。实现的基本功能就是向左边编辑框输入数据,单击发送按钮,将数据发送到剪切板上;单击接收按钮,从剪切板上面取出数据,并在右边的编辑框中显示出来。
在这里插入图片描述

17.1.1数据发送

//数据放到剪贴板之前,首先得打开剪切板,利用CWnd类的OpenClipboard成员函数完成。

BOOL OpenClipboard(
  HWND hWndNewOwner   // handle to window opening clipboard
);

//返回值为非0表示打开剪切板操作成功;返回0表示当前窗口已经打开了剪切板。CloseClipboard表示关闭剪切板;EmptyClipboard表示清空剪切板。SetClipboardData表示向剪切板上面放置数据。

HANDLE SetClipboardData(
  UINT uFormat, // clipboard format
  HANDLE hMem   // data handle
);

//第一个参数指定剪切板的格式,因为将传输文本数据,所以选择CF_TEXT格式;第二个参数指定格式的数据的句柄,该参数可以是NULL,窗口直到有对剪切板数据的请求时,才提供剪切板格式的数据。如果窗口采用延迟提交技术,则窗口必须处理WM_READERFORMAT和WM_READERALLFORMATS消息。

//如果hMen参数标识了一个内存对象,那么这个对象必须是利用GWEN_MOVEABLE标志调用GlobalAlloc函数为其分配内存

HGLOBAL GlobalAlloc(
  UINT uFlags,    // allocation attributes
  DWORD dwBytes   // number of bytes to allocate
);

//第一个参数是一个标记,用来指定分配内存的方式;第二个参数指定分配的字节数。
//GlobalLock函数的作用就是对全局内存对象加锁,然后返回该对象内存块第一个字节的指针

LPVOID GlobalLock(
  HGLOBAL hMem   // handle to the global memory object
);

//每个内存对象的内部数据结构都包含了一个初始值为0的锁计数,GlobalLock函数将其锁计数加一,而GlobalUnLock将其锁计数减一。被锁定内存对象的的内存块将保持锁定,直到它的锁计数为0这是内存块才能被移动或者废弃。另外已被加锁的内存不能移动或者废弃,除非调用了GlobalRealloc函数重新分配了该内存对象。
//使用GMEN_FIXED标志分配的内存对象其锁计数为0,如果一个函数采用HGLOBAL类型的参数,为了保证安全,我们就应该用GMEM_MOVEABLE标志调用GlobalAlloc函数来生成这个参数值。

//双击对话框上面的发送按钮,为该按钮创建单击命令响应函数:OnBtnSend,在该函数中实现向剪切板发送数据的功能。

void CClipboardDlg::OnBtnSend() 
{
 // TODO: Add your control notification handler code here
 if(OpenClipboard())//打开剪切板
 {
  CString str;
  HANDLE hClip;
  char *pBuf;
  //清空剪切板
  EmptyClipboard();
  GetDlgItemText(IDC_EDIT_SEND,str);
  //给内存对象分配内存
  hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);
  //给内存对象加锁
  pBuf=(char*)GlobalLock(hClip);
  strcpy(pBuf,str);
  //给内存对象解锁
  GlobalUnlock(pBuf);
  //在剪切板放置数据
  setClipboard(CF_TEXT,hClip);
  //关闭剪切板
  CloseClipboard();
 }
}

//运行后,输入数据,点击发送按钮,然后选择打开一个文件粘贴,就出现了刚刚发送的数据。
在这里插入图片描述

7.1.2数据接收

//同样地双击接收按钮,添加相应的命令消息响应函数,完后完成从剪切板接收数据的功能:

void CClipboardDlg::OnBtnRecv() 
{
 // TODO: Add your control notification handler code here
 if(OpenClipboard())//打开剪切板
 {
  if(IsClipboardFormatAvailable(CF_TEXT))
  {
   HANDLE hClip;
   char *pBuf;
   hClip=GetClipboardData(CF_TEXT);
            //将句柄转换成地址
   pBuf=(char*)GlobalLock(hClip);
   GlobalUnlock(hClip);
   SetDlgItemText(IDC_EDIT_RECV,pBuf);
  }
  CloseClipboard();
 }
}

//接收端这时不应该调用EmptyClipboard函数,因为这时是从剪切板中得到数据;在获得数据之前,先看一下剪贴板中是否有我们想要的特定格式的数据,通过调用GetClipboardData函数实现。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值