#include <OCIDL.h>
#include <OleCtl.h>
#include <Shlwapi.h>
//
#pragma comment(lib, "Shlwapi");
HRESULT ShowPicture(LPVOID pImageData, DWORD dwLength, HWND hWnd)
{
HDC hDC = NULL;
LPVOID pData = NULL;
HGLOBAL hGlobal = NULL;
OLE_XSIZE_HIMETRIC xWidth = 0;
OLE_YSIZE_HIMETRIC xHeight = 0;
IStream *pStream = NULL;
IPicture *pPicture = NULL;
CRect rect;
HRESULT hResult = E_FAIL;
if (pImageData == NULL || dwLength == 0 || !::IsWindow(hWnd)) {
goto Exit;
}
::GetClientRect(hWnd, &rect);
hDC = ::GetDC(hWnd);
if (hDC == NULL) {
goto Exit;
}
hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, dwLength);
if (hGlobal == NULL) {
goto Exit;
}
pData = ::GlobalLock(hGlobal);
if (pData == NULL) {
goto Exit;
}
else {
CopyMemory(pData, pImageData, dwLength);
GlobalUnlock(hGlobal);
}
if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream)) || pStream == NULL) {
goto Exit;
}
if (FAILED(OleLoadPicture(pStream, dwLength, TRUE, IID_IPicture, (LPVOID *) &pPicture)) || pPicture == NULL) {
goto Exit;
}
if (FAILED(pPicture->get_Width(&xWidth))) {
goto Exit;
}
if (FAILED(pPicture->get_Height(&xHeight))) {
goto Exit;
}
if (FAILED(pPicture->Render(hDC, 0, 0, rect.Width(), rect.Height(), 0, xHeight, xWidth, -xHeight, NULL))) {
goto Exit;
}
hResult = S_OK;
Exit:
if (hDC != NULL) {
::ReleaseDC(hWnd, hDC);
hDC = NULL;
}
if (hGlobal != NULL) {
GlobalFree(hGlobal);
hGlobal = NULL;
}
if (pStream != NULL) {
pStream->Release();
pStream = NULL;
}
if (pPicture != NULL) {
pPicture->Release();
pPicture = NULL;
}
return hResult;
}
HRESULT ShowPicture(LPCTSTR pszPictureFile, HWND hWnd)
{
LPVOID pData = NULL;
HANDLE hFile = NULL;
HGLOBAL hGlobal = NULL;
DWORD dwFileSize= 0;
HRESULT hResult = E_FAIL;
if (pszPictureFile == NULL || !PathFileExists(pszPictureFile) || !(::IsWindow(hWnd))) {
goto Exit;
}
hFile = ::CreateFile(pszPictureFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
hFile = (hFile == INVALID_HANDLE_VALUE) ? NULL : hFile;
if (hFile == NULL) {
goto Exit;
}
dwFileSize = ::GetFileSize(hFile, NULL);
if (dwFileSize == -1) {
goto Exit;
}
hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
if (hGlobal == NULL) {
goto Exit;
}
pData = ::GlobalLock(hGlobal);
if (pData == NULL) {
goto Exit;
}
else {
DWORD dwByteRead = 0;
BOOL bErrFlag = ::ReadFile(hFile, pData, dwFileSize, &dwByteRead, NULL) && (dwByteRead == dwFileSize);
if (hFile != NULL) {
CloseHandle(hFile);
hFile = NULL;
}
GlobalUnlock(hGlobal);
if (!bErrFlag) {
goto Exit;
}
}
hResult = ShowPicture(pData, dwFileSize, hWnd);
Exit:
if (hFile != NULL) {
CloseHandle(hFile);
hFile = NULL;
}
if (hGlobal != NULL) {
GlobalFree(hGlobal);
hGlobal = NULL;
}
return hResult;
}
注:工作中发现 OleLoadPicture 在加载文件内容有错的图像文件时,会阻塞在 OleLoadPicture,这是微软的 BUG,如有可能显示无效的图像文件,请勿使用此法显示图像。