JPEGs/GIFs/etc laden und darstellen
-
Es ist immer wieder eine beliebte Frage, wie man JPEG/GIF/ICO/WMF laden und darstellen kann, deshalb hier die Antwort
In der MSDN gibt es ein Beispiel dazu, also eine offizielle MS-Lösung:
How To Load and Display Graphics FilesTrolli hat vor einiger Zeit ein kleines Programm geschrieben, das den Lade- und Anzeige Vorgang in einer Klasse kapselt:
#include <windows.h> #include <olectl.h> class COlePicture { public: COlePicture() : pPicture(NULL) { } ~COlePicture() { if(pPicture != NULL) { pPicture->Release(); } } BOOL Load(LPCTSTR szFile) { // open file HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if(hFile == INVALID_HANDLE_VALUE) { return FALSE; } // get file size DWORD dwFileSize = GetFileSize(hFile, NULL); if(dwFileSize == -1) { return FALSE; } LPVOID pvData = NULL; // alloc memory based on file size HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); if(hGlobal == NULL) { return FALSE; } pvData = GlobalLock(hGlobal); if(pvData == NULL) { return FALSE; } DWORD dwBytesRead = 0; // read file and store in global memory BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL); if(bRead == FALSE) { return FALSE; } GlobalUnlock(hGlobal); CloseHandle(hFile); LPSTREAM pstm = NULL; // create IStream* from global memory HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); if(FAILED(hr) || pstm == NULL) { return FALSE; } // Create IPicture from image file if(pPicture) { pPicture->Release(); } hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID*)&pPicture); if(FAILED(hr) || pPicture == NULL) { return FALSE; } pstm->Release(); return TRUE; } VOID Show(HWND hWindowHandle, LONG nX, LONG nY) { HDC hDC = GetDC(hWindowHandle); if(pPicture) { // get width and height of picture LONG hmWidth; LONG hmHeight; pPicture->get_Width(&hmWidth); pPicture->get_Height(&hmHeight); // convert himetric to pixels INT nWidth = MulDiv(hmWidth, GetDeviceCaps(hDC, LOGPIXELSX), 2540); INT nHeight = MulDiv(hmHeight, GetDeviceCaps(hDC, LOGPIXELSY), 2540); RECT rc; GetClientRect(hWindowHandle, &rc); // display picture using IPicture::Render pPicture->Render(hDC, nX, nY, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc); } } private: LPPICTURE pPicture; }; ///////////////////////////////////////////////////// // Prototypes ///////////////////////////////////////////////////// LRESULT CALLBACK MainWindowProcedure(HWND hWindowHandle, UINT uMessage, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK PictureBoxProcedure(HWND hWindowHandle, UINT uMessage, WPARAM wParam, LPARAM lParam); ///////////////////////////////////////////////////// // The application's entry point ///////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hInstanceHandle, HINSTANCE hPreviousInstanceHandle, LPSTR lpszCommandLine, INT nShowState) { ///////////////////////////////////////////////////// // Register main window class ///////////////////////////////////////////////////// WNDCLASSEX MainWindowClass = {0}; MainWindowClass.cbSize = sizeof(WNDCLASSEX); MainWindowClass.hInstance = hInstanceHandle; MainWindowClass.lpszClassName = "MainWindow"; MainWindowClass.lpfnWndProc = MainWindowProcedure; MainWindowClass.style = CS_HREDRAW | CS_VREDRAW; MainWindowClass.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH); MainWindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); MainWindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); MainWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); MainWindowClass.lpszMenuName = NULL; MainWindowClass.cbClsExtra = 0; MainWindowClass.cbWndExtra = 0; if(RegisterClassEx(&MainWindowClass) == FALSE) { MessageBox(NULL, "Can't register MainWindowClass!", "Information", MB_OK); return EXIT_FAILURE; } ///////////////////////////////////////////////////// // Register PictureBox window class ///////////////////////////////////////////////////// WNDCLASSEX PictureBoxWindowClass = {0}; PictureBoxWindowClass.cbSize = sizeof(WNDCLASSEX); PictureBoxWindowClass.hInstance = hInstanceHandle; PictureBoxWindowClass.lpszClassName = "PictureBox"; PictureBoxWindowClass.lpfnWndProc = PictureBoxProcedure; PictureBoxWindowClass.style = CS_HREDRAW | CS_VREDRAW; PictureBoxWindowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); PictureBoxWindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); PictureBoxWindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); PictureBoxWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); PictureBoxWindowClass.lpszMenuName = NULL; PictureBoxWindowClass.cbClsExtra = 0; PictureBoxWindowClass.cbWndExtra = 0; if(RegisterClassEx(&PictureBoxWindowClass) == FALSE) { MessageBox(NULL, "Can't register PictureBoxWindowClass!", "Information", MB_OK); return EXIT_FAILURE; } ///////////////////////////////////////////////////// // Create main window ///////////////////////////////////////////////////// HWND hMainWindow = CreateWindowEx( 0, "MainWindow", "Simple Window Application", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, GetModuleHandle(NULL), NULL); if(hMainWindow == NULL) { MessageBox(NULL, "Can't create main window!", "Information", MB_OK); return EXIT_FAILURE; } ///////////////////////////////////////////////////// // Create PictureBox 1 ///////////////////////////////////////////////////// HWND hPictureBox1 = CreateWindowEx( 0, "PictureBox", "C:\\test1.jpg", WS_CHILD | WS_VISIBLE, 40, 20, 450, 100, hMainWindow, (HMENU) 1000, GetModuleHandle(NULL), NULL); if(hPictureBox1 == NULL) { MessageBox(NULL, "Can't create PictureBox 1!", "Information", MB_OK); return EXIT_FAILURE; } ///////////////////////////////////////////////////// // Create PictureBox 2 ///////////////////////////////////////////////////// HWND hPictureBox2 = CreateWindowEx( 0, "PictureBox", "C:\\test2.jpg", WS_CHILD | WS_VISIBLE, 40, 150, 450, 100, hMainWindow, (HMENU) 1001, GetModuleHandle(NULL), NULL); if(hPictureBox2 == NULL) { MessageBox(NULL, "Can't create PictureBox 2!", "Information", MB_OK); return EXIT_FAILURE; } ///////////////////////////////////////////////////// // Do the message loop ///////////////////////////////////////////////////// MSG Message = {0}; while(GetMessage(&Message, NULL, 0, 0)) { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } ///////////////////////////////////////////////////// // Callback function for the main window ///////////////////////////////////////////////////// LRESULT CALLBACK MainWindowProcedure(HWND hWindowHandle, UINT uMessage, WPARAM wParam, LPARAM lParam) { switch(uMessage) { case WM_COMMAND: switch(LOWORD(wParam)) { case 1000: MessageBox(hWindowHandle, "PictureBox 1 geklickt!", "Information", MB_OK); break; case 1001: MessageBox(hWindowHandle, "PictureBox 2 geklickt!", "Information", MB_OK); break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWindowHandle, uMessage, wParam, lParam); } return 0; } ///////////////////////////////////////////////////// // Callback function for the PictureBox ///////////////////////////////////////////////////// LRESULT CALLBACK PictureBoxProcedure(HWND hWindowHandle, UINT uMessage, WPARAM wParam, LPARAM lParam) { switch(uMessage) { case WM_CREATE: { COlePicture* pPicture = new COlePicture; CHAR WindowText[MAX_PATH]; GetWindowText(hWindowHandle, WindowText, MAX_PATH); pPicture->Load(WindowText); SetWindowLong(hWindowHandle, GWL_USERDATA, (LONG) pPicture); } break; case WM_DESTROY: { COlePicture* pPicture = (COlePicture*) GetWindowLong(hWindowHandle, GWL_USERDATA); if(pPicture != NULL) { delete pPicture; } } break; case WM_LBUTTONDOWN: SendMessage(GetParent(hWindowHandle), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hWindowHandle), 0), (LPARAM)hWindowHandle); break; case WM_PAINT: { PAINTSTRUCT ps; HDC hDC = BeginPaint(hWindowHandle, &ps); COlePicture* pPicture = (COlePicture*) GetWindowLong(hWindowHandle, GWL_USERDATA); if(pPicture != NULL) { pPicture->Show(hWindowHandle, 0, 0); } EndPaint(hWindowHandle, &ps); } break; default: return DefWindowProc(hWindowHandle, uMessage, wParam, lParam); } return 0; }
Da sich dieser Code damals nicht ganz einwandfrei mit LCC kompilieren ließ sei hier noch für die LCC-User das Beispielprogramm OleLoadPic von John Findlay erwähnt