慕码人8056858
在显示图像之前,首先要获取到图像文件的存放路径,这里采用标准的文件打开对话框来选取图像文件,文件名存放在CString 型的变量m_sPath中:CFileDialog dlg(TRUE,"jpg","*.jpg",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"JPEG文件(*.jpg)|*.jpg|GIF文件(*.gif)|*.gif||",NULL);if(dlg.DoModal()==IDOK){m_sPath=dlg.GetPathName();Invalidate();} 为简单计,图形显示的代码直接在视类中的OnDraw中编写,首先打开文件并判断文件的可用性,并把文件内容放到流接口IStream的对象pStm中:IStream *pStm;CFileStatus fstatus;CFile file;LONG cb;……if (file.Open(m_Path,CFile::modeRead)&&file.GetStatus(m_Path,fstatus)&& ((cb = fstatus.m_size) != -1)){HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);LPVOID pvData = NULL;if (hGlobal != NULL){ if ((pvData = GlobalLock(hGlobal)) != NULL) { file.ReadHuge(pvData, cb); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); }}} 然后,就直接调用OleLoadPicture函数从流中装载图像:IPicture *pPic;……OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)); 由于该函数有时会导致失败,所以应当用SUCCEEDED宏来做一些适当的保护工作,只有在数据装载成功的前提下才能继续下面的图像显示工作:if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic))){OLE_XSIZE_HIMETRIC hmWidth;OLE_YSIZE_HIMETRIC hmHeight;pPic->get_Width(&hmWidth);pPic->get_Height(&hmHeight);double fX,fY;……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);if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL))) { AfxMessageBox("渲染图像失败!"); pPic->Release();}elseAfxMessageBox("从流中装载图像失败!");} 其中,显示工作主要是由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 //指向目标图元设备环境句柄的指针);