图片文件的存在形式并不总是文件形式,有时可能是内存块、也有可能是字节流,比如保存于数据库中的某一图片,用GetChunk方法读取出来后一般保存在一个预先分配的内存块中,我们知道内存块的首地址,内存块的大小,要把这样的图片显示出来,可以自己编写函数按文件结构解析数据,但未免太麻烦,也是没有意义的“制造轮子”的重复工作,不如用windows系统自带的Ipicture的COM组件显示图片来得更简便些。下面是核心代码。技巧是把数据内存块转换成一个内存文件CMemFile,不必把图片文件存储成一个临时文件再读取。

  1 #include <atlbase.h>

 2 #include <afxpriv2.h>
 3 void CIpicDlg::ShowPic()
 4 {
 5     CComQIPtr<IPicture>spIPicture;
 6     HRESULT m_hr;
 7     //unsigned char* pPictureData;
 8     //UINT nPictureSize;
 9     CRect rc;
10     m_wndPic1.GetClientRect(&rc);
11     CDC* pDC = m_wndPic1.GetDC();
12     if(m_pPictureData)
13     {
14         CMemFile memfile;
15         memfile.Attach(m_pPictureData,m_nPictureSize);
16         CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete);
17         CArchiveStream arcstream(&ar);
18         HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE,
19             IID_IPicture, (void**)&spIPicture);
20         ASSERT(SUCCEEDED(hr) && spIPicture);
21         OLE_XSIZE_HIMETRIC hmWidth = 0;
22         OLE_YSIZE_HIMETRIC hmHeight = 0;
23         m_hr = spIPicture->get_Width(&hmWidth);
24         ASSERT(SUCCEEDED(m_hr));
25         m_hr = spIPicture->get_Height(&hmHeight);
26         ASSERT(SUCCEEDED(m_hr));
27         spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
28             0, hmHeight, hmWidth, -hmHeight, NULL);
29         CSize sz(hmWidth,hmHeight);
30         pDC->HIMETRICtoDP(&sz);
31     }
32     if (spIPicture)
33     {
34         spIPicture.Release();
35     }
36 }

其中m_pPictureData为图片数据块首地址,m_nPictureSize为内存块大小。

测试的VS2005的源代码可以在此下载文件信息】。

posted on 2010-04-08 15:41  Routop  阅读(852)  评论(2编辑  收藏  举报