Windows平台下进程间通信的方式:剪切板、匿名管道、命名管道、邮槽。
实际上socket网络通信就是在两个进程之间的通信,需了解相关的网络协议。
一、剪切板
剪切板是所有进程都可以访问的。
发送端编写:
打开剪切板:
BOOL OpenClipboard( );
打开剪切板后其它应用程序不能修改剪切板,直到调用了BOOL CloseClipboard(void);
BOOL EmptyClipboard(void);获取剪切板。清空剪切板并释放剪切板中的句柄,将使用权给当前打开剪切板的窗口。
然后向剪切板中放置数据:
HANDLE SetClipboardData(
UINT uFormat,
HANDLE hMem
);
窗口延迟提交,必须响应这两个消息:WM_RENDERFORMAT andWM_RENDERALLFORMATS。
当一个提供数据的进程创建了剪切板数据之后,到有其它进程获取剪切板数据之前,这些数据都要占据内存空间,如果在剪切板上放置的数据量过大,就会浪费内存空间,降低对资源的利用率,为了避免这种浪费,我们就可以采取延迟提交的技术,也就是由数据提供进程,
先创建一个指定数据的格式的空剪切板数据块(将第二个参数设置为NULL),直到有其它进程需要数据或自身进程终止运行时,才真正提交数据。
HGLOBAL WINAPI GlobalAlloc(
__in UINT uFlags,
__in SIZE_T dwBytes
); 分配一定的内存对象。第一个参数选为:GMEM_MOVEABLE 详细参见MSDN。
LPVOID WINAPI GlobalLock(
__in HGLOBAL hMem
); 对内存对象加锁,并返回一个指针类型变量。
BOOL WINAPI GlobalUnlock(
__in HGLOBAL hMem
); 对内存对象解锁,参数是句柄
接收端编写:
打开剪切板;(此时不再需要将剪切板清空了)
获取剪切板上的数据:
HANDLE GetClipboardData(
UINT uFormat
);
程序如下:
发送端:
void CClipboard1Dlg::OnBnClickedBtnSend()
{
// TODO: 在此添加控件通知处理程序代码
if(OpenClipboard( )) //打开剪切板
{
CString str;
HANDLE hClip;
TCHAR *pBuf;
EmptyClipboard(); //清空剪切板
GetDlgItemText(IDC_EDIT_SEND,str); //读取编辑框中的内容
hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()*2+2); //为数据分配内存
pBuf=(TCHAR *)GlobalLock(hClip); //锁定内存,并将返回的句柄转换为指针
//str2=str1;
_tcscpy(pBuf,(TCHAR *)(LPCTSTR)str);
GlobalUnlock(hClip); 解除内存锁定
SetClipboardData(CF_TEXT,hClip); //将指定格式的数据写入剪切板
CloseClipboard(); //关闭剪切板否则其它进程打不开剪切板
}
}
接收端:
void CChipboard2Dlg::OnBnClickedBtnRecv()
{
// TODO: 在此添加控件通知处理程序代码
if(OpenClipboard())
{
if(IsClipboardFormatAvailable(CF_TEXT)) //判断剪切板中数据是否是想要格式的数据
{
HANDLE hClip;
TCHAR *pBuf;
hClip=GetClipboardData(CF_TEXT);
pBuf=(TCHAR *)GlobalLock(hClip);
GlobalUnlock(hClip);
SetDlgItemText(IDC_EDIT_RECV,pBuf);
CloseClipboard();
}
}
}
遇到的问题:
1.VS2008在同一个窗口中如何打开两个项目进行运行?
首先打开其中一个项目,文件——>添加——>现有项目即可。
2.发送端与接收端通信时出现中文乱码问题?
原因分析:Unicode与ANSI字符关系
解决方法:对于处理包含类似中英文混合的字符时,最好使用UNICODE编译选项,然后在使用字符串常量时采用_T(“字符串”)的方式,将char型改成TCHAR,相关的字符处理函数也使用UNICODE的,这些函数可以在MDSN中查到,具体位置为:generic-text mappings -> Routine Mappings。