[乱]mfc与sdk笔记[十三]
进程间通信。剪贴板,管道,邮槽
- 剪贴板
- OpenClipboard();//打开剪贴板,别人将不能使用剪贴板。
- CloseClipboard();//关闭剪贴板
- GetClipboardData(CF_TEXT);//获得剪贴板数据
- EmptyClipboard();//清空剪贴板,释放剪贴板中的数据句柄,当前窗口成为剪贴板拥有者
- SetClipboardData();//在剪贴板上放置数据
- hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1); //全局内存,返回指针
- pBuf=(char*)GlobalLock(hClip);//全局内存加锁返回指针
- GlobalUnlock(); //全局内存解锁
-
- 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(hClip); //区域解锁
- SetClipboardData(CF_TEXT,hClip); //这块内存加载到剪贴板
- CloseClipboard(); //关闭剪贴板
- }
- //接受
- 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();
- }
- }
- 匿名管道,他们只能父子进程之间通讯
- HANDLE hRead;
- HANDLE hWrite;
- SECURITY_ATTRIBUTES sa;
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- if(!CreatePipe(&hRead,&hWrite,NULL,))//创建一个匿名管道,返回管道读写句柄
- {
- MessageBox("Create pipe fail!");
- return ;
- }
- //============================
- STARTUPINFO sui; //打开窗口的信息
- PROCESS_INFORMATION pi; //进程信息
- ZeroMemory(&sui,sizeof(STARTUPINFO)); //把内存结构设为0
- sui.cb=sizeof(STARTUPINFO); //大小
- sui.dwFlags=STARTF_USESTDHANDLES; //设置标记
- sui.hStdInput=hRead; //标准输入句柄,设为继承的管道句柄
- sui.hStdOutput=hWrite; //标准输出句柄,设为继承的管道句柄
- sui.hStdError=GetStdHandle(STD_ERROR_HANDLE); //得到父亲的标准错误句柄
- if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,
- TRUE,0,NULL,NULL,&sui,&pi))
- {
- CloseHandle(hRead); //关闭管道读取句柄
- CloseHandle(hWrite); //关闭管道写入句柄
- hRead=NULL;
- hWrite=NULL;
- MessageBox("创建子进程失败!");
- return;
- }
- else
- {
- CloseHandle(pi.hProcess); //子进程的句柄,使用技术-1
- CloseHandle(pi.hThread); //子进程线程内核对象,使用技术-1
- //不使用内核对象的时候要关闭句柄
- }
- //===========子进程=================
- char buf[100];
- DWORD dwRead;
- if(!ReadFile(hRead,buf,100,&dwRead,NULL))
- {
- MessageBox("读取数据失败!");
- return;
- }
- MessageBox(buf);
- // =======写入句柄=========
- char buf[]="匿名管道测试程序";
- DWORD dwWrite;
- if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
- {
- MessageBox("写入数据失败!");
- return;
- 命名管道
- //=======服务端=======
- //创建
- HANDLE hPipe;
- hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- 0,1,1024,1024,0,NULL);
- if(INVALID_HANDLE_VALUE==hPipe)
- {
- MessageBox("创建命名管道失败!");
- hPipe=NULL;
- return;
- }
- HANDLE hEvent;
- hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); //人工重置的事件对象
- if(!hEvent)
- {
- MessageBox("创建事件对象失败!");
- CloseHandle(hPipe);
- hPipe=NULL;
- return;
- }
- OVERLAPPED ovlap;
- ZeroMemory(&ovlap,sizeof(OVERLAPPED));
- ovlap.hEvent=hEvent;
- if(!ConnectNamedPipe(hPipe,&ovlap)) //允许一个服务进程等待一个客户端进程链接一个命名管道实例上
- {
- if(ERROR_IO_PENDING!=GetLastError())
- {
- MessageBox("等待客户端连接失败!");
- CloseHandle(hPipe);
- CloseHandle(hEvent);
- hPipe=NULL;
- return;
- }
- }
- if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))
- {
- MessageBox("等待对象失败!");
- CloseHandle(hPipe);
- CloseHandle(hEvent);
- hPipe=NULL;
- return;
- }
- CloseHandle(hEvent);
- //写入
- char buf[]="abc";
- DWORD dwWrite;
- if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
- {
- MessageBox("写入数据失败!");
- return;
- }
- //读取
- char buf[100];
- DWORD dwRead;
- if(!ReadFile(hPipe,buf,100,&dwRead,NULL))
- {
- MessageBox("读取数据失败!");
- return;
- }
- MessageBox(buf);
- //客户端
- if(!WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER)) //链接命名管道
- {
- MessageBox("当前没有可利用的命名管道实例!");
- return;
- }
- hPipe=CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ | GENERIC_WRITE,
- 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
- if(INVALID_HANDLE_VALUE==hPipe)
- {
- MessageBox("打开命名管道失败!");
- hPipe=NULL;
- return;
- }
- //读取
- char buf[100];
- DWORD dwRead;
- if(!ReadFile(hPipe,buf,100,&dwRead,NULL))
- {
- MessageBox("读取数据失败!");
- return;
- }
- MessageBox(buf);
- // 写入
- char buf[]="命名管道测试程序";
- DWORD dwWrite;
- if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
- {
- MessageBox("写入数据失败!");
- return;
- }
- 邮槽. 采用udp传输的
- //=====接收=====
- HANDLE hMailslot;
- hMailslot=CreateMailslot("\\\\.\\mailslot\\MyMailslot",0,
- MAILSLOT_WAIT_FOREVER,NULL); //一直等待直到有消息的邮槽
- if(INVALID_HANDLE_VALUE==hMailslot)
- {
- MessageBox("创建油槽失败!");
- return;
- }
- char buf[100];
- DWORD dwRead;
- if(!ReadFile(hMailslot,buf,100,&dwRead,NULL))
- {
- MessageBox("读取数据失败!");
- CloseHandle(hMailslot);
- return;
- }
- MessageBox(buf);
- CloseHandle(hMailslot);
- //=====发送=====
- HANDLE hMailslot;
- hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE,
- FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
- if(INVALID_HANDLE_VALUE==hMailslot)
- {
- MessageBox("打开油槽失败!");
- return;
- }
- char buf[]="abcd";
- DWORD dwWrite;
- if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL))
- {
- MessageBox("写入数据失败!");
- CloseHandle(hMailslot);
- return;
- }
- CloseHandle(hMailslot);
10月 8th, 2007 at 4:21 下午
在两台机子上用命名管道你用过吗?