jpg aus resource?



  • Hi!
    Ich versuche, eine jpg-datei in einem fenster anzuzeigen. dabei soll die jpg-datei aus einer resource geholt werden. wieso funktioniert das so nicht?

    #include <windows.h>
    #include <olectl.h>
    
    LPPICTURE pPicture;
    long lWidth, lHeight;
    int iWidth, iHeight;
    static HINSTANCE g_hInst=NULL;
    
    BOOL LoadPicture(LPCTSTR pszResourceID)
    {
      HGLOBAL hGlobal = LoadResource (g_hInst,
                              FindResource (g_hInst, "IMAGE", pszResourceID));
    
      // größe der Resource ermitteln
      DWORD dwFileSize = SizeofResource (g_hInst,
                               FindResource (g_hInst, "IMAGE", pszResourceID));
    
      //IStream* aus dem speicher erzeugen
      LPSTREAM pstm = NULL;
      HRESULT  hr   = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
    
      //IPicture vom bild erzeugen
      if(pPicture)
          pPicture->Release();
    
      hr = OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID*)&pPicture);
      pstm->Release();
    
      //breite u. höhe vom bild holen
      pPicture->get_Width(&lWidth);
      pPicture->get_Height(&lHeight);
    
      HDC hdc = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);
    
      //in Pixel konvertieren
      iWidth = (lWidth  * GetDeviceCaps(hdc, LOGPIXELSX)) / 2540;
      iHeight = (lHeight * GetDeviceCaps(hdc, LOGPIXELSY)) / 2540;
    
      return TRUE;
    }
    
    BOOL DrawPicture(HWND hwnd, HDC hdc)
    {
      if(pPicture) //wenn bild geladen
      {
       RECT rc;
       GetClientRect(hwnd, &rc);
    
       //Bild anzeigen mittels Render
       pPicture->Render(hdc, 0, 0, iWidth, iHeight, 0, lHeight, lWidth, -lHeight, &rc);
       return TRUE;
      }
      return FALSE;
    }
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    //Deklaration der Windows-Nachrichten-Prozedur
    
    int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
    {
    char szName[] = "Fensterklasse";
    WNDCLASS wc;
    g_hInst=hI;
    
    wc.style         = CS_HREDRAW | CS_VREDRAW;   // CS = "class style"
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hI;
    wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO);
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = szName;
    
    RegisterClass (&wc);
    
    HWND hwnd = CreateWindow (szName, "", WS_SYSMENU | WS_THICKFRAME,
                              0, 0, 200, 100, NULL, NULL, hI, NULL);
    
    ShowWindow   (hwnd, iCmdShow);
    UpdateWindow (hwnd);
    
    // Nachrichten-Schleife
    MSG msg;
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    return msg.wParam;
    }
    
    // Windows-Nachrichten-Prozedur
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HDC hdc;
    PAINTSTRUCT ps;
    
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint (hwnd, &ps);
                LoadPicture("ID_TESTBILD");
                DrawPicture(hwnd, hdc);
        EndPaint (hwnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage (0);
        return 0;
    }
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    

    *.rc-datei:

    ID_TESTBILD IMAGE DISCARDABLE "test1.jpg"
    

    Mein Dank an alle hilfsbereiten menschen 😉



    Es ist immer gut, wenn man angibt, wo der Fehler passiert!

    CreateStreamOnHGlobal sollte als 2. Parameter ein FALSE bekommen, da das HGLOBAL der Resource nicht gelöscht werden darf.

    case WM_PAINT:
    hdc = BeginPaint (hwnd, &ps);
    LoadPicture("ID_TESTBILD");

    Wie häufig willst Du denn das Bild laden?



  • Also zu 1.: Das Programm lässt sich nicht starten. es spuckt die fehlermeldung aus Access violation at address 004011f3. Read of adress 00000000.

    ich nehme mal an, das die LoadResource/FindResource kombination in meinem programm fehlerhaft ist, und anstelle des speicherbereichs der resource bekomme ich nix.

    2. Ok, ist vielleicht auch eine mögliche fehlerquelle, aber ich bekomme immer noch den fehler von 1.

    3. naja, ich weiss, der aufruf von LoadPicture ist dort ein bischen fehl am platz, aber es hat funktioniert, als ich das jpg-file noch von der platte laden lies. soll ja nur zum testen sein ohne das nochmal wm_paint aufgerufen werden soll. sonst würde ich es natürlich in diesem fall in wm_create laden lassen.



  • Tach,
    du hattest mir ja schonmal ein Mail geschickt. Ich hab auch mal ein bischen rumprobiert, aber so auf die schnelle hats nicht geklappt.
    Hier hast du einen kleinen Fehler drin:
    FindResource(g_hInst, "IMAGE", pszResourceID)
    "IMAGE" ist der Typ, also Parameter 3 und pszResourceID ist der Name, also Parameter 2.

    Allerdings ist das scheinbar nicht der einzige.

    TIPP:Prinzipiell solltest du, vor allem wenn etwas nicht funktioniert, die Rückgabewerte der Funktionen auswerten und evtl. mit GetLastError auch den entsprechenden Fehlercode abfragen, dann findest du schnell die Stelle in welcher der Fehler steckt.

    Folgenden Code habe ich mal zum anzeigen einea JPG aus einer Resource verwendet (ist allerdings nicht sehr Variabel die Funktion 😉 naja vieliecht hilfts dir ja [irgendwie scheint mir die "spiecherkopiererei" auch zu viel zu sein 😕 weiß nicht mehr warum ich das da rein hab, aber es geht]) :

    void ShowJPG(HDC hdc){
    
        LPPICTURE gpPicture=0;
    
        HRSRC hResInfo;
        HGLOBAL hGlobal, hResource;
    
        hResInfo=FindResource(GetModuleHandle(0), MAKEINTRESOURCE(IDR_JPG1), "JPG");
        _ASSERTE(NULL != hResInfo);
    
        hResource=LoadResource(GetModuleHandle(0), hResInfo);
        _ASSERTE(NULL != hResource);
    
        // get ressource size
        DWORD dwFileSize = SizeofResource(GetModuleHandle(0), hResInfo);
    
        LPVOID pvDataFrom = NULL;
        LPVOID pvDataTo = NULL;
    
        // alloc memory based on file size
        hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
        _ASSERTE(NULL != hGlobal);
    
        pvDataTo=GlobalLock(hGlobal);
        _ASSERTE(NULL != pvDataTo);
    
        pvDataFrom=LockResource(hResource);
    
        memcpy(pvDataTo, pvDataFrom, dwFileSize);
    
        GlobalUnlock(hGlobal);
    
        LPSTREAM pstm = NULL;
        // create IStream* from global memory
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
        _ASSERTE(SUCCEEDED(hr) && pstm);
    
        // Create IPicture from image file
        if (gpPicture)
            gpPicture->Release();
        hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
        _ASSERTE(SUCCEEDED(hr) && gpPicture);   
        pstm->Release();
    
                if(gpPicture){
                    // get width and height of picture
                    long hmWidth;
                    long hmHeight;
                    gpPicture->get_Width(&hmWidth);
                    gpPicture->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;
                    rc.left=0;
                    rc.right=700;
                    rc.bottom=500;
                    rc.top=0;
                    // display picture using IPicture::Render
                    gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
    
                    gpPicture->Release();
                }
                else TextOut(hdc, 10, 10, "Error", 5);
    
    }
    


  • DANKE, funktioniert!

    Allerdings musste ich die _asserte-makros rausnehmen, sonst beschwert sich mein compiler wegen der fehlenden funktion '_asserte'. Gibts was vergleichbares für den c++builder 5 oder hab ich nur vergessen, etwas einzubinden?

    Also, der weg, die resource vorher in einen speicherplatz zu verschieben und dann anzuzeigen, funktioniert. bedeutet das mein programm nicht lauffähig gemacht werden kann?



  • Es heißt assert ohne e.



  • Original erstellt von <@-,-'->:
    Es heißt assert ohne e.

    Quatsch keinen Blödsinn!

    _ASSERTE



  • _ASSERTE ist Microshit-spezifisch, das solltest du dazu sagen. Bello hat einen Borland Compiler, wie du lesen kannst. Deshalb kann er damit recht wenig anfangen.


Anmelden zum Antworten