Problem mit DirectDraw7 (UpdateOverlay), help!



  • Hall Community,

    also ich habe mir jetzt hier ein Programm geschrieben das einfach nur ein Overlay anzeigen soll, wenn von Prozess X das Window, ActiveWindow ist. Jetzt gibts da irgendwie ein Problem, wenn ich Prozess X im Fenster-Modus starte wird das Overlay angezeigt und auch brave geupdatet, allerdings wenn ich Prozess X im Fullscreen-Mode laufen lasse und dann versuche das Overlay zu zeichnen, liefert ::UpdateOverlay != DD_OK, ich hab mal versucht mit GetLastError() den Fehlercode zu indentifizieren, aber da kamen nur irgendwelche Zeichen raus die kein Sinn ergeben haben.

    Was ich noch beobachten konnte war, dass das Overlay ganz kurz (nicht mal eine Sekunde) erscheint und dann aber der Fehler auftritt.

    Ich hoffe hier koennt ihr mir weiter helfen.

    Gruß Tobi



  • Hat keiner eine Idee?



  • Also meine Kristallkugel sagt...

    Das du mal schauen musst im Debugger was da "!= DD_OK" genau sein soll und du dann auch in der Doku nachlesen koenntest, was das Problem ist. f'`8k

    Autocogito

    Gruß, TGGC (Der neue Game Star)



  • Also der Returnwert ist DDERR_SURFACELOST, das heisst also das durch das setzen des Fullscreen-Modus vom andern Prozess der Surface Speicher ungueltig wurde und zwar der vom Overlay, richtig? Also hab ich ein ::Restore( ) gemacht was allerdings nichts gebracht hat.



  • Hilfe?



  • Hier mal mein Code:

    //--- Includes ---------------------------------------------------
    
    #include "stdafx.h"
    
    //--- Globals ----------------------------------------------------
    
    const char szAppName[ ] = "BLA";
    const char szAppTitle[ ] = "BLA";
    
    HINSTANCE               g_hInst;
    LPDIRECTDRAW7           g_lpDD;		// global DD object
    LPDIRECTDRAWSURFACE7    g_lpPrim;   // Primary surface
    LPDIRECTDRAWSURFACE7    g_lpOver;   // Overlay surface
    LPDIRECTDRAWSURFACE7    g_lpBack;   // Backbuffer from overlay
    DDPIXELFORMAT           g_ddPF;	    // Pixelformat for overlay 
    
    HBITMAP                 g_hSlots[ 2 ];
    
    //--- Prototypes -------------------------------------------------
    
    LRESULT CALLBACK WinProc( HWND, UINT, WPARAM, LPARAM );
    
    DWORD   WINAPI   ThreadFunc( LPVOID lpData );
    
    bool fInitialDD( );
    bool fOverlayComp( );
    bool fCreatePrimSurf( );
    bool fCreateOverSurf( );
    bool fUpdateOverlay( const bool bShow );
    void fCleanUp( );
    
    //--- WinMain ----------------------------------------------------
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
    
    	HWND hWnd;
    	WNDCLASS wc;
    	MSG msg;
    
    	// ***** Create windowclass *****
    	wc.cbClsExtra = 0;
    	wc.cbWndExtra = 0;
    	wc.hbrBackground = reinterpret_cast< HBRUSH >( GetStockObject( WHITE_BRUSH ) );
    	wc.hCursor = LoadCursor( 0, IDC_ARROW );
    	wc.hIcon = LoadIcon( 0, IDI_APPLICATION );
    	wc.hInstance = hInstance;
    	wc.lpfnWndProc = WinProc;
    	wc.lpszClassName = szAppName;
    	wc.lpszMenuName = 0;
    	wc.style = CS_HREDRAW | CS_VREDRAW;
    
    	// ***** Register class *****
    	if( !( RegisterClass( &wc ) ) ) {
    
    		MessageBox( 0, "Could not register window class!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return 0;
    	}
    
    	// ***** Create mainwindow *****
    	hWnd = CreateWindowEx( 0,
    		                   szAppName, szAppTitle,
    						   WS_SYSMENU | WS_MINIMIZEBOX,
    						   CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    						   0,
    						   0,
    						   hInstance,
    						   0 );
    
    	// ***** Show & Update window *****
    	ShowWindow( hWnd, nCmdShow );
    	UpdateWindow( hWnd );
    
        // Save instance
        g_hInst = hInstance;
    
    	// ***** Messageloop *****
    	while( GetMessage( &msg, 0, 0, 0 ) ) {
    
    	    TranslateMessage( &msg );
    	    DispatchMessage( &msg );
    	}
    
    	return 0;
    }
    
    //--- Definitions ------------------------------------------------
    
    // ***** Mainwindow procedure *****
    LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
    
        static HMODULE hLib = 0;
    	switch( message ) {
    
    		case WM_CREATE: {	
    
                            // Init all
    
    			return 0;
    		}
    
    		case WM_PAINT: {
    
                HDC hDC;
                PAINTSTRUCT ps;
    
                hDC = BeginPaint( hWnd, &ps );
    
                //bla
    
                EndPaint( hWnd, &ps );
    
                return 0;
            }
    
    		case WM_DESTROY: {
    
                            // bla 
    			return 0;
    		}
    	}
    	return( DefWindowProc( hWnd, message, wParam, lParam ) );
    }
    
    DWORD WINAPI ThreadFunc( LPVOID lpData ) { 
    
        while( true ) {
    
            if( GetForegroundWindow( ) == g_hWar3Win ) {
    
                if( g_lpPrim->IsLost( ) == DDERR_SURFACELOST ) {
    
                    g_lpPrim->Restore( );
    
                    if( g_lpOver->IsLost( ) == DDERR_SURFACELOST )
                        g_lpOver->Restore( );    
    
                    continue;
                }
    
                if( !( fFadeOut( ) ) ) {
    
                    fUpdateOverlay( true );
                }
                else {
    
                    fUpdateOverlay( false );    
                }
            }
            else {
    
                fUpdateOverlay( false );
            }
    
            Sleep( 1 );
        }
        return 0; 
    }
    
    // ***** Initial the DD *****
    bool fInitialDD( ) {
    
    	HRESULT result;
    
    	result = DirectDrawCreateEx( 0, (void**)&g_lpDD, IID_IDirectDraw7, 0 );
    
    	if( result != DD_OK ) {
    
    		MessageBox( 0, "Could not initial 'DirectDraw'!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
    	// ***** Set cooperativlevel *****
    	result = g_lpDD->SetCooperativeLevel( 0, DDSCL_MULTITHREADED | DDSCL_NORMAL );
    	return true;
    }
    
    // ***** Check whether the graficcrad is overlay compatible *****
    bool fOverlayComp( ) {
    
    	DDCAPS ddCaps;
    	HRESULT result;
    
    	memset( &ddCaps, 0, sizeof( DDCAPS ) );
    	ddCaps.dwSize = sizeof( DDCAPS );
    
    	result = g_lpDD->GetCaps( &ddCaps, 0 );
    	if( result != DD_OK ) {
    
    		MessageBox( 0, "Could not get the caps!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
    	if( !( ddCaps.dwCaps & DDCAPS_OVERLAY ) ) {
    
    		MessageBox( 0, "This graficcard is not overlay compatible!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
    	return true;
    }
    
    // ***** Craete the primary surface *****
    bool fCreatePrimSurf( ) {
    
    	DDSURFACEDESC2 ddsd;
    	HRESULT result;
    
    	memset( &ddsd, 0, sizeof( DDSURFACEDESC2 ) );
    	ddsd.dwSize         = sizeof( DDSURFACEDESC2 );
    	ddsd.dwFlags        = DDSD_CAPS;
    	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    
    	result = g_lpDD->CreateSurface( &ddsd, &g_lpPrim, 0 );
    	if( result != DD_OK ) {
    
    		MessageBox( 0, "Could not create the primary surface!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
    	return true;
    }
    
    // ***** Craete the overlay surface *****
    bool fCreateOverSurf( ) {
    
    	DDSURFACEDESC2 ddsd;
    	DDSCAPS2 ddCaps;
    	HRESULT result;
    
    	// ***** Setup the pixelformat *****
    	memset ( &g_ddPF, 0, sizeof( DDPIXELFORMAT ) );
    	g_ddPF.dwSize           = sizeof( DDPIXELFORMAT );
    	g_ddPF.dwFlags          = DDPF_RGB;
    	g_ddPF.dwRBitMask       = 0x00FF0000;
    	g_ddPF.dwGBitMask       = 0x0000FF00;
    	g_ddPF.dwBBitMask       = 0x000000FF;
    	g_ddPF.dwRGBBitCount    = 32;
    
    	memset( &ddsd, 0, sizeof( DDSURFACEDESC2 ) );
    	ddsd.dwSize             = sizeof( DDSURFACEDESC2 );
    	ddsd.dwFlags            = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
    	ddsd.ddsCaps.dwCaps     = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
    	ddsd.dwBackBufferCount  = 1;
    	ddsd.dwWidth            = 110;
    	ddsd.dwHeight           = 160;
    	ddsd.ddpfPixelFormat    = g_ddPF;
    
    	result = g_lpDD->CreateSurface( &ddsd, &g_lpOver, 0 );
    	if( result != DD_OK ) {
    
    		MessageBox( 0, "Could not create the overlay surface!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
    	// ***** Attach the backbuffer to the overlay *****
    	memset( &ddCaps, 0, sizeof( DDSCAPS2 ) );
    	ddCaps.dwCaps = DDSCAPS_BACKBUFFER;
    
    	result = g_lpOver->GetAttachedSurface( &ddCaps, &g_lpBack );
    	if( result != DD_OK ) {
    
    		MessageBox( 0, "Could not attched the backbuffer to the overlay surface!", "Shutdown error!", MB_OK | MB_ICONERROR );
    		return false;
    	}
    
        // Set colorkey RGB( 0, 0, 0 )
        DDCOLORKEY ddColorKey;
    
        memset( &ddColorKey, 0, sizeof( DDCOLORKEY ) );
        ddColorKey.dwColorSpaceHighValue = 0x00000000;
        ddColorKey.dwColorSpaceLowValue  = 0x00000000;
    
        g_lpOver->SetColorKey( DDCKEY_SRCOVERLAY, & ddColorKey );
    
    	return true;
    }
    
    // ***** Update the overlay and repositionate it on screen *****
    bool fUpdateOverlay( const bool bShow ) {
    
    	HDC hDC         = 0; 
    	HDC hDCMem      = 0;
    	RECT descRect   = { 0, 0, 0, 0 };
    	HRESULT result  = 0;
    
    	// ***** Draw something to the backbuffer *****
    	g_lpBack->GetDC( &hDC );
    
    	    hDCMem = CreateCompatibleDC( hDC );
    	    SelectObject( hDCMem, g_hSlots[ 0 ] );
    
    	    int iSlotNumber = 1;
    	    for( int i = 0; i < 3; i++ ) {
    
    	        for( int j = 0; j < 2; j++ ) {
    
    	            // Highlight active slot
    	            if( iSlotNumber == fGetActiveSlot( ) ) {
    
    	                SelectObject( hDCMem, g_hSlots[ 1 ] );
    
    	                // Draw slot
    		            BitBlt( hDC, (j * 50) + 5, (i * 50) + 5, 50, 50, hDCMem, 0, 0, SRCCOPY );
    
    		            SelectObject( hDCMem, g_hSlots[ 0 ] );
    
    	            }
                    else {
    
    	                // Draw slot
    		            BitBlt( hDC, (j * 50) + 5, (i * 50) + 5, 50, 50, hDCMem, 0, 0, SRCCOPY );
    		        }
    
    		        // Go to next slot pos
    		        iSlotNumber++;
    	        }
    	    }
    
    		DeleteDC( hDCMem );
    	g_lpBack->ReleaseDC( hDC );
    
    	// ***** Now flip it to screen *****
    	g_lpOver->Flip( 0, DDFLIP_WAIT );
    
    	// ***** Set position of overlay *****
    	descRect.left   = 50;
    	descRect.top    = 50; 
    	descRect.right  = 160;
    	descRect.bottom = 210;
    
        DWORD dwFlags;
        if( bShow ) {
    
           dwFlags = DDOVER_SHOW | DDOVER_KEYSRC;
        }
        else {
    
            dwFlags = DDOVER_HIDE | DDOVER_KEYSRC;
        }
    
    	result = g_lpOver->UpdateOverlay( 0, g_lpPrim, &descRect, dwFlags, 0 );
    	if( result != DD_OK ) {
    
            if( DDERR_SURFACELOST ) {
    
                g_lpPrim->Restore( );
                g_lpOver->Restore( );       
            }
    
    		return false;
    	}
    
    	return true;
    }
    
    // ***** clearup all dd objects *****
    void fCleanUp( ) {
    
    	// ***** Clear backbuffer surface *****
    	if( g_lpBack != 0 ) {
    
    		g_lpBack->Release( );
    		g_lpBack = 0;
        }
    
    	// ***** Clear overlay surface *****
    	if( g_lpOver != 0 ) {
    
    		g_lpOver->Release( );
    		g_lpOver = 0;
        }
    
    	// ***** Clear primary surface *****
    	if( g_lpPrim != 0 ) {
    
    		g_lpPrim->Release( );
    		g_lpPrim = 0;
        }
    
    	// ***** Clear global dd object *****
    	if( g_lpDD != 0 ) {
    
    		g_lpDD->Release( );	
    		g_lpDD = 0;
        }
    }
    
    //--- EXIT -------------------------------------------------------
    
    Ist das nicht richtig mit dem ::Restore( ) oder wie?
    


  • Also du musst das Restore so programmieren, das es was bringt. f'`8k

    Autocogito

    Gruß, TGGC (Der neue Game Star)



  • Inwiefern richtig programmieren? Ich weiß nicht wirklich wie ich da ran gehen soll undim Netz finden sich auch nicht wirklich DirectDraw Overlay Samples mit Sourecode. Btw das ::Restore( ) sollte die Methode der Surface darstellen.

    Also ich weiß ja nicht, ob ich das Grundprinzip da jetzt richtig verstanden habe, aber sobald eine andere Fullscreen Application in den Fordergrund tritt, verlieren die Primary-, Overlay- und deren Backbuffersurface ihre Gueltigkeit, sprich sie return als Fehler Devicesurface lost. So un ab diesen Moment weiß ich nicht wie ich da richtig reagieren soll.

    Muss ich nun also:
    1. die Primary-, Overlay- und deren Backbuffersurface ::Releas()'n
    2. sie dann neu initialisieren? (wobei hier die Primarysurface sich nicht mehr initialisieren laesst)
    3. und dann ::Restore() ?

    Waer toll, wenn hier evtl. mal einer so eine kleine Grundroutine posten koennte.

    Gruß Tobi



  • Wie Restore funktioniert, steht in der Doku. f'`8k

    Autocogito

    Gruß, TGGC (Der neue Game Star)



  • Weiß ich, aber wirklich geholfen hat es mir nicht.



  • Mehr brauchst du aber nicht wissen. f'`8k

    Autocogito

    Gruß, TGGC (Das kommt gut)



  • Koenntest du mich nicht einfach auf den Fehler in meinem Code hinweisen?



  • Keine Lust und Zeit deinen ganzen Code zu lesen. f'`8k

    Autocogito

    Gruß, TGGC (Das kommt gut)



  • Es wird dich leider nicht weiterbringen, aber hier hast du schonmal einen Flüchtigkeitsfehler:

    if( DDERR_SURFACELOST ) {
    


  • Hatte ich schon behoben, aber bringt mich in der Tat nicht weiter.


  • Mod

    versuchst du zufaellig overlays zu zeichnen waehrend eine _andere_ applikation einen exklusiven, fullscreen zugriff auf das render device hat?



  • Ja. Kannst du mir da weiter helfen?



  • Lass doch die Cheaterei.
    Und beschäftige dich nicht mit DirectDraw 7 (kiloLOL) in 2009.

    http://www.sfml-dev.org

    nichtMFG



  • Was hat Overlay mit Cheaten zu run 😉


  • Mod

    T0bi schrieb:

    Ja. Kannst du mir da weiter helfen?

    ja, hab ich doch schon.
    notfalls schau nach was "exklusiv" bedeutet.


Anmelden zum Antworten