InvalidateRect arbeitet unzuverlässig



  • Hallo,

    Ich habe eine Aufzählung mittels enum in einer Headerdatei, die global ist (die Aufzählung). Momentan verwende ich diese Aufzählung aber nur in zwei .cpp Dateien, einmal in einer, wo ich sie auch definiere (den ersten Wert der Aufzählung zuweise), und in der anderen verwende ich sie nur.

    // global.h
    
    enum singlePlayer
    {
      sPchoose,
      sPchose,
      sPchosecom,
      sPgame   
    };
    
    extern singlePlayer sPstate;
    

    Nun arbeite ich momentan in meiner WindowsProcedure, dort verändere ich entweder in der WM_KEYDOWN Message den Wert von sPstate oder auch in der WM_PAINT, da es kein Key Event gibt.

    Jetzt das Problem in WM_PAINT:

    ich lasse erst den Nutzer vor dem Rechner quasi eine Grafik wählen. Das Funktioniert auch und man bestätigt mit VK_RETURN. Ich lasse dann aber quasi die Grafik nochmal anzeigen, also die Grafik, die der Nutzer gewählt hat:

    /////////////// BLOCK 1
    
    if(sPstate == sPchose)
    {
      SelectObject(hDeCo, hFONTtext);
    
      if (p1_char == 1)
      {
        wDshowText(hDeCo, "You chose\nDonald Duck...", &recStrText, 26, 0, DT_CENTER | DT_WORDBREAK);          
        SelectObject(hDeCoMem, hBMPdonald);
        TransparentBlt(hDeCo, wDcalcPosition(wcwidth, (BMPdonald.bmWidth / 2)), 170, (BMPdonald.bmWidth / 2), (BMPdonald.bmHeight / 2), hDeCoMem, 0, 0, BMPdonald.bmWidth, BMPdonald.bmHeight, RGBtransparent);
      }
    
      // ... usw
    
      sPstate = sPchosecom;
      Sleep(3500);
      InvalidateRect(WPhwnd, NULL, 1);
    }
    

    Das Programm wartet also 3,5 Sekunden, verändert vorher den sPstate und das ganze Fenster soll neu gezeichnet werden.
    Klappt auch.

    Dann wären wir beim neuen Status, der geht so:

    /////////////// BLOCK 2
    
    if(sPstate == sPchosecom)
    {
      SelectObject(hDeCo, hFONTtext);
    
      if (p2_char == 1)
      {
        wDshowText(hDeCo, "Your oponent is\nDonald Duck...", &recStrText, 26, 0, DT_CENTER | DT_WORDBREAK);          
        SelectObject(hDeCoMem, hBMPdonald);
        TransparentBlt(hDeCo, wDcalcPosition(wcwidth, (BMPdonald.bmWidth / 2)), 170, (BMPdonald.bmWidth / 2), (BMPdonald.bmHeight / 2), hDeCoMem, 0, 0, BMPdonald.bmWidth, BMPdonald.bmHeight, RGBtransparent);
      }
                // usw...
    
      //sPstate = sPgame;
      //Sleep(3500);
      //InvalidateRect(WPhwnd, NULL, 1);
    }
    

    So klappt es auch. Um nochmal kurz zusammen zufassen. Der Nutzer wählt eine Grafik und bestätigt mit Enter. Diese wird 3,5 Sekunden angezeigt. Dann wählt der Computer eine andere Grafik, was auch funktioniert. Diese wird momentan solange angezeigt, bis ich das Programm beende.

    Wenn ich jetzt die letzten drei Zeilen aus BLOCK 2 wieder aus dem Kommentar rausnehme, dann funktioniert schon der InvalidateRect vom BLOCK 1 nicht mehr. Der legt die zweite Grafik einfach über die 1. Grafik. Wenn ich die letzten drei Zeilen in BLOCK 2 wieder auskommentiere, funktioniert es normal und er zeichnet die 2. Grafik NICHT über die 1. Grafik sondern neu, so wie es sein soll.

    Meine Frage ist, wieso er ein Problem damit bekommt, wenn ich schon sPstate im zweiten Block einfach nur verändere??? Wieso funktioniert dann das InvalidateRect von Block 1 nicht mehr?

    Falls das Problem unklar ist, kann ich auch mehr von der source Datei posten.
    Über Hilfe wäre ich dankbar.

    Gruß,
    Paddle



  • Okay,

    Schon selbst gelöst 😃
    Ich hatte zwar ein

    DeleteDC(hDeCoMem);      
    EndPaint(WPhwnd, &ps);
    return 0;
    

    ganz unten in der WM_PAINT Nachricht stehen, aber scheinbar
    muss er in WM_PAINT so ungünstig durch den Aufruf von InvalidateRect hin und
    hergesprungen sein, dass nur der Aufruf ganz unten nicht mehr gereicht hat.
    Ich habe diesen Block jetzt überall stehen, wo ich wirklich auch fertig
    bin mit Malen, und so funktioniert es.

    Ist auch in sofern effizienter weil im günstigsten Fall natürlich einige Abfragen
    ausbleiben, da ja schon 0 zurück gegeben wird.

    Danke trotzdem fürs Lesen.


Anmelden zum Antworten