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 ...
随机推荐
- 进程的处理器亲和性和 vCPU 的绑定(查看cpu信息,超线程等)
通常情况下,在 SMP 系统中,Linux 内核的进程调度器根据自有的调度策略将系统中的一个进程调度到某个 CPU 上执行.一个进程在前一个执行时间是在 cpuM(M 为系统中的某 CPU 的 ID) ...
- android 开发 ------- 接口文档 规范
1 接口书写的格式: 1 用例图 2 流程图 3 详细的接口: 3.1请求的方式: 包含: server地址 le.gxjinan.com/open/user.php?ac=login ...
- 简单好用的hash表-----uthash
在软件开发中,不可不免的会使用到hash表,hash表的优点这里就不说了,以下介绍一个hash表的C实现, uthash是用宏实现的,使用的时候非常方便,只用包含uthash.h即可. Uthash的 ...
- Spark大师之路:广播变量(Broadcast)源码分析
概述 最近工作上忙死了……广播变量这一块其实早就看过了,一直没有贴出来. 本文基于Spark 1.0源码分析,主要探讨广播变量的初始化.创建.读取以及清除. 类关系 BroadcastManager类 ...
- WSAAsyncSelect 模型
WSAAsyncSelect模型是winsock编程模型的一种,它提供了socket异步编程的方便,其实现是基于Windows消息机制的,最主要的就是下面这个函数: int PASCAL FAR WS ...
- LeetCode: Spiral Matrix II 解题报告-三种方法解决旋转矩阵问题
Spiral Matrix IIGiven an integer n, generate a square matrix filled with elements from 1 to n2 in sp ...
- [转]SQL Server 2012 的 T-SQL 新功能 – 新的数据分析函数(LEAD、LAG)
当您需要在 SQL Server 中利用 T-SQL 比较结果集的每一列跟前一列或后一列的差异时,在过去可能需要利用 CURSOR 搭配临时表变量,或是透过递归 CTE 来达到这个效果,如今 SQL ...
- python 读取文件、并以十六进制的方式写入到新文件
#!/usr/bin/env python infile = file("in.mp3","rb") outfile = file("out.txt& ...
- 在shell 中字符串,文件,数字的比较
hadoop fs -test -e /path/exist ] ;then echo 'exist' else echo 'Error! path is not exist' fi 在shell中如 ...
- 用STS创建Maven的Web项目<转>
右键New——>other——>Maven——>Maven Project 弹出框中点击Next,在Filter中写上:webapp. 然后在下面的框中选择org.apache.ma ...