1.继续完成进程间通信

1.1 完成 剪贴板Ctrl+c 按钮的消息处理函数

1.从 Edit 控件上往下取字符串: UpdateData(TRUE) ;
2.首先打开剪贴板: OpenClipboard() ;
3.若剪贴板有复制好的东西则我们将其进行清空: EmptyClipboard() ;
4.申请一个全局堆空间: HGLOBAL h_global = GlobalAlloc(GPTR, m_size) ;申请全局堆空间需要我们给定一个大小,我们给定的大小为我们从 Edit 控件上取下来的字符串的宽字符集大小: int m_size = (m_str_send.GetLength()+1)2 ;
5.给全剧堆加锁: wchar_t
psz_content = (wchar_t*)::GlobalLock(h_global) ;
6.把数据放到剪贴板中: memcpy(psz_content, m_str_send.GetBuffer(), m_size) ;
7.给全局堆解锁: GlobalUnlock ;
8.将全局堆交给剪贴板: SetClipboardData(CF_UNICODETEXT, h_global) ;
9.关闭剪贴板: CloseClipboard ;

void CSendDlg::OnBnClickedButton2()
{UpdateData(TRUE);int m_size = (m_str_send.GetLength()+1)*2;// 1.1 打开剪贴板if(OpenClipboard() == 0){this->MessageBox(L"打开剪贴板失败");return;}// 1.2 清空剪贴板if(EmptyClipboard() == 0){CloseClipboard();MessageBox(L"清空剪贴板失败");return;}// 1.3 分配一个全局堆空间HGLOBAL h_global = GlobalAlloc(GPTR, m_size);if(h_global == 0){CloseClipboard();MessageBox(L"分配全局堆失败");return;}// 1.4 给全局堆加锁wchar_t* psz_content = (wchar_t*)::GlobalLock(h_global);if(psz_content == 0){CloseClipboard();CloseHandle(h_global);h_global = 0;MessageBox(L"给全局堆加锁失败");return;}// 1.5 把数据放到剪贴板中memcpy(psz_content, m_str_send.GetBuffer(), m_size);// 1.6 给全局堆解锁if(::GlobalUnlock(h_global) == 0){CloseClipboard();MessageBox(L"全局堆解锁失败");return;}// 1.7 将全局堆交给剪贴板if(SetClipboardData(CF_UNICODETEXT, h_global) == NULL){CloseClipboard();MessageBox(L"剪贴板控制全局堆失败");return;}// 1.8 关闭剪贴板CloseClipboard();
}

1.2 完成 Recv 对话框上的 剪贴板Ctrl+v 按钮

1.打开剪贴板: OpenClipboard ;
2.获取剪贴板里的数据: HANDLE h_content = GetClipboardData(CF_UNICODETEXT) ;
3.加锁: wchar_t* psz_content = (wchar_t*)::GlobalLock(h_content) ;
4.从剪贴板取数据: m_str_recv = psz_content ;
5.解锁: ::GlobalUnlock(h_content) ;
6.关闭剪贴板: CloseClipboard() ;
7.将从剪贴板中获取的数据上传到 Edit 控件中: UpdateData(FALSE) ;

void CRecvDlg::OnBnClickedButton1()
{// 接收端 剪贴板Ctrl+V// 2.1 打开剪贴板if(OpenClipboard() == 0){MessageBox(L"打开剪贴板失败");return;}// 2.2 获取剪贴板里的数据HANDLE h_content = GetClipboardData(CF_UNICODETEXT);if(h_content == 0){CloseClipboard();MessageBox(L"获取剪贴板里数据失败");return;}// 2.3 加锁wchar_t* psz_content = (wchar_t*)::GlobalLock(h_content);if(psz_content == 0){CloseClipboard();MessageBox(L"加锁失败");return;}// 2.4 从剪贴板取数据m_str_recv = psz_content;// 2.5 解锁if(::GlobalUnlock(h_content) == 0){CloseClipboard();MessageBox(L"全局堆解锁失败");return;}// 2.6 关闭剪贴板CloseClipboard();// 2.7 更新edit中的数据UpdateData(FALSE);
}

1.3 完成上述两个步骤之后我们打开两个项目,在 Send 对话框中输入一串字符,点击 剪贴板Ctrl+c ,在 Recv 对话框中点击 剪贴板Ctrl+v 来进行接受字符串。

1.4 在 Send 对话框中发送一张位图,在 Recv 对话框中进行接受

1.我们使用剪贴板来进行位图的传送;
2.在 Send 对话框中添加一个 发送图片 的按钮,并创建一张位图;
3.在 发送图片 按钮中,首先加载创建好的位图: CBitmap h_bitmap ; h_bitmap.LoadBitmap(IDB_BITMAP1) ;
4.打开剪贴板: OpenClipboard ;
5.清空剪贴板: EmptyClipboard ;
6.设置剪贴板数据: SetClipboardData(CF_BITMAP, h_bitmap.m_hObject) ;
7.关闭剪贴板: CloseClipboard ;

void CSendDlg::OnBnClickedButton3()
{// 发送图片CBitmap h_bitmap;h_bitmap.LoadBitmap(IDB_BITMAP1);// 打开剪贴板if(OpenClipboard() == 0){MessageBox(L"打开剪贴板失败");return;}// 清空剪贴板if(EmptyClipboard() == 0){CloseClipboard();MessageBox(L"清空剪贴板失败");return;}// 设置剪贴板数据if(SetClipboardData(CF_BITMAP, h_bitmap.m_hObject) == 0){CloseClipboard();MessageBox(L"设置数据失败");return;}else{// 分离图片和句柄h_bitmap.Detach();}CloseClipboard();
}

1.5 在 Recv 对话框中添加一个 接受图片 按钮和一个 Picture Control 控件

1.给 Picture Control 控件添加一个 CStatic 变量;
2.打开剪贴板: OpenClipboard ;
3.获得剪贴板里的数据: HBITMAP h_bitmap = (HBITMAP)GetClipboardData(CF_BITMAP) ;
4.显示图片: m_picture.SetBitmap(h_bitmap) ;
5.关闭剪贴板: CloseClipboard() ;

void CRecvDlg::OnBnClickedButton2()
{// 接受图片// 打开剪贴板if(OpenClipboard() == FALSE){MessageBox(L"打开剪贴板失败");return;}// 获取剪贴板里的数据HBITMAP h_bitmap = (HBITMAP)GetClipboardData(CF_BITMAP);if(h_bitmap == 0){CloseClipboard();MessageBox(L"获取数据失败");return;}// 显示图片m_picture.SetBitmap(h_bitmap);// 关闭剪贴板CloseClipboard();
}

1.6 延迟拷贝技术

1.给 Send 对话框添加 延迟拷贝 按钮;
2.在 延迟拷贝 按钮的处理函数中,首先打开剪贴板: OpenClipboard ;
3.清空剪贴板: EmptyClipboard ;
4.设置空数据: SetClipboardData(CF_UNICODETEXT, 0) ;

void CSendDlg::OnBnClickedButton4()
{// 延迟拷贝// 打开剪贴板if(OpenClipboard() == 0){MessageBox(L"打开剪贴板失败");return;}// 清空剪贴板if(EmptyClipboard() == 0){CloseClipboard();MessageBox(L"清空剪贴板失败");return;}// 设置空数据SetClipboardData(CF_UNICODETEXT, 0);CloseClipboard();
}

5.给 Send 对话框添加一个 WM_RENDERDORMAT 消息: CSendDlg::OnRenderFormat ;
6.由于在处理该消息时,剪贴板是出于打开状态的,因此在 CSendDlg::OnRenderFormat 函数中不需要打开剪贴板;
7.取数据: UpdateData(TRUE) ; int m_size = (m_str_send.GetLength()+1)2 ;
8.分配一个全局堆空间: HGLOBAL h_global = GlobalAlloc(GPTR, m_size) ;
9.给全局堆加锁: wchar_t
psz_content = (wchar_t*)::GlobalLock(h_global) ;
10.把数据放到剪贴板中: memcpy(psz_content, m_str_send.GetBuffer(), m_size) ;
11.给全局堆解锁: ::GlobalUnlock(h_global) ;
12.将全局堆交给剪贴板: SetClipboardData(CF_UNICODETEXT, h_global) ;

void CSendDlg::OnRenderFormat(UINT nFormat)
{if(CF_UNICODETEXT == nFormat){UpdateData(TRUE);int m_size = (m_str_send.GetLength()+1)*2;// 1.3 分配一个全局堆空间HGLOBAL h_global = GlobalAlloc(GPTR, m_size);if(h_global == 0){CloseClipboard();MessageBox(L"分配全局堆失败");return;}// 1.4 给全局堆加锁wchar_t* psz_content = (wchar_t*)::GlobalLock(h_global);if(psz_content == 0){CloseClipboard();CloseHandle(h_global);h_global = 0;MessageBox(L"给全局堆加锁失败");return;}// 1.5 把数据放到剪贴板中memcpy(psz_content, m_str_send.GetBuffer(), m_size);// 1.6 给全局堆解锁if(::GlobalUnlock(h_global) == 0){CloseClipboard();MessageBox(L"全局堆解锁失败");return;}// 1.7 将全局堆交给剪贴板if(SetClipboardData(CF_UNICODETEXT, h_global) == NULL){CloseClipboard();MessageBox(L"剪贴板控制全局堆失败");return;}}CDialogEx::OnRenderFormat(nFormat);
}

2.内存文件映射(另一种进程间通信的方法)

2.1 文件缓冲区:文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。通过磁盘缓存来实现,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充(辅存)。

2.2 文件缓冲区的作用

1.缓和 CPU 与 I/O 设备间速度不匹配的矛盾;
2.减少对 CPU 的中断频率,放宽对 CPU 中断响应时间的限制;
3.提高 CPU和 I/O 设备之间的并行性。

2.3 给 Send 对话框和 Recv 对话框分别添加一个按钮, Send 上的用来 创建内存文件映射

1.给 Send 对话框上的 创建内存文件映射 按钮添加消息处理函数;
2.在 CSendDlg::OnBnClickedButton5 函数中,首先创建文件: HANDLE h_file = ::CreateFile ;
3.创建内存文件映射: HANDLE h_file_mapping = ::CreateFileMapping ;
4.向文件的哪一块区域写入内容: wchar_t* pwsz_content = (wchar_t*)MapViewOfFile ;
5.UnmapViewOfFile(pwsz_content) ;
6.关闭文件: CloseHandle ;

void CSendDlg::OnBnClickedButton5()
{UpdateData(TRUE);int m_size = (m_str_send.GetLength()+1)*2;// 创建文件HANDLE h_file = ::CreateFile(L"../Msg/aa.txt",                      // 创建的文件名GENERIC_READ|GENERIC_WRITE,                // 对文件操作的权限FILE_SHARE_WRITE|FILE_SHARE_READ,        // 共享者的权限0,                                     // 安全属性CREATE_ALWAYS,                           // 一直创建FILE_ATTRIBUTE_NORMAL,                   // 文件属性0                                        // 文件模版);if(h_file == INVALID_HANDLE_VALUE){MessageBox(L"文件创建失败");return;}// 创建内存文件映射HANDLE h_file_mapping = ::CreateFileMapping(h_file,                                   // 建立与哪个文件的映射0,                                     // 安全属性PAGE_READWRITE,                          // 操作权限0, 4096,                             // 创建内存映射的大小L"HH"                                 // 内核对象名);if(h_file_mapping == 0){MessageBox(L"文件映射创建失败");return;}// 向文件的哪一块区域写入内容wchar_t* pwsz_content = (wchar_t*)MapViewOfFile(h_file_mapping, FILE_MAP_ALL_ACCESS,0, 0, m_size);if(pwsz_content != 0){::memcpy(pwsz_content, m_str_send.GetBuffer(), m_size);}UnmapViewOfFile(pwsz_content);// 关闭文件::CloseHandle(h_file);h_file = 0;// 关闭内存映射(这里不关闭文件映射的原因是我们需要在另一个进程中打开这个内存映射,若在这里关闭了,那么在另一个进程中无法打开)//::CloseHandle(h_file_mapping);//h_file_mapping = 0;
}

7.完成上述操作后我们运行 Send 对话框,在 Edit 控件上输入一串字符,点击 创建内存文件映射 按钮就会在 Send 项目同级的目录下的 Msg 文件夹里创建一个 aa.txt 文件,这个文件里的数据就是我们在 Edit 控件上输入的字符串。

操作系统与网络 2019-1-28相关推荐

  1. 【阅读材料精选 From-to-Date:2019.05.25~2019.06.28】

    [阅读材料精选 From-to-Date:2019.05.25~2019.06.28] 重点内容 [文本数据集] github:https://github.com/imhuster/funNLP [ ...

  2. 拼多多2020学霸批数据分析师笔试 —— SQL整理(2019.7.28)

    半个月过去,终于安装好Mysql,可以开始实操.解决和总结「拼多多学霸批」的SQL题了.真题还是非常珍贵的,难得和业务需求结合在一起. 加之这周,了解了「窗口函数」,比半个月前的我,又有多一点不一样的 ...

  3. 拼多多2020学霸批数据分析师笔试题 (2019.7.28)

    真真正正20届秋招,第一场笔试献给了「拼多多」. 套题 20届学霸批数据分析师笔试题 题型简单粗暴 5道问答题:3 * SQL + 1 * 概率计算 + 1 * 业务分析题 完成时间 90分钟 会写的 ...

  4. 拉勾网《32个Java面试必考点》学习笔记之二------操作系统与网络知识

    本文为拉勾网<32个Java面试必考点>学习笔记.只是对视频内容进行简单整理,详细内容还请自行观看视频<32个Java面试必考点>.若本文侵犯了相关所有者的权益,请联系:txz ...

  5. 2019.11.28

    2019.11.28 % 滑动平均(均值滤波) sliding_window = 5; impulse_fft_tmp = impulse_fft_6k; for i = 1+sliding_wind ...

  6. 18天精读掌握《费曼物理学讲义卷一》 第12天 2019/6/28

    18天精读掌握<费曼物理学讲义卷一> 第12天 2019/6/28 1. 18日掌握<费曼物理学讲义>卷一计划概览 2. 今日学习成果 3. 今日时间表 4.Atimelogg ...

  7. linux网卡断流测试,Windows XP SP2操作系统下网络非完全断流的再分析(转)

    Windows XP SP2操作系统下网络非完全断流的再分析(转)[@more@] 在升级到WindowsSP2系统后,本人的电脑经常出现这种怪毛病,具体情况为:在上网时网关能够PING通,用Bitc ...

  8. EMQ 加入VMware 创新网络“威睿加速计划” 并将参加 VMware 创新网络 2019 高峰论坛

    伴随 AIoT & 5G 时代到来,数字化转型进程的深⼊推进,和 ICT 融合.边缘计算.多云架构的产业趋势,开源创新生态的重要性变的越来越明显. VMware 作为全球领先的企业软件创新者, ...

  9. 服务器操作系统就是网络操作系统,下列网络系统软件中,最重要的是()。A. 服务器操作系统B. 网络操作系统C. 工作站重定向软件D....

    下列网络系统软件中,最重要的是().A. 服务器操作系统B. 网络操作系统C. 工作站重定向软件D. 更多相关问题 [单选] 套管可分为表层套管.()和油层套管. [单选] 硅酸盐水泥中,对强度贡献最 ...

  10. STM32CubeMX+LAN8720+LWIP不带操作系统实现网络通讯

    STM32CubeMX+LAN8720+LWIP不带操作系统实现网络通讯 使用STM32CubeMX可以非常方便的将LWIP移植到工程中,本文就是介绍如何利用STM32CubeMX移植LWIP到STM ...

最新文章

  1. [C] 深度优先搜索解决连通块/染色问题——求岛的个数
  2. 有了这 4 款工具,老板再也不怕我写烂SQL了
  3. 基础知识——用户输入和函数(五)
  4. 从FCKEDITOR到ckeditor(二) 撰写自定义对话框,增加数学公式(与webEq的结合)
  5. 堆排序之 大顶堆和小顶堆 c语言
  6. innobackupex中--slave-info参数的含义和适用场景
  7. 项目经理让我陪着技术加班
  8. php上传图片大小判断,jQuery实现判断上传图片类型和大小的方法示例
  9. 淘宝客淘点金代码自动生成跳转
  10. postgresql.conf log_rotation_size
  11. 准PR控制的谐波抑制方法
  12. 镭速传输攻克视频素材传输顽疾,大幅提升业务效率
  13. python 写入csv时添加表头,这个是亲测,最详细最傻瓜教程
  14. 木子-后端-Spring配置时间触发器的方法
  15. 耿丹CS16-2班第三次作业汇总
  16. 【机器学习】代价函数,损失函数,目标函数区别
  17. [Math Algorithm] 拉格朗日乘数法
  18. ofo共享单车和摩拜单车背后的物联网技术分析
  19. 为什么院士们纷纷推荐这本书?​
  20. NLP系列(7)_Transformer详解

热门文章

  1. 【组件封装】显示实时时间和星期几·附文字特效
  2. 秒杀抢购案例,基于 Redis 实现
  3. python+playwright 学习-1.环境准备与快速开始
  4. 模拟电路——电源电路
  5. C语言实现二路归并算法
  6. 机械员培训建筑八大员培训机械员建筑机械设备安装工程的要点
  7. virtualbox安装增强功能遇到错误
  8. 西藏2022中国农民丰收节 国稻种芯:让农牧民成为活动主角
  9. python带你制作自动答题程序,速度超越98%人
  10. 情人节程序员用HTML网页表白【守护爱情(泡泡游戏)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript