浅析Windows编程的剪贴板机制word格式

上传人:jiups****uk12 文档编号:40096737 上传时间:2018-05-23 格式:DOC 页数:5 大小:54.50KB
返回 下载 相关 举报
浅析Windows编程的剪贴板机制word格式_第1页
第1页 / 共5页
浅析Windows编程的剪贴板机制word格式_第2页
第2页 / 共5页
浅析Windows编程的剪贴板机制word格式_第3页
第3页 / 共5页
浅析Windows编程的剪贴板机制word格式_第4页
第4页 / 共5页
浅析Windows编程的剪贴板机制word格式_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《浅析Windows编程的剪贴板机制word格式》由会员分享,可在线阅读,更多相关《浅析Windows编程的剪贴板机制word格式(5页珍藏版)》请在金锄头文库上搜索。

1、【转转】浅析浅析 Windows 编程的剪贴板机制编程的剪贴板机制Windows 剪贴板剪贴板Windows 剪贴板是一种比较简单同时也是开销比较小的 IPC(InterProcess Communication,进程间通讯)机制。Windows 系统支持剪贴板 IPC 的基本机制是由 系统预留的一块全局共享内存,用来暂存在各进程间进行交换的数据:提供数据的进程创 建一个全局内存块,并将要传送的数据移到或复制到该内存块;接受数据的进程(也可以 是提供数据的进程本身)获取此内存块的句柄,并完成对该内存块数据的读取。为使剪贴板的这种 IPC 机制更加完善和便于使用,需要解决好如下三个问题:提供数

2、据的进程在结束时 Windows 系统将删除其创建的全局内存块,而接受数据的进程则希望 在其退出后剪贴板中的数据仍然存在,可以继续为其他进程所获取;能方便地管理和传送 剪贴板数据句柄;能方便设置和确定剪贴板数据格式。为完善上述功能,Windows 提供 了存在于 USER32.dll 中的一组 API 函数、消息和预定义数据格式等,并通过对这些函数、 消息的使用来管理在进程间进行的剪贴板数据交换。Windows 系统为剪贴板提供了一组 API 函数和多种消息,基本可以满足编程的需要。 而且 Windows 还为剪贴板预定义了多种数据格式。通过这些预定义的格式,可以使接收 方正确再现数据提供方放

3、置于剪贴板中的数据内容。 文本剪贴板和位图剪贴板的使用文本剪贴板和位图剪贴板的使用这两种剪贴板是比较常用的。其中,文本剪贴板是包含具有格式 CF_TEXT 的字符串 的剪贴板,是最经常使用的剪贴板之一。在文本剪贴板中传递的数据是不带任何格式信息 的 ASCII 字符。若要将文本传送到剪贴板,可以先分配一个可移动全局内存块,然后将要 复制的文本内容写入到此内存区域。最后调用剪贴板函数将数据放置到剪贴板:? DWORD dwLength = 100; / 要复制的字串长度HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); / 分配内存LP

4、BYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); / 锁定内存for (int i = 0; i dwLength; i+) / 将“*“复制到全局内存块*lpGlobalMemory+ = *;GlobalUnlock(hGlobalMemory); / 锁定内存块解锁HWND hWnd = GetSafeHwnd(); / 获取安全窗口句柄:OpenClipboard(hWnd); / 打开剪贴板:EmptyClipboard(); / 清空剪贴板:SetClipboardData(CF_TEXT, hGlobalMemory

5、); / 将内存中的数据放置到剪贴板:CloseClipboard(); / 关闭剪贴板这里以 OpenClipboard()打开剪贴板,并在调用了 EmptyClipboard()后使 hWnd 指向的窗口成为剪贴板的拥有者,一直持续到 CloseClipboard()函数的调用。 在此期间,剪贴板为拥有者所独占,其他进程将无法对剪贴板内容进行修改。从剪贴板获取文本的过程与之类似,首先打开剪贴板并获取剪贴板的数据句柄,如果 数据存在就拷贝其数据到程序变量。由于 GetClipboardData()获取的数据句柄是属于 剪贴板的,因此用户程序必须在调用 CloseClipboard()函数之前

6、使用它:? HWND hWnd = GetSafeHwnd(); / 获取安全窗口句柄 :OpenClipboard(hWnd); / 打开剪贴板 HANDLE hClipMemory = :GetClipboardData(CF_TEXT);/ 获取剪贴板数据句柄 DWORD dwLength = GlobalSize(hClipMemory); / 返回指定内存区域的当前大小 LPBYTE lpClipMemory = (LPBYTE)GlobalLock(hClipMemory); / 锁定内存 m_sMessage = CString(lpClipMemory); / 保存得到的文本数

7、据 GlobalUnlock(hClipMemory); / 内存解锁 :CloseClipboard(); / 关闭剪贴板大多数应用程序对图形数据采取的是位图的剪贴板数据格式。位图剪贴板的使用与文本剪 贴板的使用是类似的,只是数据格式要指明为 CF_BITMAP,而且在使用 SetClipboardData()或 GetClipboardData()函数时交给剪贴板或从剪贴板返回的 是设备相关位图句柄。下面这段示例代码将把存在于剪贴板中的位图数据显示到程序的客 户区:? HWND hWnd = GetSafeHwnd(); / 获取安全窗口句柄 :OpenClipboard(hWnd); /

8、 打开剪贴板 HANDLE hBitmap = :GetClipboardData(CF_BITMAP); / 获取剪贴板数据句柄 HDC hDC = :GetDC(hWnd); / 获取设备环境句柄 HDC hdcMem = CreateCompatibleDC(hDC); / 创建与设备相关的内存环境 SelectObject(hdcMem, hBitmap); / 选择对象 SetMapMode(hdcMem, GetMapMode(hDC); / 设置映射模式 BITMAP bm; / 得到位图对象 GetObject(hBitmap, sizeof(BITMAP), BitBlt(h

9、DC, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); /位图复制 :ReleaseDC(hWnd, hDC); / 释放设备环境句柄 DeleteDC(hdcMem); / 删除内存环境 :CloseClipboard(); / 关闭剪贴板多数据项和延迟提交技术多数据项和延迟提交技术要把数据放入剪贴板,在打开剪贴板后一定要调用 EmptyClipboard()函数清除当 前剪贴板中的内容,而不可以在原有数据项基础上追加新的数据项。但是,可以在 EmptyClipboard()和 CloseClipboard()调用之间多次调用 S

10、etClipboardData()函数来放置多个不同格式的数据项。例如:?OpenClipboard(hWnd); EmptyClipboardData(); SetClipboardData(CF_TEXT, hGMemText); SetClipboardData(CF_BITMAP, hBitmap); CloseClipboard();这时如果用 CF_TEXT 或 CF_BITMAP 等格式标记去调用 IsClipboardFormatAvailable()都将返回 TRUE,表明这几种格式的数据同时存在于 剪贴板中。以不同的格式标记去调用 GetClipboardData()函数可

11、以得到相应的数据句 柄。对于多数据项的剪贴板数据,还可以用 CountClipboardFormats()和 EnumClipboardFormats()函数得到当前剪贴板中存在的数据格式数目和具体的数据 格式。EnumClipboardFormats()的函数原型为:?UINT EnumClipboardFormats(UINT format);参数 format 指定了剪贴板的数据格式。如果成功执行将返回 format 指定的格式的下一 个数据格式值,如果 format 为最后的数据格式值,那么将返回 0。由此不难写出处理剪 贴板中所有格式数据项的程序段代码:? UINT format =

12、 0; / 从第一种格式值开始枚举 OpenClipboard(hWnd); while(format = EnumClipboardFormats(format) / 对相关格式数据的处理 CloseClipboard();在数据提供进程创建了剪贴板数据后,一直到有其他进程获取剪贴板数据前,这些数据都 要占据内存空间。如在剪贴板放置的数据量过大,就会浪费内存空间,降低对资源的利用 率。为避免这种浪费,可以采取延迟提交(Delayed rendering)技术,即由数据提供进 程先创建一个指定数据格式的空(NULL)剪贴板数据块,直到有其他进程需要数据或自 身进程要终止运行时才真正提交数据。延

13、迟提交的实现并不复杂,只需剪贴板拥有者进程在调用 SetClipboardData()将 数据句柄参数设置为 NULL 即可。延迟提交的拥有者进程需要做的主要工作是对 WM_RENDERFORMAT、WM_DESTORYCLIPBOARD 和 WM_RENDERALLFORMATS 等剪贴板延迟提交消息的处理。当另一个进程调用 GetClipboardData()函数时,系统将会向延迟提交数据的剪贴板拥有者进程发送 WM_RENDERFORMAT 消息。剪贴板拥有者进程在此消息的响应函数 中应使用相应的格式和实际的数据句柄来调用 SetClipboardData()函数,但不必再调 用 Ope

14、nClipboard()和 EmptyClipboard()去打开和清空剪贴板了。在设置完数据 有也无须调用 CloseClipboard()关闭剪贴板。如果其他进程打开了剪贴板并且调用 EmptyClipboard()函数去清空剪贴板的内容,接管剪贴板的拥有权时,系统将向延迟 提交的剪贴板拥有者进程发送 WM_DESTROYCLIPBOARD 消息,以通知该进程对剪贴 板拥有权的丧失。而失去剪贴板拥有权的进程在收到该消息后则不会再向剪贴板提交数据。 另外,在延迟提交进程在提交完所有要提交的数据后也会收到此消息。如果延迟提交剪贴板拥有者进程将要终止,系统将会为其发送一条 WM_RENDERAL

15、LFORMATS 消息,通 知其打开并清除剪贴板内容。在调用 SetClipboardData()设置各数据句柄后关闭剪贴 板。下面这段代码将完成对数据的延迟提交,WM_RENDERFORMAT 消息响应函数 OnRenderFormat()并不会立即执行,当有进程调用 GetClipboardData()函数从 剪贴板读取数据时才会发出该消息。在消息处理函数中完成对数据的提交:进行延迟提交:? HWND hWnd = GetSafeHwnd(); / 获取安全窗口句柄 :OpenClipboard(hWnd); / 打开剪贴板 :EmptyClipboard(); / 清空剪贴板 :SetC

16、lipboardData(CF_TEXT, NULL); / 进行剪贴板数据的延迟提交 :CloseClipboard(); / 关闭剪贴板在 WM_RENDERFORMAT 消息的响应函数中:? DWORD dwLength = 100; / 要复制的字串长度 HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); / 分配内存块 LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); / 锁定内存块 for (int i = 0; i dwLength; i+) / 将“*“复制到全局内存块 *lpGlobalMemory+ = *; GlobalUnlock(hGlobalMemory); / 锁定内存块解锁 :SetClipboardData(CF_TEXT, hGlobalMemory); /

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号