• 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);

  • 相关阅读:
    cavans笔记
    input心得
    杂乱的笔记
    CSS学习目录
    CSS3四个自适应关键字——fill-available、max-content、min-content、fit-content
    闭包
    0..0 小白
    Scrum
    Git与GitHub
    博客1
  • 原文地址:https://www.cnblogs.com/anfeind/p/1489403.html
Copyright © 2020-2023  润新知