在上篇 VC 中用 IPicture 在窗口中顯示圖片文件 講到的是 VC 窗口(或控件)中顯示本地圖片文件,本文延伸這一話題,來演示如何顯示網(wǎng)上的圖片,即提供圖片的 HTTP URL 地址,把它顯示到 VC 的界面中來。
本文參考我原來寫的一篇日志 VC中使用CInternetSession抓取網(wǎng)頁內(nèi)容 來修改上篇代碼中用來顯示圖片的函數(shù):HRESULT ShowPic(char *lpstrFile,HWND hWnd)。把研究過的東西整理記下來總是好處多多,瞧,至少現(xiàn)在展開其他話題,可參考時便能信手拈來。
重新實現(xiàn)的函數(shù) 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; //讀取網(wǎng)頁上圖片文件,實際是個CHttpFile指針 CInternetSession session( "HttpClient" ); CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl); if (httpFile!=INVALID_HANDLE_VALUE) { dwFileSize= httpFile->GetLength(); //獲取文件字節(jié)數(shù) 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) //鎖定分配內(nèi)存塊 return E_FAIL; //把文件讀入內(nèi)存緩沖區(qū) 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); //轉(zhuǎn)換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; //讀取網(wǎng)頁上圖片文件,實際是個CHttpFile指針 CInternetSession session( "HttpClient" ); CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl); if (httpFile!=INVALID_HANDLE_VALUE) { dwFileSize= httpFile->GetLength(); //獲取文件字節(jié)數(shù) 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) //鎖定分配內(nèi)存塊 return E_FAIL; //把文件讀入內(nèi)存緩沖區(qū) 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); //轉(zhuǎn)換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 在窗口中顯示圖片文件 中函數(shù)HRESULT ShowPic(char *lpstrFile,HWND hWnd) 的比較
1. 參數(shù) lpstrFile 改為了 lpstrImgUrl,切合實際,這里是傳入的一個網(wǎng)上圖片的 URL 地址
2. 得到文件的句柄不是通過 CreateFile 函數(shù),而是改為了用 CInternetSession 網(wǎng)絡讀取,得到的是一個 httpFile
CInternetSession session("HttpClient");
CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl);
3. 獲取文件的大小方式有變,GetFileSize() 改為用 CFile 的 GetLength()
4. 把文件讀入緩沖區(qū)的方式也變了,不使用 Windows API 函數(shù) ReadFile(),而是直接調(diào)用 CFile 的 Read()函數(shù)。
其余都一樣的。把這個函數(shù)替換上一篇的同名函數(shù),給它傳遞圖片的 URL,將會在窗口中顯示出對應圖片來,尚不支持 GIF 動畫,只顯示第一幀,完整代碼不在此列出,朋友們根據(jù)實際實現(xiàn)自己的需求。