windows下图形数据的粘贴操作(VC)

Windows图形数据粘贴到VC程序
本文介绍如何在Windows环境下,使用VC++将CF_METAFILEPICT、CF_DIB和CF_BITMAP三种格式的剪贴板图形数据粘贴并显示在程序中。通过COleDataObject和CImage类实现对不同格式图形数据的处理和显示。

//#include // for CImage
//#include
//#include      // for abs

 

本文章描述了使用将CF_METAFILEPICT,CF_DIB和CF_BITMAP三种形式的剪贴板数据粘贴到程序中进行显示的方法.
本文章中代码编译环境为VS2003(VC71).使用了ATL类CImage

 

// CF_METAFILEPICT类型的图形
int PasteMetaGraph(CDC * pDC)
{
        // 1判断剪切板中数据格式
        COleDataObject obj;
        FORMATETC fm;memset(&fm,0,sizeof(fm));
        obj.AttachClipboard();
        BOOL bRet = obj.IsDataAvailable(CF_METAFILEPICT,&fm);
        if(!bRet)
                return 0;

        GLOBALHANDLE    hGMem =  obj.GetGlobalData(CF_METAFILEPICT);

        if(hGMem==NULL)
                return 0;
        LPMETAFILEPICT  lpMFP = (LPMETAFILEPICT)GlobalLock(hGMem) ;
        if(lpMFP==NULL)
                return 0;

        // 2计算图像的大小
        CImage img1;
        img1.Create(1,1,32);
        CDC* pDC = CDC::FromHandle(img1.GetDC());
        POINT pt= {lpMFP->xExt,lpMFP->yExt};
        pDC->SaveDC();
        pDC->SetMapMode(MM_HIMETRIC);
        pDC->LPtoDP(&pt);
        pDC->RestoreDC(-1);

        img1.ReleaseDC();
        img1.Destroy();

        // 3 按照剪切板中图像大小重新创建图片,准备接收图形数据
        CSize szNew(abs(pt.x),abs(pt.y));
        CRect  imgRect(CPoint(0,0),szNew);
        // 4根据计算好的大小imgRect对图像进行对应的操作
        CSize sizePic(imgRect.GetWidth(),imgRect.GetHeight());
        CRect rcPic(CPoint(0,0),sizePic);
       imgRect.BitBlt(pDC->GetSafeHdc(),rcPic,CPoint(0,0));
        // 5释放使用的GDI资源 obj.GetGlobalData(CF_METAFILEPICT);
        ::DeleteMetaFile(lpMFP->hMF);

        // 6解锁剪贴板
        BOOL b1 = GlobalUnlock(hGMem) ;

        return 1;
}

// CF_DIB格式的图片
int CDrawView::PasteDIBGraph(CDC* pDC)
{
        COleDataObject obj;
        FORMATETC fm;
        obj.AttachClipboard();
        // 1判断剪切板中数据格式

        BOOL bRet = obj.IsDataAvailable(CF_DIB,&fm);
        if(!bRet)
                return 0;

        // 2锁定数据,获取剪切板中的图像
        HGLOBAL    hGMem =  obj.GetGlobalData(CF_DIB) ;
        if(hGMem==NULL)
                return 0;
        PBITMAPINFO  lpBI = (PBITMAPINFO)GlobalLock(hGMem) ;
        if(lpBI==NULL)
                return 0;

        // 3查找数据图形数据段额起始位置
        int nColors = lpBI->bmiHeader.biClrUsed ? lpBI->bmiHeader.biClrUsed : 1 << lpBI->bmiHeader.biBitCount;

        // 这里的计算和转换对于bitmap bits数据的获取至关重要:
        //((lpBI->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0);这个3代表3个DWORD.即12个字节
        void * pDIBBits=NULL;
        if( lpBI->bmiHeader.biBitCount > 8 ){
                pDIBBits = (LPVOID)((LPDWORD)(lpBI->bmiColors + lpBI->bmiHeader.biClrUsed) +
                        ((lpBI->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
        }else{
                pDIBBits = (LPVOID)(lpBI->bmiColors + nColors);
        }

        // 4准备接收图形数据,获取剪切板中的数据
        ::StretchDIBits(pDC->GetSafeHdc(),
                0, 0, lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight,
                0, 0, lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight,
                pDIBBits, lpBI, DIB_PAL_COLORS, SRCCOPY);

        // 5解锁剪贴板
        GlobalUnlock(hGMem) ;

        // 刷新界面
        this->Invalidate();
        return TRUE;

}
// CF_BITMAP 类型的图片
int CDrawView::PasteBitmap(CDC* pDC)
{
        // CWnd::OpenClipboard.操作CF_BITMAP时,必须带窗体参数
        if(!OpenClipboard()){
                return 0;
        }

        BOOL bRet = IsClipboardFormatAvailable(CF_BITMAP);
        if(!bRet){
                CloseClipboard();
                return 0;
        }

        HANDLE hBitmap =  ::GetClipboardData(CF_BITMAP);
        if(hBitmap){
        CImage img;
                img.Attach((HBITMAP)hBitmap);
                // 刷新界面
                CSize sizePic(img.GetWidth(),img.GetHeight());
                CRect rcPic(CPoint(0,0),sizePic);
               img.BitBlt(pDC->GetSafeHdc(),rcPic,CPoint(0,0));
                bRet = TRUE;
        }
        CloseClipboard();

        return bRet;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值