【Windows API】OpenClipboard --- 剪切板(转)

原文转自 http://www.cnblogs.com/wind-net/archive/2012/11/01/2749558.html

剪切板:系统维护的一个全局公共内存区域.每次只允许一个进程对其进行访问。

剪切板操作方法如下:(MSDN上搜索Clipboard Operations)

1.打开剪切板 Bool OpenClipboard(HWND hWndNewOwner);   指定关联到打开的剪切板的窗口句柄,传入NULL表示关联到当前任务。每次只允许一个进程打开并访问。

每打开一次就要关闭,否则其他进程无法访问剪切板。

2.清空剪切板 Bool EmptyClipboard(void)

  写入前必须先清空,得到剪切板占有权

3.分配内存 HGLOBAL GlobalAlloc(UINT uFlags, SIZE_T dwBytes);   在堆上动态分配以字节为单位的内存区域。成功则指向该内存,失败NULL。参数:1.分配内存属性, 2.分配的大小

4.锁定内存 LPVOID GlobalLock(HGLOBAL hMem);   锁定由GlobalAlloc分配的内存,并将内存对象的锁定计数器+1,成功返回指向内存对象起始地址的指针。失败NULL

系统为每个全局内存对象维护一个锁定计数器,初始为0,GlobalLock使计数器+1,GlobalUnLock计数器-1.一旦计数器值大于0,

这块内存区域将不允许被移动或删除,只有当为0时,才解除对这块内存的锁定。如果分配时GMEM_FIXED属性,计数器一直为0

5.设置剪切板 HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

  执行成功,返回数据句柄,否则返回NULL

6.解除锁定 BOOL GlobalUnlock(HGLOBAL hMem);   将GlobalAlloc分配的属性为GMEM_MOVEABLE的内存对象计数器-1.

7.关闭剪切板 Bool CloseClipboard(void);

  必须关闭剪切板其他进程才能使用剪切板,且关闭后当前进程就不能写入数据。

8.获取剪切板数据 HANDLE GetClipboardData(UINT uFormat);

  执行成功,返回数据句柄,否则返回NULL数据格式,指定格式的数据的句柄

一:UINT uFormate格式说明:标准剪贴簿数据格式

Windows支持不同的预先定义剪贴簿格式, 这些格式在WINUSER.H定义成以CF为前缀的标识符。

■三种能够储存在剪贴簿上的文字数据型态:

①CF_TEXT    以NULL结尾的ANSI字符集字符串。它在每行末尾包含一个carriage  return和linefeed字符,这是最简单的剪贴簿数据格式。

②CF_OEMTEXT    含有文字数据(与CF_TEXT类似)的内存块。但是它使用的是OEM字符集。

③CF_UNICODETEXT    含有Unicode文字的内存块。与CF_TEXT类似,它在每一行的末尾包含一个carriage  return和linefeed字符,以及一个NULL字符(两个0字节)以表示数据结束。CF_UNICODETEXT只支援Windows NT。

■两种附加的剪贴簿格式、但是它们不需要以NULL结尾,因为格式已经定义了数据的结尾。

①CF_SYLK    包含Microsoft 「符号连结」数据格式的整体内存块。这种格式用在Microsoft的Multiplan、Chart和Excel程序之间交换数据,它是一种ASCII码格式。

②CF_DIF    包含数据交换格式(DIF)之数据的整体内存块。用于把数据送到VisiCalc电子表格程序中。这也是一种ASCII码格式

■下面三种剪贴簿格式与位图有关。所谓位图就是数据位的矩形数组

①CF_BITMAP    与设备相关的位图格式。位图是通过位图句柄传送给剪贴簿的。

②CF_DIB    定义一个设备无关位图的内存块。

③CF_PALETTE    调色盘句柄。

■下面是两个metafile格式、metafile就是一个以二进制格式储存的画图命令集

①CF_METAFILEPICT    以旧的metafile格式存放的「图片」 。

②CF_ENHMETAFILE    增强型metafile(32位Windows支持的)句柄。

■最后介绍几个混合型的剪贴簿格式:

CF_PENDATA与Windows的笔式输入扩充功能联合使用。

CF_WAVE声音(波形)文件。

CF_RIFF使用资源交换文件格式(Resource Interchange File Format)的多媒体数据。

CF_HDROP与拖放服务相关的文件列表。

二:UINT uFlags格式说明:内存属性

GMEM_FIXED

  分配一块固定的内存区域,不允许系统移动,这时返回值是一个指针。

GMEM_MOVEABLE

  分配一块可移动的内存区域,实际上内存块在物理内存中是不可移动的,这里的可移动指的是在应用程序的默认逻辑堆内可以移动。返回值是内存对象的句柄。可以通过调研GlobalLock()函数将一个句柄转化为一个指针,这个标志不能喝GMEM_FIXED 同时使用

GMEM_ZEROINT   

  初始化内存对象为全0,如果不用这个标志,内存对象将为不确定的内容

GHND

  GMEM_MOVEABLE和GMEM_ZEROINT块标志联合使用,即可移动同时初始化为0

GPTR

  GMEM_FIXED和GMEM_ZEROINT标志联合使用,即不可移动同时初始化为0

1. 将数据保存到剪切板

void  CMFC_TabCtrlDlg::SetClipBoardData_(CString strText)
{
    /*
    OpenClipboard打开剪切板:指定关联到打开的剪切板的窗口句柄,传入NULL表示关联到当前任务。每次只允许一
    个进程打开并访问。每打开一次就要关闭,否则其他进程无法访问剪切板。
    EmptyClipboard清空剪切板:写入前必须先清空,得到占有权
    */
    if (::OpenClipboard(m_hWnd) &&::EmptyClipboard())
    {
        //根据环境变量获取数据长度
        size_t cbStr = (strText.GetLength() + 1) * sizeof(TCHAR);

        //在堆上动态分配以字节为单位的全局内存区域。成功则指向该内存,失败NULL。参数:1.分配内存属性,2.大小
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cbStr); 

        if (hMem == NULL)
        {
            //关闭剪切板,释放剪切板所有权,关闭后就不能写入数据
            CloseClipboard();
            return;
        }

        //锁定由GlobalAlloc分配的内存,并将内存对象的锁定计数器+1;成功返回指向内存对象起始地址的指针。失败NULL
        LPTSTR lpDest = (LPTSTR)GlobalLock(hMem);
        /*
        系统为每个全局内存对象维护一个锁定计数器,初始为0,GlobalLock使计数器+1,
        */

        //拷贝数据到剪贴板内存。
        memcpy_s(lpDest, cbStr, strText.LockBuffer(), cbStr);
        strText.UnlockBuffer();

        //解除内存锁定,将属性为GMEM_MOVEABLE的内存对象计数器-1.
        GlobalUnlock(hMem);
        /*
        GlobalUnLock计数器-1.一旦计数器值大于0,这块内存区域将不允许被移动或删除,只
        有当为0时,才解除对这块内存的锁定。如果分配时GMEM_FIXED属性,计数器一直为0

        */

        //根据环境变量设置数据格式
        UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT;

        //设置数据到剪贴板。执行成功,返回数据句柄,否则返回NULL
        if(SetClipboardData(uiFormat, hMem) == NULL);
        {
            CloseClipboard();
            return;
        }

        CloseClipboard();
    }
}

2.从剪切板内存获取数据

void CMFC_TabCtrlDlg::GetClipBoardData_(void)
{
    //if (IsClipboardFormatAvailable(CF_UNICODETEXT)) //判断某种格式的数据是否可用
    if(::OpenClipboard(m_hWnd))
    {
        UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT;

        ////执行成功,返回数据句柄,否则返回NULL。参数:1.数据格式,2.指定格式的数据的句柄
        HGLOBAL hMem = GetClipboardData(uiFormat); 

        if (hMem != NULL)
        {
            //获取UNICODE的字符串。
            LPCTSTR lpStr = (LPCTSTR)GlobalLock(hMem);
            if (lpStr != NULL)
            {
                SetDlgItemText(IDC_EDIT1, lpStr);
            }
            GlobalUnlock(hMem);
        }
    }
    CloseClipboard();
}
时间: 2024-10-06 08:11:19

【Windows API】OpenClipboard --- 剪切板(转)的相关文章

关于剪切板

因为最近在做图文混排的复制,但又鉴于网上资料不多,也说得不是很明确,所以我想总结一下我所知道的和自己考虑的做法. windows平台,剪切板支持好几种格式,这个我还没有深入研究其他格式,暂时只对CF_TEXT,和CF_BITMAP等有点理解. 当时有点好奇qq的图文混排是怎么做到的,但是并没有太多资料给到提示,可能大家的做法都是自定义一种格式.因为我找不 到一些代码去提点我自定义格式,到底是怎么一回事,所以我目前的想法只是当选中内容中有图片时,会用<img></img> 这样的标签

背水一战 Windows 10 (102) - 应用间通信: 剪切板

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 应用间通信 剪切板 - 基础, 复制/粘贴 text 内容 剪切板 - 复制/粘贴 html 内容 剪切板 - 复制/粘贴 bitmap 内容,延迟复制 剪切板 - 复制/粘贴文件 示例1.演示剪切板的基础知识,以及如何复制 text 数据到剪切板,以及如何从剪切板中获取 text 数据 App2AppCommunication/Clipboard.xaml <Page x:Class="Windows10.App

C# 使用WinApi操作剪切板Clipboard

前言: 最近正好写一个程序,需要操作剪切板 功能很简单,只需要从剪切板内读取字符串,然后清空剪切板,然后再把字符串导入剪切板 我想当然的使用我最拿手的C#来完成这项工作,原因无他,因为.Net框架封装了能实现这种功能的方法 然后就有了如下代码 1 string Temp = ""; 2 while (true) 3 { 4 string Tex = Clipboard.GetText().ToString(); 5 if (!string.IsNullOrWhiteSpace(Tex)

C#操作剪切板(Clipboard)

剪切板是Windows系统提供的功能,从我最早接触到的Windows 3.2版本开始,就一直带着了.以前使用C++的时候,是直接使用Windows API对其进行操作的,到了.NET下,在WinForm中也有一个对剪切板的封装类,即System.Windows.Forms.Clipboard,这个类其实是通过COM组件间接地使用剪切板的,我个人觉得COM是一个设计非常糟糕的东西,难懂坑多还不可移植,但微软现存的大量代码又是基于COM的,所以又无法彻底舍弃,关于不可移植这个并不难理解,前面说了,剪

在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。 多线程操作剪切板的时候。

最近做一个蛋疼的东西就是C#调用windows API 来操作一个 软件,自动处理一些东西.要用到剪切板复制 粘贴功能,即 Clipboard.SetDataObject(filedic, true)等. 本来测试的时候,通过主线程 按钮点击开始的时候没有任何问题.但是把整个过程放在一个单独一个线程的时候一到复制的时候就报错, “在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记”.但是查看我的主线程main

C++和C#实现剪切板数据交互

c#端由于system.windows.form自带的剪切板功能太少,所以写了一个Helper类把接口转了出来.这样就可以用不同的uint的id了. 并且自带的剪切板必须执行在[STAThread]模式下,很麻烦 而c++端拷贝字符串由于编码问题,需要使用宽字符.否则会乱码 c# ClipboardHelper using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Inter

剪切板操作SetClipboardData GetClipboardData

转载:http://blog.csdn.net/ycc892009/article/details/6521565 Code: 01.// Funciton: 02.// 拷贝数据到剪切板 03.// 从剪切板粘贴数据 04.// Data:2011/4/8 05.#include <windows.h> 06.#include <stdio.h> 07.void SetDataToClip(void) 08.{ 09. // 打开剪贴板 10. if (!OpenClipboar

【整理】c# 调用windows API(user32.dll)

User32.dll提供了很多可供调用的接口,大致如下(转自http://blog.csdn.net/zhang399401/article/details/6978803) using System;    using System.Collections.Generic;    using System.Linq;    using System.Text;    using System.Runtime.InteropServices;       namespace WindowsAPI

将标题空格替换为 &#39;_&#39; , 并自动复制到剪切板上

代码: #include <stdio.h> #include <string.h> #include <windows.h> #include <conio.h> //清空剪切板 int ClearClipboradBuffer() { HGLOBAL hClipboard = NULL; if( OpenClipboard( NULL ) ) { hClipboard = GetClipboardData( CF_TEXT ); GlobalFree(