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 Files

    Trolli 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 🙂


Anmelden zum Antworten