VC++ :传统剪贴板的延迟提交技术
传统剪贴板存在的局限
传统剪贴板有一个局限性:剪贴板上的所有数据都要保存在内存上。
对于文本字符串和其它简单数据类型,可以快速有效地传递。但是,对于比较大的数据,清空剪贴板之前,数据都要占用较大的内存。而如果没有人粘贴这个位图,给它分配的内存就毫无用处。
延迟提交技术
为了避免这种浪费,Windows支持延迟提交。即直到需要的时候才将数据复制到剪贴板。
首先,用有效的剪贴板格式和NULL数据句柄调用::SetClipboardData。
然后,响应WM_RENDERFORMAT消息,调用::SetClipboardData将数据真正地放入剪贴板。
应用调用::GetClipboardData请求获取指定格式的数据时,就会发送WM_RENDERFORMAT消息。
如果没有人请求数据,就不会传递这条消息,就无需分配10MB的内存。
要注意,该消息的处理函数不应该调用::OpenClipboard和::CloseClipboard,因为接收该消息的窗口,收到消息时就占有了剪贴板。
处理WM_RENDERFORMAT消息的应用还必须处理WM_RENDERALLFORMATS消息。
当应用终止而剪贴板拥有应用放置的NULL数据句柄时,就会发送这条消息。
该消息处理函数的任务是打开剪贴板、传递应用承诺提供的数据、关闭剪贴板。
将数据放入剪贴板,保证使用延迟提交的应用终止后,其它应用可以使用这些数据。
延迟提交中还会使用WM_DESTROYCLIPBOARD消息。
这条消息通知应用不需要再提供延迟提交数据。
当其它应用调用::EmptyClipboard时,发送该消息。
在WM_RENDERALLFORMATS消息之后也发送该消息。
如果你拥有响应WM_RENDERFORMAT和WM_RENDERALLFORMATS所需的资源,可以在收到WM_DESTROYCLIPBOARD消息时安全释放它们。
测试实现
新建一个基于对话框的MFC应用程序,取名为TradClipboard;
一路“Next”到底;
在主对话框上增加一个按钮(IDC_BTN_SETCLIPBOARD);
在TradClipboardDlg.h中, 声明消息响应:
// Generated message map functions
//{{AFX_MSG(CTradClipboardDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRenderFormat (UINT nFormat);
afx_msg void OnRenderAllFormats ();
afx_msg void OnDestroyClipboard ();
afx_msg void OnBtnSetClipboard();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
在TradClipboardDlg.cpp中, 添加消息响应映射并实现:
BEGIN_MESSAGE_MAP(CTradClipboardDlg, CDialog)
//{{AFX_MSG_MAP(CTradClipboardDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_SET_CLIPBOARD, OnBtnSetClipboard)
ON_WM_LBUTTONDOWN()
ON_WM_RENDERFORMAT()
ON_WM_RENDERALLFORMATS()
ON_WM_DESTROYCLIPBOARD()
//}}AFX_MSG_MAP
END_MESSAGE_MAP() void CTradClipboardDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
MessageBox(_T("Empty zone is clicked!")); CDialog::OnLButtonDown(nFlags, point);
} void CTradClipboardDlg::OnBtnSetClipboard()
{
if(!OpenClipboard())
{
MessageBox(_T("Open Clipboard Error!"));
return;
}
if(!EmptyClipboard() )
{
MessageBox(_T("Empty Clipboard Error"));
return;
}
SetClipboardData( CF_TEXT, NULL) ;
CloseClipboard();
} void CTradClipboardDlg::OnRenderFormat (UINT nFormat)
{
if (nFormat == CF_TEXT)
{
DWORD dwLength = ;
HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + );
LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); char* pText = "Michael Jordan";
for (int i = ; i < dwLength; i++)
*lpGlobalMemory++ = *pText++; GlobalUnlock(hGlobalMemory);
SetClipboardData(CF_TEXT, hGlobalMemory);
MessageBox("OnRenderFormat");
// Make a copy of the bitmap, and store the handle in hBitmap.
//::SetClipboardData (CF_BITMAP, hBitmap);
}
}
void CTradClipboardDlg::OnRenderAllFormats ()
{
::OpenClipboard(m_hWnd);
OnRenderFormat(CF_TEXT);
CloseClipboard();
}
void CTradClipboardDlg::OnDestroyClipboard ()
{
// Delete the temporary file.
MessageBox("OnDestroyClipboard");
}
运行:

测试代码下载:
链接:http://pan.baidu.com/s/1i5zEhpV 密码:89hx
VC++ :传统剪贴板的延迟提交技术的更多相关文章
- VC 绘图,使用双缓冲技术实现
VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...
- 延迟提交form
提交按钮延迟提交form表单 function a(){document.getElementById('form1').submit();}setTimeout(a,5000);
- 移动端的传统click事件延迟和点透现象
一.场景描述: 1.A/B两个层上下z轴重叠. 2.上层的A点击后消失或移开.(这一点很重要) 3.B元素本身有默认click事件(如a标签) 或 B绑定了click事件. 在以上情况下,点击A/B重 ...
- Forth 采用Create,Does>定义新的词(word)& 延迟词技术
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 青云B轮获2000万美元VC的背后逻辑:用技术超越巨头
http://www.lagou.com/gongsi/31164.html http://capital.chinaventure.com.cn/11/7/1389263145.shtml
- VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
1.首先,要用#import语句来引用支持ADO的组件类型库(*.tlb),其中类型库可以作为可执行程序 (DLL.EXE等)的一部分被定位在其自身程序中的附属资源里,如:被定位在msado15.dl ...
- VC控件-子类化控件技术
子类化一个Windows控件与子类化一个C++类不同,子类化一个控件要求你把一个窗口的一些或所有的消息映射都替换成自己的函数来响应,这样你就有效的阻止了控件去做系统默认的行为,而按自己的想法去做.子类 ...
- 【转】浅析Windows编程的剪贴板
摘要: 本文对Windows剪贴板机制作了深入.全面的阐述,具体内容包括:文本.位图.DSP.自定义格式剪贴板的使用和多数据项和延迟提交技术. 关键词: VC++6.0: 剪贴板机制:数据格式:延迟提 ...
- windows剪贴板
0x01 Windows剪贴板 Windows剪贴板是一种比较简单同时也是开销比较小的IPC(InterProcess Communication,进程间通讯)机制.Windows系统支持剪贴板IP ...
随机推荐
- linux下使用shell脚本自动化部署项目
在Java开发项目时经常要把正在开发的项目发布到测试服务器中去测试,一般的话是要把项目先打成war包,然后把war包发布到服务器中,关闭服务器, 最后重新启动服务器,虽然这过程不是很繁琐,但如果是多个 ...
- mogoose的bug之不能根据类型为number的字段查找数据
Users.find({paw:6868}).exec() //返回的结果为空 Users.find({paw:"6868"}).exec() //返回的结果也为空 Users.f ...
- 用C++画光(一)——优化
写在前面 在先前的画光系列中,实现实体几何.反射.折射等效果,但是最大的一个缺陷是复杂度太高.当采样是1024时,渲染时间直线上升(用4线程),以至好几个小时才能完成一副作品,实现太慢.然而,当我看到 ...
- c++11特性与cocos2d-x 3.0之std::bind与std::function
昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0 ...
- 详解Base64编码和解码
Base64是最常用的编码之一,比如开发中用于传递参数.现代浏览器中的<img />标签直接通过Base64字符串来渲染图片以及用于邮件中等等.Base64编码在RFC2045中定义,它被 ...
- HTML onmousedown 事件属性 关于鼠标按键的问题;
在项目中遇到一个问题,就是点击任意键关闭弹窗的处理:出现了一个bug:就是在angularjs项目中两个controller之间的事件跳转,使用的ng-show =“iscontext” : 如所示: ...
- FreeRTOS基础篇教程目录汇总
以下教程(大部分章节)(尤其理论介绍部分)转载自安富莱电子,官网链接: http://forum.armfly.com/forum.php 然后根据安富莱的教程自己做了分析和测试,希望大家共同进步. ...
- 纯css3实现的创意图片放大镜
今天要给大家分享的的一款用纯css3实现的图片放大镜特效.页面打开五个小图显示于页面.当鼠标经过图片时,当前图片以灰色背景图的形式展示.效果非常不错. 在线预览 源码下载 实现的代码: html代 ...
- 【WPF】CommandParameter解决多传参问题
方法一:传参按钮控件自身绑定的ItemSource 用WAF框架实现MVVM,按钮的点击事件都要通过Command来传递到这个View对应的ViewModel上,再通过ViewModel传递到上层的C ...
- [Linux应用]Linux应用程序输出数据重定向到文件中
转自:http://blog.chinaunix.net/uid-20680966-id-4698387.html 目的是要让程序的printf的打印能重定向到某个文本中,ctrl+c强制退出后查看文 ...