Вот пример простого класса CImage и его использования. Нужно только в примере подставить путь к своей картинке. Класс CImage - обёртка над стандартным COM интерфейсом IPicture. Т.е. я отвечаю только за загрузку файла, и всё! За рисование его отвечает сама система. И об типе файла задумаваться не нужно. Пробовал на bmp, ico, gif, jpeg, emf, wmf. Отображает.
Код | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h> #include <tchar.h> #include <ocidl.h> #include <olectl.h>
#define HIMETRIC_INCH 2540
class CImage { private: IPicture *m_pPicture; private: BOOL Release(); public: CImage(LPCTSTR szFileName = NULL); ~CImage() { Release(); } SIZE GetSizeImage() const;
BOOL Draw(HDC hDC, const RECT&) const; BOOL Load(LPCTSTR szFileName); };
//////////////////////////////////////////////////////////////////////////////// // other function ////////////////////////////////////////////////////////////////////////////////
SIZE PictureSize(IPicture *pPicture, bool bPixel) { SIZE size = {0,0}; DWORD dwErrCode = NO_ERROR; if (!pPicture) { dwErrCode = ERROR_INVALID_PARAMETER; } else { OLE_YSIZE_HIMETRIC hmHeight = 0; HRESULT hRes = pPicture->get_Height(&hmHeight); if (FAILED(hRes)) { dwErrCode = HRESULT_CODE(hRes); } else { OLE_XSIZE_HIMETRIC hmWidth = 0; hRes = pPicture->get_Width(&hmWidth); if (FAILED(hRes)) { dwErrCode = HRESULT_CODE(hRes); } else { if (bPixel) { HDC hDC = ::GetDC(::GetDesktopWindow()); size.cx = MulDiv(hmWidth , ::GetDeviceCaps(hDC, LOGPIXELSX), HIMETRIC_INCH); size.cy = MulDiv(hmHeight, ::GetDeviceCaps(hDC, LOGPIXELSY), HIMETRIC_INCH); ::ReleaseDC(::GetDesktopWindow(), hDC); } else { size.cx = hmWidth; size.cy = hmHeight; } } } } ::SetLastError(dwErrCode); return size; }
HRESULT LoadPictFromFile(IN OUT IPicture **ppPicture, IN LPCTSTR szFile) { HRESULT hRes = S_OK; DWORD dwErrCode = NO_ERROR; if (!ppPicture || !szFile || !szFile[0]) { hRes = HRESULT_FROM_WIN32(dwErrCode = ERROR_INVALID_PARAMETER); } else { *ppPicture = NULL; }
HANDLE hFile = INVALID_HANDLE_VALUE; DWORD dwFileSize = 0; if (SUCCEEDED(hRes)) { hFile = ::CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { hRes = HRESULT_FROM_WIN32(dwErrCode = ::GetLastError()); } else { dwFileSize = ::GetFileSize(hFile, NULL); if (dwFileSize == 0xFFFFFFFF) { hRes = HRESULT_FROM_WIN32(dwErrCode = ::GetLastError()); } } }
HGLOBAL hGlobal = NULL; LPVOID pData = NULL; if (SUCCEEDED(hRes)) { // alloc memory based on file size hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, dwFileSize); if (!hGlobal) { hRes = HRESULT_FROM_WIN32(dwErrCode = ::GetLastError()); } else { pData = ::GlobalLock(hGlobal); if (!pData) { hRes = HRESULT_FROM_WIN32(dwErrCode = ::GetLastError()); } } }
DWORD dwNBOR = 0; if (SUCCEEDED(hRes)) { // read file and store in global memory if (!::ReadFile(hFile, pData, dwFileSize, &dwNBOR, NULL) || (dwFileSize!=dwNBOR)) { hRes = HRESULT_FROM_WIN32(dwErrCode = ::GetLastError()); } } LPSTREAM pStm = NULL; if (SUCCEEDED(hRes)) { if (SUCCEEDED(hRes)) { // create IStream* from global memory hRes = ::CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); if (SUCCEEDED(hRes) && !pStm) { hRes = E_FAIL; } }
if (SUCCEEDED(hRes)) { // Create IPicture from image file hRes = ::OleLoadPicture(pStm, dwFileSize, FALSE, IID_IPicture, (LPVOID*)ppPicture); if (SUCCEEDED(hRes) && (*ppPicture == NULL)) { hRes = E_FAIL; } }
}
// free data if (pStm) { pStm->Release(); pStm = NULL; } if (hGlobal) { ::GlobalUnlock(hGlobal); ::GlobalFree(hGlobal); } if (hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(hFile); }
::SetLastError(FAILED(hRes) ? dwErrCode ? dwErrCode : HRESULT_CODE(hRes) : dwErrCode);
return hRes; }
//////////////////////////////////////////////////////////////////////////////// // implementation CImage ////////////////////////////////////////////////////////////////////////////////
CImage::CImage(LPCTSTR szFileName) : m_pPicture (NULL) { if (szFileName) { Load(szFileName); } }
BOOL CImage::Load(LPCTSTR szFileName) { BOOL bRes = TRUE; DWORD dwErrCode = NO_ERROR; if (!szFileName || !szFileName[0]) { dwErrCode = ERROR_INVALID_PARAMETER; bRes = FALSE; } else { HANDLE hImageNew = NULL; IPicture *pPicture = NULL; bRes = SUCCEEDED(::LoadPictFromFile(&pPicture, szFileName)); if (!bRes) { dwErrCode = ::GetLastError(); } else { Release(); m_pPicture = pPicture; } } ::SetLastError(dwErrCode); return bRes; }
BOOL CImage::Release() { BOOL bRes = !!m_pPicture; if (m_pPicture) { m_pPicture->Release(); m_pPicture = NULL; } return bRes; }
SIZE CImage::GetSizeImage() const { return PictureSize(m_pPicture, true); }
BOOL CImage::Draw(HDC hDC, const RECT &rect) const { BOOL bRes = TRUE; DWORD dwErrCode = NO_ERROR; if (m_pPicture) { //SIZE sizeP = PictureSize(m_pPicture, true); SIZE sizeH = PictureSize(m_pPicture, false); //HRESULT hRes = m_pPicture->Render(hDC, 0, 0, sizeP.cx, sizeP.cy, 0, sizeH.cy, sizeH.cx, -sizeH.cy, &rect); HRESULT hRes = m_pPicture->Render(hDC, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, sizeH.cy, sizeH.cx, -sizeH.cy, &rect); if (FAILED(hRes)) { dwErrCode = HRESULT_CODE(hRes); } } ::SetLastError(dwErrCode); return bRes; }
//////////////////////////////////////////////////////////////////////////////// // main part ////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { WNDCLASSEX wcex = { sizeof(WNDCLASSEX), // UINT cbSize; CS_HREDRAW | CS_VREDRAW, // UINT style; (WNDPROC)WndProc, // WNDPROC lpfnWndProc; 0, // int cbClsExtra; 0, // int cbWndExtra; hInstance, // HINSTANCE hInstance; NULL, // HICON hIcon; LoadCursor(NULL, IDC_ARROW), // HCURSOR hCursor; GetSysColorBrush(COLOR_BTNFACE), // HBRUSH hbrBackground; NULL, // LPCSTR lpszMenuName; _T("TestImageWindowClass"), // LPCSTR lpszClassName; NULL // HICON hIconSm; }; RegisterClassEx(&wcex); HWND hWnd = CreateWindow(_T("TestImageWindowClass"), _T("Test CImage"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rt; GetClientRect(hWnd, &rt); static CImage img(_T("c:\\img\\index_r1_c3.jpg")); img.Draw(hdc, rt); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
|
|