Reaktion auf Maximierung eines Fensters



  • Hallo,

    ich habe eine eigentlich simple Frage:

    Ich habe eine Applikation in DDraw4 geschrieben, die im Fullscreen Modus läuft. Wenn ich nun einen Fehler abfange, dann gebe ich die dazugehörige Fehlerbeschreibung auf einer MessageBox aus, wozu ich das Fenster aber mit ShowWindow(hWnd, SW_MINIMZE) minimiere.

    Jetzt habe ich das Problem, das der User entscheiden kann, ob er trotz des Fehlers weitermachen will oder nicht. Wenn er ja anklickt, dann muss die Applikation also ganz normal weitergeführt werden. Nur habe ich das Problem, dass dies nicht klappt. Die Anwendung zeigt also einfach einen schwarzen Bildschirm!

    Meine Frage: Welche Schnittstellen muss ich reinitialisieren, damit DDraw/seine Surfaces richtig verwendet werden können? Sagt mir erstmal nur die Schnittstellen, ich probiere das dann selber, wenn ich dann nochmal fragen muss dann könnt ihr mir auch SourceCode posten. Wenn ihr SourceCode schon da habt, stört der aber natürlich auch nicht 🙂

    THX
    PH



  • *push*

    Wenn ihr denkt, das niemand im Forum das weiß, dann sagt mir das 🙂
    Dann höre ich auch auf zu pushen 😛

    PH



  • Naja, DirectDraw ist ja schon was älter 🙂
    Such mal nach Reset oder Restore...



  • Also ich habe jetzt indirekt was gefunden, werde es heute mal ausprobieren und dann berichten ob es geklappt hat 🙂

    3. Losing Surfaces

    One very important area of robustness that the code samples above ignored is what happens if the user switches away from a fullscreen DirectDraw app to some other app running in the system. First of all, your code needs to handle the WM_ACTIVATEAPP message and set a flag when your app goes inactive. In the idle section of your PeekMessage loop, check this flag, and don't try to update your display when you're not active.

    But the real issue is that once you switch to another app, you have left the DirectDraw environment and allowed GDI to become active. GDI is oblivious to DirectDraw, and will overwrite the areas of display memory in use by your DirectDraw surfaces. This means that your bitmaps get wiped out and will need to be reloaded. Fortunately, when you call a function that operates on a surface, such as Flip() or BltFast(), DirectDraw will return an error of DDERR_SURFACELOST to let you know if the surface was lost. So, your code has to check for this error and reload the bitmaps into the surfaces if this error occurs.

    ddrval = lpDDSPrimary->Blt( &rcRectDest, lpDDSBack, &rcRectSrc, DDBLT_WAIT, NULL);
    if( ddrval == DDERR_SURFACELOST )
    {
    ddrval = restoreAll();
    }

    ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT);

    if( ddrval == DDERR_SURFACELOST )
    {
    ddrval = restoreAll();
    }
    :
    :

    void restoreAll()
    {
    // for each surface your app has created you should do the following:
    ddrval = lpMyDDSurface->Restore(); // this reattaches the video memory to the surface
    if( ddrval == DD_OK )
    {
    lpTempDDS ->DDReLoadBitmap(); // this will be the same as the function above
    // that was originally used to load the bitmap
    // with the exception that the surface is already
    // created and ready to go
    }
    }

    Klar ist DDraw alt, deswegen lerne ich ja auch bald D3d&co...

    PH

    [ Dieser Beitrag wurde am 03.02.2003 um 13:34 Uhr von Programator editiert. ]



  • So, ich habe jetzt versucht, das was in dem Artikel stand, mal in etwas Code umzusetzen.

    Ich habe also vor der Hauptschleife eine Abfrage, ob die Anwendung aktiv ist, wenn sie das ist, wird gezeichnet, wenn nicht, dann zeichnet die Anwendung auch nicht.

    Vor/nach jedem BltFast Aufruf habe ich den folgenden Code:

    Result=lpDDBackSurface->BltFast(ShieldxBltPos,ShieldyBltPos,lpDDShieldSurface,&rctShield,DrawFlags);
    if(FAILED(Result))
    {
        if(Result==DDERR_SURFACELOST)
            ReInitWindow();
        else
            return -1;
    }
    

    Dann habe ich noch die Funktion ReInitWindow, welche nach einem Fehlschlag von Bltfast mit der Fehlermeldung DDERR_SURFACELOST aufgerufen wird.

    HRESULT RestoreResult;
    
    RestoreResult=lpDDPlayerSpaceShipSurfaces->Restore();
    if(FAILED(RestoreResult))
    {
        if(RestoreResult==DDERR_GENERIC)
            LogDataFile<<GetTime()<<"DDERR_GENERIC "<<endl;
        else if(RestoreResult==DDERR_IMPLICITLYCREATED)
            LogDataFile<<GetTime()<<"DDERR_IMPLICITLYCREATED"<<endl;
        else if(RestoreResult==DDERR_INCOMPATIBLEPRIMARY)
            LogDataFile<<GetTime()<<"DDERR_INCOMPATIBLEPRIMARY"<<endl;
        else if(RestoreResult==DDERR_INVALIDOBJECT)
            LogDataFile<<GetTime()<<"DDERR_INVALIDOBJECT"<<endl;
        else if(RestoreResult==DDERR_INVALIDPARAMS)
            LogDataFile<<GetTime()<<"DDERR_INVALIDPARAMS"<<endl;
        else if(RestoreResult==DDERR_NOEXCLUSIVEMODE)
            LogDataFile<<GetTime()<<"DDERR_NOEXCLUSIVEMODE"<<endl;
        else if(RestoreResult==DDERR_OUTOFMEMORY)
            LogDataFile<<GetTime()<<"DDERR_OUTOFMEMORY"<<endl;
        else if(RestoreResult==DDERR_UNSUPPORTED)
            LogDataFile<<GetTime()<<"DDERR_UNSUPPORTED"<<endl;
        else if(RestoreResult==DDERR_WRONGMODE)
            LogDataFile<<GetTime()<<"DDERR_WRONGMODE"<<endl;
    
        OnFailed("Error restoring Surface",__FILE__,__LINE__);
    }
    RestoreResult=lpDDPlayerShotSurface->Restore();
    if(FAILED(RestoreResult))
        OnFailed("Error restoring Surface",__FILE__,__LINE__);
    

    Der Fehler besteht jetzt darin, das ich beim Aufrufen der Methode Restore() einen Fehler bekommen, undzwar DDERR_WRONGMODE, OnFailed(meine Fehlermelderoutine) meldet in den LogFiles folgendes:

    20:10:42 ***On Failed reported the following error:***
    20:10:42 Error restoring Surface
    20:10:42 File: E:\Programming\C++Samples\Bücher\DirectX Programming\ownDX\SpaceBuster\Space Buster Game\Space Buster.cpp
    20:10:42 Line: 2171
    20:10:43 The User has decided to ignore the error, Space Buster will resume now...
    20:10:43 DDERR_WRONGMODE

    In der Doku zu DX7(DDraw7) steht zu diesem Fehlercode folgendes:

    DDERR_WRONGMODE

    This surface cannot be restored because it was created in a different mode.

    So und jetzt kommt meine Frage: 🙂

    welcher Modus ist gemeint/Wie muss ich die Surface erstellen/restoren, damit es klappt/wenigstens die Funktion Restore() schonmal läuft!

    Und sagt bitte nicht wieder DDraw wäre zu alt 🙂

    THX
    PH

    [ Dieser Beitrag wurde am 05.02.2003 um 20:29 Uhr von Programator editiert. ]



  • if(RestoreResult==DDERR_GENERIC)
            LogDataFile<<GetTime()<<"DDERR_GENERIC "<<endl;
        else if(RestoreResult==DDERR_IMPLICITLYCREATED)
            LogDataFile<<GetTime()<<"DDERR_IMPLICITLYCREATED"<<endl;
        else if(RestoreResult==DDERR_INCOMPATIBLEPRIMARY)
            LogDataFile<<GetTime()<<"DDERR_INCOMPATIBLEPRIMARY"<<endl;
        else if(RestoreResult==DDERR_INVALIDOBJECT)
            LogDataFile<<GetTime()<<"DDERR_INVALIDOBJECT"<<endl;
        else if(RestoreResult==DDERR_INVALIDPARAMS)
            LogDataFile<<GetTime()<<"DDERR_INVALIDPARAMS"<<endl;
        else if(RestoreResult==DDERR_NOEXCLUSIVEMODE)
            LogDataFile<<GetTime()<<"DDERR_NOEXCLUSIVEMODE"<<endl;
        else if(RestoreResult==DDERR_OUTOFMEMORY)
            LogDataFile<<GetTime()<<"DDERR_OUTOFMEMORY"<<endl;
        else if(RestoreResult==DDERR_UNSUPPORTED)
            LogDataFile<<GetTime()<<"DDERR_UNSUPPORTED"<<endl;
        else if(RestoreResult==DDERR_WRONGMODE)
            LogDataFile<<GetTime()<<"DDERR_WRONGMODE"<<endl;
    

    Schonmal was von switch/case gehört?



  • Ja...

    Aber tut das irgendwas wichtiges zur Sache?
    Beides funktioniert, und auf die Performance würde es auch nicht ankommen, wobei ich noch nichteinmal glaube das switch/case da allzuviel schneller ist.

    PH


Anmelden zum Antworten