D3D device release bei DestroyWindow notwendig?
-
Danke für die Tips.
MfG
EDIT:
Hmm @TGGC, scheint nicht hinzuhauen, danach kann ich nicht mehr minimieren, der Desktop flackert nur hindurch:wc.lpfnWndProc = MsgProc; wc.lpszClassName = "Main2"; RegisterClass(&wc); d3dPP.hDeviceWindow = CreateWindow("Main2", 0, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); d3dDev->Reset(&d3dPP); UnregisterClass("Main", 0); DestroyWindow(windowHandle);Meine Frage war ja, ob ein Reset bei einem window change ausreichen würde, oder ob man um ein Release & Create nicht herumkommt...
MfG
-
Ok dann nehm ich mal an, dass es ohne erneutem CreateDevice nicht geht.
Noch eine Frage:Wird d3dPP.hDeviceWindow benötigt? Werd aus der msdn Hilfe ned ganz schlau. Wenn ich es nicht initialisiere, passt trotzdem alles, zumindest im fullscreen mode.
MfG
-
So bisschen Fehlercodes abfragen usf. waere sicher nicht verkehrt. f'`8k
AutocogitoGruß, TGGC (making great games since 1992)
-
Bezieht sich vermutlich nicht auf die letzte Frage. CreateDevice gibt keinen Fehlercode zurück, wenn ich d3dPP.hDeviceWindow weglasse.
-
Reset reicht zum wechseln zw. FullScreen und Windowed modus. Jedoch nicht wenn Du z.B. während der Fenstermodus läuft die Auflösung ändern willst. Denn beim erstellen des Direct3D Devices musst Du ja das Handle vom Fenster übergeben, das ist natürlich beim neu-erstellen eines Fensters nichtmehr valid. Edit: Mit Reset() wird ja nicht das ganze Direct3DDevice neu erstellt und so wird wahrscheinlich ein neues Window-Handle einfach ignoriert. Leider ist das soviel ich weiss nicht dokumentiert.
Du kannst auch versuchen mit MoveWindow zu arbeiten, das ist aber meines erachtens nicht so eine schöne Angelegenheit.
Da ich sowieso relativ API-Unabhänig programmiere mach ich da so:
Direct3D Surfaces etc. releasen.
Direct3D runterfahren (komplett).
Fenster zerstören.
Fenster neu erstellen.
Direct3D mit neuem Fenster-Handle neu initialisieren.
Direct3D Surfaces etc. neu laden.Gruss, Andi
Edit:
TGGC:
- neues Fenster erstellen
- D3D freigeben
- D3D neu erstellen in neuen Fenster
- altes Fenster schliessenIch denke nicht dass es sinvoll ist, kurzzeitig zwei Fenster zu haben wenn man doch nur eines braucht. Weil da muss man dann zwei Handles speichern und aufpassen mit der Window-Prozedur.
-
hier stand müll
-
Jo danke Andi. Aber sobald ich DestroyWindow() aufrufe, schließt sich auch mein Programm...
Deshalb:
while(message.message != WM_QUIT) HauptschleifeWie könnte ich das am elegantesten verhindern?
MfG
-
Hast du nen WinProc (Message-Handler)?
Dann füg das WM_QUIT dort ein und benachrichtige eine Funktion einer Klasse, dass das Fenster geschlossen hat. Dann prüfst du ne Variable, ob das Programm geschlossen werden soll, oder nur das Fenster neu gebaut wird. Und für die while-Schleife nimmst eine andere Bedingung.
rya.
-
Das versteh ich nicht. WM_QUIT wird doch von PeekMessage() in der Hauptschleife empfangen. In meinem MessageHandler hat das doch nix zu suchen? Da wird ja nur auf WM_DESTROY reagiert.
Globale Variablen oder nen Singleton möchte ich eben vermeiden.
MfG
-
Andi001 schrieb:
Ich denke nicht dass es sinvoll ist, kurzzeitig zwei Fenster zu haben wenn man doch nur eines braucht.
Wenn man nur eines braucht, warum will man es dann ueberhaupt wechseln? f'`8k
AutocogitoGruß, TGGC (making great games since 1992)
-
Jo hast recht... hab mich vertan -.- Naja nimm halt einfach ne andere abfrage für deine schleife und lass WM_QUIT raus...
EDIT: Aber WM_QUIT wird doch nur durch ::PostQuitMessage() ausgelöst? Warum beendet sich dann deine Anwendung wenn du das Fenster zerstörst?
The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.
rya.
-
@TGGC
Um die Fenstergröße zu ändern, wenn man in den Fenstermodus geht. Der Benutzer könnte ja die Desktop-Auflösung geändert haben.@Scorcher24
LRESULT WINAPI MsgProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { if(message == WM_DESTROY) PostQuitMessage(0); return DefWindowProc(windowHandle, message, wParam, lParam); }Ich werd wohl einfach PeekMessage() in meiner Hauptklasse aufrufen.
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { Game game; game.Tick(); }MfG
EDIT:
Ich weiß grad echt nicht, warum ich nicht einfach MoveWindow() verwende. Sollte doch funktionieren...
-
Man braucht keine neues Fenster, um die Größe zu verändern. Warum probierst du es nicht einfach aus, mit der Maus das Fenster auseinander zu ziehen und stellst fest, dass es geht, einfach so? Um die Auflösung anzupassen reicht dann auch ein Reset.
-
Ich mein aber die Fenstergröße und Position anzupassen, wenn die Anwendung im Fenstermodus ist, damit das Fenster dann in der Mitte liegt.
Achja, warum funktioniert das nicht:
SetWindowLong(windowHandle, GWL_STYLE, WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE); SetWindowPos(windowHandle, HWND_NOTOPMOST, 0, 0, 640, 480, SWP_FRAMECHANGED);Der STYLE wird nicht verändert.
MfG
-
Weiß ich doch nicht. Ich benutze .Net und kenne nicht die äquivalenten Windows API aufrufe. Ich kann mein Form resizen und verschieben. Du musst dafür kein neues Fenster erstellen.
-
Jo hab ich auch eben rausgefunden

Die Frage war ja ned direkt an dich gerichtet.MfG
EDIT:
Ich frag das lieber im WINAPI Forum
-
TGGC schrieb:
Andi001 schrieb:
Ich denke nicht dass es sinvoll ist, kurzzeitig zwei Fenster zu haben wenn man doch nur eines braucht.
Wenn man nur eines braucht, warum will man es dann ueberhaupt wechseln? f'`8k
AutocogitoGruß, TGGC (making great games since 1992)
Aus dem Grund wie ich weiter oben in meinem Post geschrieben habe. Z.B. OpenGL<->Direct3D Renderer-Wechsel, nicht zu vergessen Window-Style änderungen (Fullscreen ohne Border, Fenstermodus mit Border etc.). Sollte Dir eigentlich klar sein, weil Du ja schon so lange hier bist...
Wegen dem anderen Problem: Das Programm schliesst sich, weil Du wahrscheinlich die WM_DESTORY-Message abfängst. Immer wenn Du mit DestroyWindow() ein Fenster zerstörst, bekommt dessen Window-Prozedur natürlich die WM_DESTROY-Nachricht. Reagiert deine WindowProzedur mit dem Beendes des Programms darauf, ist dann natürlich nicht nur das Fenster geschlossen

Edit:
Hier ein kleines Schnippsel aus meinem Prog was bei der Lösung helfen könnte:
case WM_DESTROY: // Wenn die Auflösung gewechselt wird, wird das Fenster zerstört. // Dies wird jedoch von Platform::createWindow()/Platform::destroyWindow() // schon richtig gehandhabt. Also mache ich einfach nichts, da das Fenster // schon richtig zerstört wurde. So wird keine PostQuitMessage(0) geschickt, // die das ganze Programm beenden würde. break; case WM_CLOSE: // Löst ein QuitEvent aus. PostQuitMessage(0); return 0;Edit 2: (uhm bin heute nur am Editieren^^)
Also das mit der PostQuitMessage(0) ist halt so, dass man normalerweise in der Schleife guckt ob die Message == WM_QUIT ist und reagiert darauf mit dem beenden des Programms. Sendet man also bei WM_DESTROY ein Quit-Signal, wird das ganze Programm beendet. Bei mir wird dabei halt dann ein QuitEvent an die Applikation gesendet.
-
Jo danke Andi, aber man muss kein neues Fenster erstellen:
void Window::changeWindow(bool fullscreen, int width, int height) { if(fullscreen) { SetWindowLong(windowHandle, GWL_STYLE, WS_POPUP | WS_VISIBLE); SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED); } else { SetWindowLong(windowHandle, GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE); SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, width, height, SWP_FRAMECHANGED); } }MfG
-
Wird dabei wirklich der Fenster-Style geändert? Bei mir hat das meistens nicht geklappt.
Naja ich muss sowieso das Fenster neu erstellen bei mir, wenn Renderer-Wechsel angesagt ist. Von daher ist das egal

Bei der Höhe und Breite deines Fensters, fehlt aber doch der Border oder? Wenn Dein Programm 1024x768 rendert z.B. fehlen da ein paar Pixel dann im Client-Bereich wenn Du deine Funktion mit diesen Werten aufrufst. Betrifft nur den Fenstermodus.
Andi001
-
Andi001 schrieb:
Aus dem Grund wie ich weiter oben in meinem Post geschrieben habe. Z.B. OpenGL<->Direct3D Renderer-Wechsel, nicht zu vergessen Window-Style änderungen (Fullscreen ohne Border, Fenstermodus mit Border etc.). Sollte Dir eigentlich klar sein, weil Du ja schon so lange hier bist...
Ja, ich bin schon laenger da. Aber bisher hat mir noch niemand erzaehlt, das wenn ich Fenstergroessen und Stile nur an neuen Fenstern greaendert werden duerfen. Ist das ein neues Feature von Vista?

Gruß, TGGC (making great games since 1992)