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 ...
随机推荐
- cocos2d-x笔记-CCGLProgram
引擎提供了CCGLProgram类来处理着色器相关操作,对当前绘图程序进行了封装,其中使用频率最高的应该是获取着色器程序的接口: const GLuint getProgram(); 该接口返回了当前 ...
- 破解swf文件
但我们在网页上看到漂亮的flashs,想看下别人是怎么做的,怎么办? 答曰:我们需要两个工具 swf_reader_2.3 (把浏览器中的flash下载到本地的swf文件)下载地址http://dow ...
- 让一个div始终固定在页面的某一固定位置的方法
方法一:直接用position:fixed 方法二:写一个滚动条滚动事件,让这个div设置 position:absolute 该top的距离等于滚动的距离scrollTop() 写法如下:$(win ...
- HttpWebRequest类与HttpRequest类的区别
HttpRequest类的对象用于服务器端,获取客户端传来的请求的信息,包括HTTP报文传送过来的所有信息.而HttpWebRequest用于客户端,拼接请求的HTTP报文并发送等. HttpWebR ...
- fileupload的乱码解决
解决方法就是这段代码,其中item是fileupload中的FileItem String value = new String(item.getString().getBytes("ISO ...
- js图片转base64并压缩
/* 2015-09-28 上传图片*/ function convertImgToBase64(url, callback, outputFormat){ var canvas = document ...
- 【Unity】状态机的状态改变及其回调
问:怎么知道状态机发生了改变?即如何得知从一个状态切换到了另一个状态? 答:Unity使用StateMachineBehaviours类来描述状态机的行为,当状态机处于不同的状态时,会触发不同的回调. ...
- 【C#】删除集合(Collection)里的元素(Item)
问题:C#中如果想要删除一个集合中的所有元素,直接for循环边读边删除是不可行的.因为每删除一个元素,后面的元素就会往前排,即它们的索引会向前-1,然后i还是正常的自增,就会跳过下一个元素. // 错 ...
- swd 适配器接口线序
1 vref 2 gnd 3 swdio FP1 4 swclk PF0 5 nrst 6 swo PF2
- Android——FileOutputStream与openFileOutput()的区别分析【第一个用于文件存储,第二个用于SD卡存储】【转】
本文实例分析了Android编程中FileOutputStream与openFileOutput()的区别.分享给大家供大家参考,具体如下: openFileOutput() 首先给大家介绍使用文件如 ...