在上篇 VC 中用 IPicture 在窗口中顯示圖片文件 講到的是 VC 窗口(或控件)中顯示本地圖片文件,本文延伸這一話題,來演示如何顯示網上的圖片,即提供圖片的 HTTP URL 地址,把它顯示到 VC 的界面中來。
本文參考我原來寫的一篇日志 VC中使用CInternetSession抓取網頁內容 來修改上篇代碼中用來顯示圖片的函數:HRESULT ShowPic(char *lpstrFile,HWND hWnd)。把研究過的東西整理記下來總是好處多多,瞧,至少現在展開其他話題,可參考時便能信手拈來。
重新實現的函數 HRESULT ShowPic(char *lpstrFile,HWND hWnd) 代碼如下:
// 顯示圖片, 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 動畫,只顯示第一幀,完整代碼不在此列出,朋友們根據實際實現自己的需求。