zoukankan      html  css  js  c++  java
  • 【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();
    }
  • 相关阅读:
    嗨分享-前端技术-帝国CMS手机站修改列表分页(sysShowListMorePage)
    外观模式
    模版方法模式
    原型模式(克隆)
    策略模式
    装饰模式和代理模式
    设计原则
    工厂模式
    反射机制
    vmware RHEL6.x 开启FTP和TELNET服务--root权限
  • 原文地址:https://www.cnblogs.com/happykoukou/p/6718554.html
Copyright © 2011-2022 走看看