在上篇 VC 中用 IPicture 在窗口中显示图片文件 讲到的是 VC 窗口(或控件)中显示本地图片文件,本文延伸这一话题,来演示如何显示网上的图片,即提供图片的 HTTP URL 地址,把它显示到 VC 的界面中来。
本文参考我原来写的一篇日志 VC中使用CInternetSession抓取网页内容 来修改上篇代码中用来显示图片的函数:HRESULT ShowPic(char *lpstrFile,HWND hWnd)。把研究过的东西整理记下来总是好处多多,瞧,至少现在展开其他话题,可参考时便能信手拈来。
重新实现的函数 HRESULT ShowPic(char *lpstrFile,HWND hWnd) 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | // 显示图片, lpstrImgUrl 为图片URL地址,hWnd 为窗口句柄 HRESULT Utils::ShowPic( char *lpstrImgUrl, HWND hWnd) { HDC hDC_Temp=GetDC(hWnd); IPicture *pPic; IStream *pStm; BOOL bResult; DWORD dwFileSize,dwByteRead; //读取网页上图片文件,实际是个CHttpFile指针 CInternetSession session( "HttpClient" ); CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl); if (httpFile!=INVALID_HANDLE_VALUE) { dwFileSize= httpFile->GetLength(); //获取文件字节数 if (dwFileSize==0xFFFFFFFF) return E_FAIL; } else { return E_FAIL; } //分配全局存储空间 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); LPVOID pvData = NULL; if (hGlobal == NULL) return E_FAIL; if ((pvData = GlobalLock(hGlobal)) == NULL) //锁定分配内存块 return E_FAIL; //把文件读入内存缓冲区 dwByteRead = httpFile->Read(pvData,dwFileSize); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); //装入图形文件 bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,( LPVOID *)&pPic); if (FAILED(bResult)) return E_FAIL; OLE_XSIZE_HIMETRIC hmWidth; //图片的真实宽度, 单位为英寸 OLE_YSIZE_HIMETRIC hmHeight; //图片的真实高度, 单位为英寸 pPic->get_Width(&hmWidth); pPic->get_Height(&hmHeight); //转换hmWidth和hmHeight为pixels距离,1英寸=25.4毫米 int nWidth = MulDiv(hmWidth,GetDeviceCaps(hDC_Temp,LOGPIXELSX),2540); int nHeight = MulDiv(hmHeight,GetDeviceCaps(hDC_Temp,LOGPIXELSY),2540); //将图形输出到屏幕上(有点像BitBlt) bResult=pPic->Render(hDC_Temp,0,0,nWidth,nHeight, 0,hmHeight,hmWidth,-hmHeight,NULL); pPic->Release(); httpFile->Close(); //关闭打开的文件 if (SUCCEEDED(bResult)) { return S_OK; } else { return E_FAIL; } } // 显示图片, lpstrImgUrl 为图片URL地址,hWnd 为窗口句柄 HRESULT Utils::ShowPic( char *lpstrImgUrl, HWND hWnd) { HDC hDC_Temp=GetDC(hWnd); IPicture *pPic; IStream *pStm; BOOL bResult; DWORD dwFileSize,dwByteRead; //读取网页上图片文件,实际是个CHttpFile指针 CInternetSession session( "HttpClient" ); CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl); if (httpFile!=INVALID_HANDLE_VALUE) { dwFileSize= httpFile->GetLength(); //获取文件字节数 if (dwFileSize==0xFFFFFFFF) return E_FAIL; } else { return E_FAIL; } //分配全局存储空间 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); LPVOID pvData = NULL; if (hGlobal == NULL) return E_FAIL; if ((pvData = GlobalLock(hGlobal)) == NULL) //锁定分配内存块 return E_FAIL; //把文件读入内存缓冲区 dwByteRead = httpFile->Read(pvData,dwFileSize); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); //装入图形文件 bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,( LPVOID *)&pPic); if (FAILED(bResult)) return E_FAIL; OLE_XSIZE_HIMETRIC hmWidth; //图片的真实宽度, 单位为英寸 OLE_YSIZE_HIMETRIC hmHeight; //图片的真实高度, 单位为英寸 pPic->get_Width(&hmWidth); pPic->get_Height(&hmHeight); //转换hmWidth和hmHeight为pixels距离,1英寸=25.4毫米 int nWidth = MulDiv(hmWidth,GetDeviceCaps(hDC_Temp,LOGPIXELSX),2540); int nHeight = MulDiv(hmHeight,GetDeviceCaps(hDC_Temp,LOGPIXELSY),2540); //将图形输出到屏幕上(有点像BitBlt) bResult=pPic->Render(hDC_Temp,0,0,nWidth,nHeight, 0,hmHeight,hmWidth,-hmHeight,NULL); pPic->Release(); httpFile->Close(); //关闭打开的文件 if (SUCCEEDED(bResult)) { return S_OK; } else { return E_FAIL; } } |
代码说明:与上篇 VC 中用 IPicture 在窗口中显示图片文件 中函数HRESULT ShowPic(char *lpstrFile,HWND hWnd) 的比较
1. 参数 lpstrFile 改为了 lpstrImgUrl,切合实际,这里是传入的一个网上图片的 URL 地址
2. 得到文件的句柄不是通过 CreateFile 函数,而是改为了用 CInternetSession 网络读取,得到的是一个 httpFile
CInternetSession session("HttpClient");
CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl);
3. 获取文件的大小方式有变,GetFileSize() 改为用 CFile 的 GetLength()
4. 把文件读入缓冲区的方式也变了,不使用 Windows API 函数 ReadFile(),而是直接调用 CFile 的 Read()函数。
其余都一样的。把这个函数替换上一篇的同名函数,给它传递图片的 URL,将会在窗口中显示出对应图片来,尚不支持 GIF 动画,只显示第一帧,完整代码不在此列出,朋友们根据实际实现自己的需求。
联系客服