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; }
-
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 memleaksder 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