zoukankan      html  css  js  c++  java
  • VC 通过剪贴板读取word数据并存为jpg

    vc从剪贴板中读取word中的数据。word在剪贴板中的数据类型是HENHMETAFILE,把主要代码贴在下面

    1、读取数据转存emf文件

    void CTestClipBoardDlg::OnBnClickedButton1()

    {

    // TODO: 在此添加控件通知处理程序代码


    if(!OpenClipboard())

    {

    return;

    }

    for(int i=1; i<16; i++)

    {

    UINT   nRet1   =   EnumClipboardFormats(i); 

    CString str;

    str.Format("%d\n",i);

    if(nRet1)

    TRACE("[ok]"+str);

    else

    TRACE("[error]"+str);

    }

    DWORD   dwError;


    UINT nRet = EnumClipboardFormats(CF_ENHMETAFILE);

    if(   nRet   ) 

        { 

             BOOL   ba=::IsClipboardFormatAvailable(CF_ENHMETAFILE);   

    HANDLE   hClip=::GetClipboardData(CF_ENHMETAFILE);

    hEnhMetaFile=(HENHMETAFILE)hClip;  

    dwError=GetLastError();   //   dwError=6,无效的句柄。   

    CTime time = CTime::GetCurrentTime();

    CString str = "d:\\aaa.emf";

    //str.Format("d:\\aaa.emf", time.Format("%H%M%S"));

    HENHMETAFILE   hMetaFile=CopyEnhMetaFile(hEnhMetaFile, str);//保存到文件 

     

    //关闭CMetafileDC并获得它的句柄


    DeleteEnhMetaFile(hMetaFile);

    dwError=GetLastError();   //   dwError=6,无效的句柄。 

    CClientDC dc(this);

    CRect client(0,0,600,400);

    dc.PlayMetaFile(hEnhMetaFile,client);


        } 

          ::CloseClipboard();

    }

    2.load   emf文件转存jpg

     BOOL CConvertEMFToBMP::ConvertEMFToBMP(const char * pszEMFFile,const char* pszBMPFile,BOOL bScaleImage/*=false*/)   

    {   


    //Prepare the BMP file name   

    char szBMPFile[255] = "";   

    strcpy(szBMPFile,pszBMPFile);   



    //Convert the EMF file to BMP File   

    BOOL bRet = ConvertToBMP(pszEMFFile,(const char*)szBMPFile,bScaleImage);   


    //if BMP conversion failed return false   

    if(bRet == FALSE)   

    {   

    return FALSE;   

    }else

    {

    CImage m_img;

    m_img.Load(_T("d:\\aaa.bmp"));

    m_img.Save(_T("d:\\aaa.jpg"));


    }



    //return true/false accordingly   

    return bRet ? TRUE:FALSE;   

    }      HANDLE CConvertEMFToBMP::DDBToDIB( HBITMAP bitmap, DWORD dwCompression, HPALETTE pPal )    

    {   

    BITMAP          bm;   

    BITMAPINFOHEADER    bi;   

    LPBITMAPINFOHEADER  lpbi;   

    DWORD           dwLen;   

    HANDLE          hDIB;   

    HANDLE          handle;   

    HDC             hDC;   

    HPALETTE        hPal;   



    // The function has no arg for bitfields   

    if( dwCompression == BI_BITFIELDS )   

    return NULL;   


    // If a palette has not been supplied use defaul palette   

    hPal = (HPALETTE) pPal;   

    if (hPal==NULL)   

    hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);   


    // Get bitmap information   

    ::GetObject(bitmap,sizeof(bm),(LPSTR)&bm);   


    // Initialize the bitmapinfoheader   

    bi.biSize       = sizeof(BITMAPINFOHEADER);   

    bi.biWidth      = bm.bmWidth;   

    bi.biHeight         = bm.bmHeight;   

    bi.biPlanes         = 1;   

    bi.biBitCount       = bm.bmPlanes * bm.bmBitsPixel;   

    bi.biCompression    = dwCompression;   

    bi.biSizeImage      = 0;   

    bi.biXPelsPerMeter  = 0;   

    bi.biYPelsPerMeter  = 0;   

    bi.biClrUsed        = 0;   

    bi.biClrImportant   = 0;   


    // Compute the size of the  infoheader and the color table   

    int nColors = (1 << bi.biBitCount);   

    if( nColors > 256 )    

    nColors = 0;   

    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);   


    // We need a device context to get the DIB from   

    hDC = ::GetDC(NULL);   

    hPal = SelectPalette(hDC,hPal,FALSE);   

    RealizePalette(hDC);   


    // Allocate enough memory to hold bitmapinfoheader and color table   

    hDIB = GlobalAlloc(GMEM_FIXED,dwLen);   


    if (!hDIB)   

    {   

    SelectPalette(hDC,hPal,FALSE);   

    ::ReleaseDC(NULL,hDC);   

    return NULL;   

    }   


    lpbi = (LPBITMAPINFOHEADER)hDIB;   


    *lpbi = bi;   


    // Call GetDIBits with a NULL lpBits param, so the device driver    

    // will calculate the biSizeImage field    

    GetDIBits(hDC, (HBITMAP)bitmap, 0L, (DWORD)bi.biHeight,   

    (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);   


    bi = *lpbi;   


    // If the driver did not fill in the biSizeImage field, then compute it   

    // Each scan line of the image is aligned on a DWORD (32bit) boundary   

    if (bi.biSizeImage == 0)   

    {   

    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)    

    * bi.biHeight;   


    // If a compression scheme is used the result may infact be larger   

    // Increase the size to account for this.   

    if (dwCompression != BI_RGB)   

    bi.biSizeImage = (bi.biSizeImage * 3) / 2;   

    }   


    // Realloc the buffer so that it can hold all the bits   

    dwLen += bi.biSizeImage;   

    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))   

    {   

    hDIB = handle;   

    }   

    else   

    {   

    GlobalFree(hDIB);   


    // Reselect the original palette   

    SelectPalette(hDC,hPal,FALSE);   

    ::ReleaseDC(NULL,hDC);   

    return NULL;   

    }   


    // Get the bitmap bits   

    lpbi = (LPBITMAPINFOHEADER)hDIB;   


    // FINALLY get the DIB   

    BOOL bGotBits = GetDIBits( hDC, bitmap,   

    0L,             // Start scan line   

    (DWORD)bi.biHeight,     // # of scan lines   

    (LPBYTE)lpbi            // address for bitmap bits   

    + (bi.biSize + nColors * sizeof(RGBQUAD)),   

    (LPBITMAPINFO)lpbi,     // address of bitmapinfo   

    (DWORD)DIB_RGB_COLORS);     // Use RGB for color table   


    if( !bGotBits )   

    {   

    GlobalFree(hDIB);   


    SelectPalette(hDC,hPal,FALSE);   

    ::ReleaseDC(NULL,hDC);   

    return NULL;   

    }   


    SelectPalette(hDC,hPal,FALSE);   

    ::ReleaseDC(NULL,hDC);   

    return hDIB;   

    }   



    /*==========================================================================  

    Name                :WriteDIB  

    Purpose             :Writes the DIB information to the file  

    szFile      - Name of file to write to  

    hDIB            - Handle of the DIB  

    Arguments           :LPTSTR szFile, HANDLE hDIB  

    Return values       :TRUE on success  

    ============================================================================*/   


    BOOL CConvertEMFToBMP::WriteDIB( char * szFile, HANDLE hDIB)   

    {   

    BITMAPFILEHEADER    hdr;   

    LPBITMAPINFOHEADER  lpbi;   


    if (!hDIB)   

    return FALSE;   


    FILE* file;   

    file = fopen(szFile,"wb");   

    if(file == NULL)   

    return FALSE;   


    lpbi = (LPBITMAPINFOHEADER)hDIB;    


    int nColors = 0;    

    if(lpbi->biBitCount <= 8)    

    {    

    nColors = (1 << lpbi->biBitCount);    

    }    



    // Fill in the fields of the file header    

    hdr.bfType      = ((WORD) ('M' << 8) | 'B');  // is always "BM"   

    hdr.bfSize      = GlobalSize (hDIB) + sizeof( hdr );   

    hdr.bfReserved1     = 0;   

    hdr.bfReserved2     = 0;   

    hdr.bfOffBits       = (DWORD) (sizeof( hdr ) + lpbi->biSize +   

    nColors * sizeof(RGBQUAD));   


    // Write the file header    

    fwrite( &hdr, sizeof(hdr),1,file);   


    // Write the DIB header and the bits    

    fwrite( lpbi, GlobalSize(hDIB),1,file);   


    //Close the file and return   

    fclose(file);   


    return TRUE;   

    }   




    BOOL CConvertEMFToBMP::SetBackColorToWhite(HDC pDC)   

    {   

    // Set brush to desired background color   

    HBRUSH backBrush= (HBRUSH)(#ffffff);   



    // Save old brush   

    HBRUSH pOldBrush = (HBRUSH)::SelectObject(pDC,backBrush);   


    RECT rect ;   

    ::GetClipBox(pDC,&rect);     // Erase the area needed   


    //paint the given rectangle using the brush that is currently selected    

    //into the specified device context   

    ::PatBlt(pDC,rect.left, rect.top, abs(rect.left - rect.right),abs(rect.top-rect.bottom ),PATCOPY);   


    //Select back the old brush   

    ::SelectObject(pDC,pOldBrush);   


    return TRUE;       

    }   




    /*==========================================================================  

    Return values       :BOOL (TRUE on Success)  

    ============================================================================*/   


    BOOL CConvertEMFToBMP::ConvertToBMP(const char * strFileName,const char* strBMPFile,BOOL bScaleImage)   

    {   


    //Declartions   

    HENHMETAFILE hemf;   

    HBITMAP     bitmap;   

    HDC         memDC;   

    ENHMETAHEADER   emh;   


    //Get the DC of the Window   

    HDC dc = ::GetDC(NULL);   


    //Get the Handle from the enhanced metafile   

    hemf = GetEnhMetaFile(L"d:\\aaa.emf");


    // Get the header from the enhanced metafile.   

    ZeroMemory( &emh, sizeof(ENHMETAHEADER) );   

    emh.nSize = sizeof(ENHMETAHEADER);   

    if( GetEnhMetaFileHeader( hemf, sizeof( ENHMETAHEADER ), &emh ) == 0 )   

    {   

    DeleteEnhMetaFile( hemf );   

    return FALSE;   

    }   


    //Declare variables for calculation of metafile rect   

    RECT    rect;   

    float   PixelsX, PixelsY, MMX, MMY;   


    float fAspectRatio;   

    long lWidth,lHeight;   


    // Get the characteristics of the output device.   

    PixelsX = (float)GetDeviceCaps( dc, HORZRES );   

    PixelsY = (float)GetDeviceCaps( dc, VERTRES );   

    MMX = (float)GetDeviceCaps( dc, HORZSIZE );   

    MMY = (float)GetDeviceCaps( dc, VERTSIZE );   


    // Calculate the rect in which to draw the metafile based on the   

    // intended size and the current output device resolution.   

    // Remember that the intended size is given in 0.01 mm units, so   

    // convert those to device units on the target device.   

    rect.top = (int)((float)(emh.rclFrame.top) * PixelsY / (MMY*100.0f));   

    rect.left = (int)((float)(emh.rclFrame.left) * PixelsX / (MMX*100.0f));   

    rect.right = (int)((float)(emh.rclFrame.right) * PixelsX / (MMX*100.0f));   

    rect.bottom = (int)((float)(emh.rclFrame.bottom) * PixelsY / (MMY*100.0f));   


    //Calculate the Width and Height of the metafile   

    lWidth = (long)((float)(abs(rect.left - rect.right)));   

    lHeight =(long)((float)(abs(rect.top-rect.bottom )));   



    fAspectRatio = (float)lWidth/(float)lHeight;   



    if(bScaleImage) //If miniature option is ON, change the width and height accordingly   

    {   

    if(fAspectRatio > 1 ) //width is more than height    

    {   

    //Make width as constant and calculate Height   

    lWidth = X_MINIATUREFRAME;   

    lHeight = (long)((float)Y_MINIATUREFRAME / fAspectRatio);   


    }   

    else //width is less than height(or equal to height)   

    {   

    //Make Height as constant and calculate Width   

    lHeight = Y_MINIATUREFRAME;   

    lWidth = (long)((float)X_MINIATUREFRAME * fAspectRatio);   

    }   

    }   



    //Populate the rect structure   

    rect.left = 0;   

    rect.top = 0;   

    rect.right = lWidth;   

    rect.bottom = lHeight;   



    //Create a Memory DC compatible to WindowDC   

    memDC=::CreateCompatibleDC(dc);    



    //Create a bitmap compatible to Window DC   

    bitmap = ::CreateCompatibleBitmap(dc,lWidth,lHeight);   



    DWORD dwRetError = GetLastError();   



    //Select the bitmap into the Mem DC   

    ::SelectObject(memDC,bitmap);   


    //Paint the background of the DC to White   

    SetBackColorToWhite(memDC);   



    //Now play the enhanced metafile into the memory DC; ignore its return value   

    //it may be false even if successful   

    PlayEnhMetaFile(memDC,hemf,&rect);     

    DWORD dwRet = GetLastError();   


    // Create logical palette if device support a palette   

    HPALETTE pal;   

    if( GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE )   

    {   

    UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);   

    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];   

    pLP->palVersion = 0x300;   


    pLP->palNumEntries =    

    GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );   


    // Create the palette   

    pal = ::CreatePalette(pLP );   


    delete[] pLP;   

    }   


    // Convert the bitmap to a DIB   

    HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, NULL );   


    if( hDIB == NULL )   

    {   

    DeleteEnhMetaFile( hemf );   

    return FALSE;   

    }   



    // Write it to file   

    WriteDIB((char*)strBMPFile, hDIB );   


    // Free the memory allocated by DDBToDIB for the DIB   

    ::GlobalFree( hDIB );   


    ::DeleteEnhMetaFile( hemf );   


    ::ReleaseDC(NULL,dc);   

    return TRUE;   

    }

    (转) 转vc操作剪贴板的一些笔记

     本文主要介绍了VC++/MFC中如下内容的剪贴板操作:

    1、文本内容的操作
    2
    WMF数据的操作
    3
    、位图的操作
    4
    、设置使用自定义格式
    5
    、感知剪贴板内容的改变
    6
    、自动将数据粘贴到另一应用程序窗口

    一、文本内容的操作
    下面的代码示范了如何将文本内容复制到剪贴板(Unicode编码的先转化为ASCII)

    CString source;
    //
    文本内容保存在source变量中

    if( OpenClipboard() )
    {
     HGLOBAL clipbuffer;
     char * buffer;
     EmptyClipboard();
     clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
     buffer = (char*)GlobalLock(clipbuffer);
     strcpy(buffer, LPCSTR(source));
     GlobalUnlock(clipbuffer);
     SetClipboardData(CF_TEXT,clipbuffer);
     CloseClipboard();
    }

    下面的代码显示了如何从剪贴板上获得文本内容:

    char * buffer = NULL;
    //
    打开剪贴板

    CString fromClipboard;
    if ( OpenClipboard() )
    {
     HANDLE hData = GetClipboardData(CF_TEXT);
     char * buffer = (char*)GlobalLock(hData);
     fromClipboard = buffer;
     GlobalUnlock(hData);
     CloseClipboard();
    }

    二、WMF数据的操作

      在剪贴板上读写图象数据是非常有用的功能,并且实现起来也很简单。下面的代码显示了如何将扩展图元文件复制到剪贴板:

      if(OpenClipboard());
    {
     EmptyClipboard();

     //创建图元文件DC
     CMetaFileDC * cDC = new CMetaFileDC();
     cDC->CreateEnhanced(GetDC(),NULL,NULL,"the_name");

     //调用绘图例程

     //关闭CMetafileDC并获得它的句柄
     HENHMETAFILE handle = cDC->CloseEnhanced();

     //复制到剪贴板
     SetClipBoardData(CF_ENHMETAFILE,handle);
     CloseClipboard();

     //删除dc
     delete cDC;
    }

    下面的代码演示了从剪贴板获得图元文件并将其绘制到client DC上:

    if(OpenClipboard())
    {
     //
    获得剪贴板数据

     HENMETAFILE handle = (HENMETAFILE)GetClipboardData(CF_ENHMETAFILE);

     //显示
     CClientDC dc(this);
     CRect client(0,0,200,200);
     dc.PlayMetaFile(handle,client);

     //关闭剪贴板
     CloseClipboard();
    }
    三、位图的操作


    位图的操作稍微复杂一点,下面这个例子显示了如何在剪贴板保存位图:

    if(OpenClipboard())
    {
     EmptyClipboard();
     CBitmap * junk = new CBitmap();
     CClientDC cdc(this);
     CDC dc;
     dc.CreateCompatibleDC(&cdc);
     CRect client(0,0,200,200);
     junk->CreateCompatibleBitmap(&cdc,client.Width(),client.Height());
     dc.SelectObject(junk);

     DrawImage(&dc,CString("Bitmap"));

     //复制数据到剪贴板
     SetClipboardData(CF_BITMAP,junk->m_hObject);
     CloseClipboard();

     delete junk;
    }

    下面的代码显示了如何从剪贴板上获得位图数据:

    if(OpenClipboard())
    {
     //
    获得剪贴板数据

     HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
     CBitmap * bm = CBitmap::FromHandle(handle);

     CClientDC cdc(this);
     CDC dc;
     dc.CreateCompatibleDC(&cdc);
     dc.SelectObject(bm);
     cdc.BitBlt(0,0,200,200,&dc,0,0,SRCCOPY);

     CloseClipboard();
    }

    四、设置并使用自定义格式

    使用RegisterClipboardFormat()函数,可以复制和粘贴任何你需要的数据类型。比如我们有以下一个数据类型:

    struct MyFormatData
    {
     long val1;
     int val2;
    };

    我们要把它复制到剪贴板,可以使用如下的代码:

    UINT format = RegisterClipBoardFormat("MY_CUSTOM_FORMAT");
    if(OpenClipboard())
    {
     MyFormatData data;
     data.val1 = 100;
     data.val2 = 200;

     HGLOBAL clipbuffer;
     EmptyClipboard();
     clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(MyFormatData));
     MyFormatData * buffer = (MyFormatData*)GlobalLock(clipbuffer);

     //保存到内存
     *buffer = data;

     //保存到剪贴板
     GlobalUnlock(clipbuffer);
     SetClipboardData(format,clipbuffer);
     CloseClipboard();
    }

    读取数据使用以下代码:

    UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
    MyFormatData data;
    if(Openclipboard())
    {
     HANDLE hData =GetClipboardData(format);
     MyFormatData * buffer = (MyFormatData*)GlobalLock(hData);

     data = *buffer;

     GlobalUnlock(hData);
     CloseClipboard();
    }

    五、感知剪贴板内容的改变

    通过Windows消息可以感知剪贴板内容是否发生改变,代码如下:

    //In your initialization code call:

    SetClipboardViewer(); //将我们的程序添加到剪贴板观察链

    //In your message map add:
    ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange) //
    添加Message handle

    //Which is declared as:

    afx_msg void OnClipChange();

    Finally implement:
    void CDetectClipboardChangeDlg::OnClipChange() 
    {
     CTime time = CTime::GetCurrentTime();
     SetDlgItemText(IDC_CHANGED_DATE,time.Format("%a, %b %d, %Y -- %H:%M:%S"));

     DisplayClipboardText();
    }

    六、自动将数据粘贴到另一应用程序窗口

    只需获得相应窗口的句柄,并发送一个消息就可以了:

    SendMessage(m_hTextWnd, WM_PASTE, 0, 0);

  • 相关阅读:
    day25:接口类和抽象类
    vue1
    How the weather influences your mood?
    机器学习实验方法与原理
    How human activities damage the environment
    Slow food
    Brief Introduction to Esports
    Massive open online course (MOOC)
    Online learning in higher education
    Tensorflow Dataset API
  • 原文地址:https://www.cnblogs.com/anfeind/p/1489403.html
Copyright © 2011-2022 走看看