LPDIRECTDRAW->Lock(...) Fehler
-
mhh laut Buch nicht und hat in diesem Fall auch keine Veränderung hervorgerufen.
Komisch ist halt, dass ohne Lock keine Fehler auftauchen. Erst wenn ich Locke und Unlocke bekomme ich durch das Failed Makro einen Fehler (das Makro um den Lock). Und wenn ich das Makro weglasse und zwischen Lock und Unlock schreiben will, dann bekomme ich die Meldung, dass in den Speicher nicht geschrieben werden kann.
Und am Displaymode sollte es auch nicht liegen denn 32 Bit unterstützt die Graka auf jeden Fall.
-
Ok ich hab neue Erkenntnisse gewonnen... Nachdem ich den Code aus dem Buch kopiert habe, das schreiben in den Speicher. Das Failed Makro liefert auch keinen Fehler, solange ich das Fenster geöffnet lasse. Sobald ich das Fenster minimiere, wird ein Fehler gemeldet sprich das FAILED Makro gibt true zurück.
Wie lässt sich das erklären?
Und sobald ich das Fenster wieder Maximiere, wird nichts mehr auf das Surface gezeichnet.
-
-
Hast du es auch schon mal mit Restore() versucht, nach dem das flipen fehlgeschlagen hat?
EDIT: ahh, da war jemand schneller

-
mhhh ok wenn ich das richtig verstehe müsste ich in meiner Gameschleife überprüfen ob der Surfacememory verloren gegangen ist und wenn ja, dann muss ich Restore() aufrufen.
Und der Surfacememory geht dann verloren, sobald ich das Fenster minimiere, richtig?
Und 2. Problem:
Wie ich jetzt rausgefunden habe, bekomme ich nur dann eine Meldung, dass nicht in den Speicher geschrieben werden kann ("Die Anweisung ... verweist auf Speicher in ... . Der Vorgang written konnte nicht durchgeführt werden."), wenn ich den Lock nicht mit dem FAILED Makro überprüfe. Sprich wenn ich das FAILED Makro um den Lock setze, läuft alles wunderbar. Lasse ich es weg, läuft das Programm, aber beim Beenden kommt die Meldung von Windows. Allerdings verstehe ich nicht, warum ich unbedingt das FAILED Makro setzen muss://funktioniert: if (FAILED(lpddsprimary->Lock(...))) return 0; //funktioniert nicht (Fehlermeldung von Windows): lpddsprimary->Lock(...);EDIT: Jetzt hab ich es glaube ich: Sobald ich das Fenster schließe, geht der Speicher verloren. Aber die Schleife wird noch mind. einmal durchlaufen. Und dann geht der Zugriff nicht mehr. Nachdem ich jetzt eine zusätzliche Variable eingefügt habe, die testet, ob das Fenster geschlossen werden soll, klappt es.
Zumindest das zweite Problem...
Jetzt muss ich noch das mit dem Minimieren hinbekommen. Kann mir da vielleicht jemand einen Tipp geben, wo ich mit dem Restore arbeiten muss, damit nach dem Maximieren wieder gezeichnet wird?
-
Wie ich jetzt rausgefunden habe, bekomme ich nur dann eine Meldung, dass nicht in den Speicher geschrieben werden kann, wenn ich den Lock nicht mit dem FAILED Makro überprüfe
na klar - beachte das schluesselwort "if":
dein surface wird nur beschrieben, wenn es gelockt werden konnte.
in einen nicht mehr existenten speicherbereich zu schreiben ist prinzipiell keine gute idee.
-
Ok soweit ist klar... (Hätte ich auch selbst drauf kommen können ich Trottel)
Nur was kann ich machen um das Problem mit dem Minimieren zu beheben? Hab das jetzt mal mit dem IsLost und Restore probiert aber es hat nicht geklappt. Wo müsste ich das ganze überprüfen und dann restoren? Nach dem Lock? Oder muss ich eine Windowsmessage abfangen, die beim Minimieren und Maximieren gesendet wird?
-
du reagierst auf den fehlercode der methoden von IDirectDraw und IDirectDrawSurface.
-
Ich hab das ganze jetzt so gelöst:
HRESULT result; result=lpddsprimary->Lock(NULL, &ddsurfdesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); if (result==DD_OK) { ULONG * video_buffer = (ULONG *)ddsurfdesc.lpSurface; video_buffer[0] = BUILD32RGB(0,255,255,255); } else lpddsprimary->Restore(); if (FAILED(lpddsprimary->Unlock(NULL))) return 0;Gibts noch eine schönere Lösung, um irgendwie die Zeichenaktionen aus der Abfrage zu bekommen und trotzdem die Abfrage zu schaffen? Hab schon verschiedene if-Kombinationen probiert aber das ist bis jetzt das einzige was funktioniert. Bei den anderen schließt er meistens mein Fenster sobald ich es wieder maximiere.
EDIT:
Wie ist es mit dieser Variante? Funktioniert auch und ist meiner Meinung nach besser. Wie seht ihr das?result=lpddsprimary->Lock(NULL, &ddsurfdesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); if (result!=DD_OK) { lpddsprimary->Restore(); return 0; } ULONG * video_buffer = (ULONG *)ddsurfdesc.lpSurface; video_buffer[0] = BUILD32RGB(0,255,255,255); if (FAILED(lpddsprimary->Unlock(NULL))) return 0;
-
Ich mache es normalerweise ca. so:
void Foo::Bar() { HRESULT hr = m_lpdds->Lock(...); if(hr == DDERR_SURFACELOST) { TryRestore(); hr = m_lpdds->Lock(...); } if(FAILED(hr)) ThrowDDException(hr); // ... (use lock) VERIFY(SUCCEEDED(m_lpdds->Unlock())); } void Foo::TryRestore() { if(m_lpdds->IsLost() != DDERR_SURFACELOST) { // try restore if(SUCCEEDED(m_lpdds->Restore())) OnSurfaceRestored(); } } void Foo::OnSurfaceRestored() { // restore surface contents }