wie ihr seht versuche ich ein Bild anzuzeigen,keine Fehlermeldung Programm schließt sich sofort wider



  • #include <ddraw.h>
    #include <stdio.h>
    
    // Bildschirmbreite und -höhe 
    #define SCR_WIDTH  800
    #define SCR_HEIGHT 600
    // Farbtiefe des Videomodus
    #define COLOR_DEPTH 16
    
    #define IMAGE_FILE "..\\..\\media\\jli.bmp"
    // Prototypen
    
    // Anwendungsfenster erzeugen
    HWND CreateMainWindow(HINSTANCE hInstance);
    
    //Callback Funktion zur Nachrichtenbehandlung
    LRESULT CALLBACK WindowFunc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
    
    // DirectDraw-Objekte initialisieren
    BOOL InitDirectDraw(void);
    
    // Objekte/Speicher freigeben
    void CleanUpDirectDraw(void);
    
    // Ausgabefunktion
    void Render(void);
    
    // Fehlermeldung erzeugen
    BOOL Error(char* msg);
    
    // Funktion um eine Oberfläche anzulegen, 
    // als Grundlage dient eine Bitmap-Datei
    LPDIRECTDRAWSURFACE7 CreateSurfaceFromBitmap(LPCTSTR File, int dWidth, int dHeight);
    
    // Das Fensterhandle
    HWND hWnd = 0;
    
    // Zeiger auf das DirectDraw Interface
    LPDIRECTDRAW7        lpDD7           = NULL;
    LPDIRECTDRAWSURFACE7 lpDDSPrimary    = NULL;
    LPDIRECTDRAWSURFACE7 lpDDSurface     = NULL;
    
    // Windows main-Funktion
    int WINAPI WinMain(HINSTANCE hInstance,      // Handle der Programminstanz
                       HINSTANCE hPrevInstance,  // Handle der letzten Instanz
                       LPSTR lpCmdLine,          // Kommandozeile
                       int nCmdShow)             // Art wie das Fenster angezeigt werden soll
    {   
        char buf[255];
    
        sprintf(buf,"Dieses Programm lädt das Bild %s in eine Oberfläche"
                    "und blittet es auf die primäre Oberfläche",IMAGE_FILE);
    
        MessageBox(NULL,buf,"Beschreibung",MB_OK);
    
        // Fenster erzeugen und Handle speichern
        hWnd = CreateMainWindow(hInstance);
    
        // Wenn der Rückgabewert 0 ist, ist ein Fehler aufgetreten
        if(0 == hWnd)
        {
            return Error("Fehler beim Erzeugen des Fenster");
        }
    
        if(!InitDirectDraw())
        {
            return FALSE;
        }        
    
    	// Struktur, in der Informationen zur Nachricht gespeichert werden
        MSG msg;
    
        // Diese Schleife läuft bis WM_QUIT gesendet wird
        while(GetMessage(&msg,NULL,0,0))
    	{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        // Rückgabewert an Windows
        return 0;
    }
    
    HWND CreateMainWindow(HINSTANCE hInstance)
    {
        WNDCLASSEX wndClass;                                   // WNDCLASSEX Struktur
    
        // Struktur initialisieren
        wndClass.cbSize        = sizeof(WNDCLASSEX);           // Größe angeben (nie vergessen!)
        wndClass.style         = CS_DBLCLKS | CS_OWNDC |
                                 CS_HREDRAW | CS_VREDRAW;      // Standard Stile
        wndClass.lpfnWndProc   = WindowFunc;                   // Die Callback Funktion angeben
    
        wndClass.cbClsExtra    = 0;                            // Zusätzliche Angaben, wird nicht benötigt
        wndClass.cbWndExtra    = 0;                            // Zusätzliche Angaben, wird nicht benötigt
        wndClass.hInstance     = hInstance;                    // Anwendungsinstanz
    
        wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Schwarzer Pinsel
        wndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);  // Normaler Cursor
        wndClass.lpszMenuName  = NULL;                         // Das Fenster hat kein Menü
        wndClass.lpszClassName = "WindowClass";                // Der Name der Klasse
        wndClass.hIcon         = LoadIcon(NULL, IDI_WINLOGO);  // Windows Logo
        wndClass.hIconSm       = LoadIcon(NULL, IDI_WINLOGO);  // Windows Logo
    
        RegisterClassEx(&wndClass);
    
        return CreateWindowEx(NULL,                   // Keine erweiterten Stile nutzen
                              "WindowClass",          // Klassenname
                              "DDSurface",            // Fenstertitel
                              WS_POPUP |              // Fenster
                              WS_VISIBLE,             // Eigenschaften
                              0, 0,                   // Anfangsposition
                              SCR_WIDTH, SCR_HEIGHT,  // und Größe  des Fensters
                              NULL,                   // Handle des Elternfensters
                              NULL,                   // Handle des Menüs
                              hInstance,              // Anwendungsinstanz
                              NULL);                  // wird nicht benötigt
    }
    
    // Diese Funktion wird von Windows aufgrufen, wenn eine Nachricht
    // für Ihr Programm vorliegt
    LRESULT CALLBACK WindowFunc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        // testen, um welche Nachticht es sich handelt
        switch(msg)
        {
            case WM_KEYDOWN:
    			switch(wParam)
    			{
    				case VK_ESCAPE:                     
                        DestroyWindow(hWnd);
                    break;
                }
            break;
    
            case WM_DESTROY:
                CleanUpDirectDraw();
    			PostQuitMessage(0);
    		break;
    
            case WM_PAINT:
                PAINTSTRUCT ps;
                BeginPaint(hWnd,&ps);
                Render();
                EndPaint(hWnd,&ps);
    		break;        
        }
    
        // Wenn wir uns nicht um die Nachricht gekümmert haben wird sie 
        // an die Standardnachrichtenverarbeitung von Windows geschickt
        return (DefWindowProc(hwnd, msg, wParam, lParam));
    }
    
    // DirectDraw initialisieren
    BOOL InitDirectDraw(void)
    {
        // DirectDrawObjekt anlegen    
        if(FAILED(DirectDrawCreateEx(NULL,(void**)&lpDD7,IID_IDirectDraw7,NULL)))
        {  
            return Error("Fehler beim Anlegen des DirectDraw-Objekts");
        }
    
        // Kooperationsebene setzen
        if(FAILED(lpDD7->SetCooperativeLevel(hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)))
        {
            return Error("Fehler beim Setzen des Kooperationsebene");    
        }
    
        // Auflösung und Farbtiefe setzen
        if(FAILED(lpDD7->SetDisplayMode(SCR_WIDTH,SCR_HEIGHT,COLOR_DEPTH,0,0)))
        {
            return Error("Fehler beim Setzen des Kooperationsebene");    
        }
    
        // Struktur zur Beschreibung einer Oberfläche
        DDSURFACEDESC2 ddsd;
    
        // Initialisieren und Größe festlegen
        ZeroMemory(&ddsd,sizeof(ddsd));
        ddsd.dwSize = sizeof(ddsd);
    
        // Die Angabe wdCaps soll berücksichtigt werden
        ddsd.dwFlags = DDSD_CAPS;
    
        // Es soll eine primäre Oberfläche angelegt werden
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    
        // Oberfläche anlegen
        if(FAILED(lpDD7->CreateSurface(&ddsd,&lpDDSPrimary,NULL)))
        {
            return Error("Fehler beim Anlegen der primären Oberfläche");
        }
    
        // Oberfläche laden
        lpDDSurface = CreateSurfaceFromBitmap(IMAGE_FILE,SCR_WIDTH,SCR_HEIGHT);
    
        if(!lpDDSurface)
        {
            return FALSE;
        }    
    
        return TRUE;
    }
    
    void Render(void)
    {
        // die Oberfläche, die das geladene Bild enthält
        // auf die primäre Oberfläche Blitten    
        if(FAILED(lpDDSPrimary->Blt(NULL,lpDDSurface,NULL,DDBLT_WAIT,NULL)))
        {
            Error("Blt ist fehlgeschlagen");
        }
    }
    
    LPDIRECTDRAWSURFACE7 CreateSurfaceFromBitmap(LPCTSTR File, int dWidth, int dHeight)
    {
    	// Device Context für das Bild und die DirectDraw-Oberfläche anlegen
        HDC hBmDC,hSurfDC;
    
        // Handle der zu ladenden Bitmap
        HBITMAP hBM;                    
    
        // Oberflächenbeschreibung
        DDSURFACEDESC2 SurfDesc;  
    
        // Zeiger auf die Oberfläche
    	LPDIRECTDRAWSURFACE7 lpDDSurface;   
    
    	// Bild laden
        hBM = (HBITMAP)LoadImage(NULL,File,IMAGE_BITMAP,dWidth,dHeight,LR_LOADFROMFILE);
    
        // testen ob ein Fehler während des Ladens aufgetreten ist
        if(NULL == hBM)
        {
            return 0;
        }
    
    	// Oberflächenbeschreibung initialisieren
        ZeroMemory(&SurfDesc, sizeof(SurfDesc));
    	SurfDesc.dwSize = sizeof(SurfDesc);
    
        // Caps, Höhe und Breite sollen berücksichtigt werden
        SurfDesc.dwFlags =	DDSD_CAPS   | DDSD_HEIGHT | DDSD_WIDTH;
    
        SurfDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    	SurfDesc.dwWidth  = dWidth;
    	SurfDesc.dwHeight = dHeight;
    
        // Oberfläche anlegen
        if(FAILED(lpDD7->CreateSurface(&SurfDesc,&lpDDSurface,NULL)))
        {
            return 0;
        }
    
        ZeroMemory(&SurfDesc,sizeof(SurfDesc));
        SurfDesc.dwSize = sizeof(SurfDesc);
    
        lpDDSurface->GetSurfaceDesc(&SurfDesc);
    
        // wo befindet sich die erzeugt Oberfläche ?
        if(SurfDesc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
        {
           if(SurfDesc.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
           {
               OutputDebugString("Oberfläche befindet sich im LOCALVIDMEM (Grafikspeicher)\n");
           }
           else
           {
               OutputDebugString("Oberfläche befindet sich im NONLOCALVIDMEM (AGP-Speicher)\n");
           }
        }
        else
        {
            OutputDebugString("Oberfläche befindet sich im SYSTEMSPEICHER\n");    
        }
    
    	// Device Context der Oberfläche holen
        lpDDSurface->GetDC(&hSurfDC); 
    
        // Compatiblen Device Context für das Bild anlegen
        hBmDC = CreateCompatibleDC(hSurfDC);
    
        // Bild in den Device Context holen
        SelectObject(hBmDC,hBM);
    
        // Bild in die Oberfläche kopieren
        BitBlt(hSurfDC,0,0,dWidth,dHeight,hBmDC,0,0,SRCCOPY);
    
    	// Device Context freigeben
        lpDDSurface->ReleaseDC(hSurfDC);
    
        // Device Context und Bild löschen
        DeleteDC(hBmDC);
    	DeleteObject(hBM);
    
        // Zeiger auf die Oberfläche zurückgeben
        return lpDDSurface;
    }
    
    // Objekte/Speicher freigeben
    void CleanUpDirectDraw(void)
    {
        if(NULL != lpDDSurface)
        {
            lpDDSurface->Release();
            lpDDSurface = NULL;    
        }
        if(NULL != lpDDSPrimary)
        {
            lpDDSPrimary->Release();
            lpDDSPrimary = NULL;
        }
        if(NULL != lpDD7)
        {
            lpDD7->Release();
            lpDD7 = NULL;
        }
    }
    
    // Fehlermeldung ausgeben
    BOOL Error(char* msg)
    {
        // als MessageBox
        MessageBox(0,msg,"Error",MB_OK);
    
        // und in das Ausgabefenster
        OutputDebugString(msg);
        OutputDebugString("\n");
        return FALSE;
    }
    

  • Mod

    Zwei Worte: Debugger benutzen!



  • Zwei Worte: Tags benutzen!



  • soviel code les ich mir nicht durch.:D



  • Dieser Thread wurde von Moderator/in Phoemuex aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • if(!lpDDSurface)
    {
        return FALSE;
    }
    

    hier gehst du einfach ohne fehlermeldung raus. deswegen merkst du es auch
    nicht, wenn das programm hier versagt.

    DeleteDC(hBmDC);
    DeleteObject(hBM);
    

    genau anders rum. erst das objekt, dann das wo es drin war. (da du es nicht rausselektierst)

    schön wäre es, wenn du es dennoch rausselektierst. also den wert von
    SelectObject speichern und vor dem löschen wieder einsetzen. vermeidet
    mögliche memleaks 😉

    der code sieht eigentlich ganz gut aus. ich vermute einfach mal, dass der fehler
    in der bild-zu-surface methode liegt. debugausgaben sowie breakpoints und
    der fehler ist in sekunden gefunden 😉



  • test:

    es läuft einwandfrei. ich hab den dateipfad angepasst und directdraw im normalmodus (nicht vollbild) gestartet. und siehe da 😃


Anmelden zum Antworten