VC操作Word读取图片

来源:互联网 发布:郫县 unity3d培训 编辑:程序博客网 时间:2024/05/14 17:15

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

0 0