Windows 剪切板的应用——复制浏览器or本地目录图片

22 篇文章 3 订阅

一、简述

最近看了windows的剪切板相关的应用代码,于是乎,便想将浏览器中复制的图片保存到本地,经过尝试,通过以下代码完成在浏览器中右键选择复制图片,然后监控键盘事件,当按下Ctrl + v 时保存到本地,并显示到界面上。

看一下效果图:

这里写图片描述

二、代码之路

下面是基于Qt建立的工程,其他工程直接使用sendCopyImage() 、 SaveBitmapToFile()方法即可。

#include "clipboardtest.h"
#include "windows.h"
#include <QKeyEvent>

// CString 与 QString 相互转换;
inline QString  CS2QS(CString cs) { return  QString::fromWCharArray((LPCTSTR)cs, cs.GetLength()); }
inline CString  QS2CS(QString qs) { return  qs.toStdString().c_str(); }

ClipboardTest::ClipboardTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

ClipboardTest::~ClipboardTest()
{

}

void ClipboardTest::keyPressEvent(QKeyEvent *event)
{
    // 按下Ctrl + v 时根据当前剪切板的内容是否显示图片;
    if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_V)
    {
        sendCopyImage();
    }

    return __super::keyPressEvent(event);
}

// 根据当前剪切板的内容是否显示图片
void ClipboardTest::sendCopyImage()
{
    bool bHasImage = false;
    CString strFileName;
    //判断剪贴板的数据格式是否可以处理。;

    // 从浏览器中复制图片;
    if (IsClipboardFormatAvailable(CF_BITMAP))
    {
        if (OpenClipboard((HWND)this->winId()))
        {
            HBITMAP hBitMap = (HBITMAP)GetClipboardData(CF_BITMAP);
            //关闭剪贴板;
            CloseClipboard();
            if (hBitMap)
            {
                bHasImage = true;
                strFileName = ".//MyImage.bmp";
                // 将浏览器复制的图片保存在本地;
                SaveBitmapToFile(hBitMap, strFileName);
            }
            else
            {
                int errorType = GetLastError();
            }
        }
    }
    // 从浏览器中复制图片;
    else if (IsClipboardFormatAvailable(CF_BITMAP))
    {
        if (OpenClipboard((HWND)this->winId()))
        {
            HBITMAP hBitMap = (HBITMAP)GetClipboardData(CF_BITMAP);
            //关闭剪贴板;
            CloseClipboard();
            if (hBitMap)
            {
                bHasImage = true;

                SaveBitmapToFile(hBitMap, strFileName);
            }
            else
            {
                int errorType = GetLastError();
            }
        }
    }

    // 如果有图片则显示图片;
    if (bHasImage)
    {
        QPixmap pixmap(CS2QS(strFileName));
        this->setFixedSize(pixmap.size());
        ui.label->setPixmap(pixmap);
    }
}

// 将图片保存为bmp文件;
bool ClipboardTest::SaveBitmapToFile(HBITMAP hBitmap, CString imageFileName)
{  
    HDC     hDC;           
    //当前分辨率下每象素所占字节数;            
    int     iBits;           
    //位图中每象素所占字节数;            
    WORD     wBitCount;           
    //定义调色板大小,     位图中像素字节大小     ,位图文件大小     ,     写入文件字节数;
    DWORD     dwPaletteSize=0,   dwBmBitsSize=0,   dwDIBSize=0,   dwWritten=0;               
    //位图属性结构;                
    BITMAP     Bitmap;                   
    //位图文件头结构;
    BITMAPFILEHEADER     bmfHdr;                   
    //位图信息头结构;
    BITMAPINFOHEADER     bi;                   
    //指向位图信息头结构;
    LPBITMAPINFOHEADER     lpbi;                   
    //定义文件,分配内存句柄,调色板句柄;               
    HANDLE     fh,   hDib,   hPal,hOldPal=NULL;               

    //计算位图文件每个像素所占字节数;  
    hDC  = CreateDC(CString("DISPLAY"),   NULL,   NULL,   NULL);           
    iBits  = GetDeviceCaps(hDC,   BITSPIXEL)     *     GetDeviceCaps(hDC,   PLANES);               
    DeleteDC(hDC);               
    if(iBits <=  1)                                                     
        wBitCount = 1;               
    else  if(iBits <=  4)                                 
        wBitCount  = 4;               
    else if(iBits <=  8)                                 
        wBitCount  = 8;               
    else                                                                                                                                 
        wBitCount  = 24;  

    GetObject(hBitmap,   sizeof(Bitmap),   (LPSTR)&Bitmap);           
    bi.biSize= sizeof(BITMAPINFOHEADER);           
    bi.biWidth = Bitmap.bmWidth;           
    bi.biHeight =  Bitmap.bmHeight;           
    bi.biPlanes =  1;           
    bi.biBitCount = wBitCount;           
    bi.biCompression= BI_RGB;           
    bi.biSizeImage=0;           
    bi.biXPelsPerMeter = 0;           
    bi.biYPelsPerMeter = 0;           
    bi.biClrImportant = 0;           
    bi.biClrUsed =  0;           

    dwBmBitsSize  = ((Bitmap.bmWidth *wBitCount+31) / 32)*4* Bitmap.bmHeight;           

    //为位图内容分配内存;
    hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));               
    lpbi  = (LPBITMAPINFOHEADER)GlobalLock(hDib);               
    *lpbi  = bi;               

    //处理调色板;
    hPal  = GetStockObject(DEFAULT_PALETTE);               
    if (hPal)               
    {               
        hDC  = ::GetDC(NULL);               
        hOldPal = ::SelectPalette(hDC,(HPALETTE)hPal, FALSE);               
        RealizePalette(hDC);               
    }           

    //获取该调色板下新的像素值;
    GetDIBits(hDC,hBitmap, 0,(UINT)Bitmap.bmHeight,    
        (LPSTR)lpbi+ sizeof(BITMAPINFOHEADER)+dwPaletteSize,     
        (BITMAPINFO *)lpbi, DIB_RGB_COLORS);               

    //恢复调色板;
    if (hOldPal)               
    {               
        ::SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);               
        RealizePalette(hDC);               
        ::ReleaseDC(NULL,   hDC);               
    }               

    //创建位图文件;
    fh = CreateFile(imageFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,   NULL);               

    if (fh     ==  INVALID_HANDLE_VALUE)         return     FALSE;               

    //设置位图文件头;
    bmfHdr.bfType  = 0x4D42;     //     "BM"                
    dwDIBSize  = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;                   
    bmfHdr.bfSize  = dwDIBSize;               
    bmfHdr.bfReserved1  = 0;               
    bmfHdr.bfReserved2  = 0;               
    bmfHdr.bfOffBits  = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;               
    //写入位图文件头;
    WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),   &dwWritten,   NULL);               
    //写入位图文件其余内容;
    WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,   &dwWritten,   NULL);               
    //清除;
    GlobalUnlock(hDib);               
    GlobalFree(hDib);               
    CloseHandle(fh);               

    return     TRUE;           

}  

从浏览器中复制图片

从浏览器中右键复制图片,切换到我们的程序按下Ctrl + v 保存图片至本地并显示到界面上。

这里写图片描述


这里写图片描述


这里写图片描述

从本地目录复制图片

这里写图片描述

使用PrtScn键获取屏幕截图

按下PrtScn键(Print Screen键),然后回到程序,按下Ctrl+V即可将图片复制到程序中显示。

这里写图片描述


代码下载

环境为Qt 5.5 + VS2013,其他工程可以直接copy上面代码稍作修改即可。

Windows 剪切板的应用


更新于2017年6月15日。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值