在顯示圖像之前,首先要獲取到圖像文件的存放路徑,這裏採用標準的文件打開對話框來選取圖像文件,文件名存放在CString 型的變量m_sPath中:
CFileDialog dlg(TRUE,"jpg","*.jpg",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"JPEG文件(*.jpg)|*.jpg|GIF文件(*.gif)|*.gif||",NULL);
CString m_Path;
if(dlg.DoModal()==IDOK)
{
m_Path=dlg.GetPathName();
Invalidate();
}
else
{
return;
}
爲簡單計,圖形顯示的代碼直接在視類中的OnDraw中編寫,首先打開文件並判斷文件的可用性,並把文件內容放到流接口IStream的對象pStm中:
IStream *pStm;
CFileStatus fstatus;
CFile file;
LONG cb;
LPVOID pvData=NULL;
HGLOBAL hGlobal;
// CFileStatus.m_size, GetLength(): 文件大小
if(file.Open(m_Path,CFile::modeRead)&&file.GetStatus(m_Path,fstatus)&&((cb=fstatus.m_size)!=-1))
{
hGlobal=GlobalAlloc(GMEM_MOVEABLE,cb);
if(hGlobal!=NULL)
{
if((pvData=GlobalLock(hGlobal))!=NULL)
{
file.ReadHuge(pvData,cb);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);
}
}
}
然後,就直接調用OleLoadPicture函數從流中裝載圖像:
IPicture *pPic;
由於該函數有時會導致失敗,所以應當用SUCCEEDED宏來做一些適當的保護工作,只有在數據裝載成功的前提下才能繼續下面的圖像顯示工作:
if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)))
{
OLE_XSIZE_HIMETRIC hmWidth=0;
OLE_YSIZE_HIMETRIC hmHeight=0;
pPic->get_Width(&hmWidth);
pPic->get_Height(&hmHeight);
CDC *p=GetDC();
//fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0);
// fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0);
int lWidthPixels=MulDiv(hmWidth,p->GetDeviceCaps(LOGPIXELSX),2540);
int lHeightPixels=MulDiv(hmHeight,p->GetDeviceCaps(LOGPIXELSY),2540);
CString x;
x.Format("寬度:%d 高度:%d",lWidthPixels,lHeightPixels );
AfxMessageBox(x);
if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL))) {
AfxMessageBox("渲染圖像失敗!");
pPic->Release();
}
else
AfxMessageBox("從流中裝載圖像失敗!");
}
GlobalFree(hGlobal);
其中,顯示工作主要是由IPicture接口對象的Render函數來完成的,該函數主要用來將圖片的指定部分畫到指定的設備環境的指定位置。原型如下:
HRESULT Render( HDC hdc, //渲染圖像用的設備環境句柄
long x, //在hdc上的水平座標
long y, //在hdc上的垂直座標
long cx, //圖像寬度
long cy, //圖像高度
OLE_XPOS_HIMETRIC xSrc, //在源圖像上的水平偏移
OLE_YPOS_HIMETRIC ySrc, //在源圖像上的垂直偏移
OLE_XSIZE_HIMETRIC cxSrc,//在源圖像上水平拷貝的數量
OLE_YSIZE_HIMETRIC cySrc,//在源圖像上垂直拷貝的數量
LPCRECT prcWBounds //指向目標圖元設備環境句柄的指針);
小結:
到此爲止,通過上述代碼已經能夠在程序的客戶區內顯示JPEG、GIF等標準的圖像了,但對於有多幀圖片(即有動畫)的GIF格式的圖像,目前還只能顯示第一幀,如要完整的顯示GIF 動畫的全過程,還需要外部Active X控件的支持。