Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

1

03.10.2010, 22:48

Microsoft C++-Ausnahme beim Werfen einer Exception

Hallo,

seit kurzem habe ich mich mal wieder mit DirectX beschäftigt und damit angefangen, die Hauptbestandteile einer entsprechenden Win32-Anwendung in Klassen zu kapseln. Bisher habe ich nur ein Fenster geöffnet und Direct3D initialisiert. Es läuft auch soweit problemlos, wenn ich allerdings zum Testen meiner Fehlerbehandlung absichtlich eine Exception aus einer Methode meiner Direct3D-Klasse werfe, wird nicht wie erwartet eine MessageBox mit der Fehlerbeschreibung geöffnet, sondern Visual Studio 2010 gibt "Eine Ausnahme (erste Chance) bei 0x7c812afb in Direct3D.exe: Microsoft C++-Ausnahme: Exception an Speicherposition 0x0012fbd0." aus ?( Mein Hauptprogramm sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int cmdShow)
{
DEBUG_STACK;

// Name der Anwendung
const tstring title(TEXT("Direct3D"));

try
{
    Window w(hInstance, title);
    Direct3D d3d(w, 640, 480, true);

    while(w.processEvents())
    {
        d3d.beginScene();
        d3d.endScene();
        d3d.present();
    }
}
catch(const Exception& e)
{
    MessageBox(NULL, e.what().c_str(), title.c_str(), MB_OK | MB_ICONERROR);
}

return 0;
}

Bevor ich hier noch mehr Code hineinkopiere: Ich habe bereits einen Breakpoint auf Zeile 22 gesetzt und die Stelle wird auch erreicht. Drücke ich dann F10 höre ich sogar den Error-Sound (wenn ich das MB_ICONERROR entferne tritt dieser nicht auf, er muss also von der MessageBox stammen), die MessageBox ist jedoch nicht sichtbar. Das Programm läuft anschließend sogar ganz normal weiter bis zum return 0; und beendet sich (scheinbar) problemlos. In VS 2010 taucht dann aber wie gesagt anschließend die genannte Meldung in der Ausgabe auf.

Eine weitere Beobachtung konnte ich bereits machen: Wenn ich im Destruktor der Window-Klasse das DestroyWindow() auskommentiere, wird die MessageBox normal angezeigt (obwohl diese doch mit meinem Hauptfenster eigentlich gar nichts zu tun hat), die Meldung erscheint nach Beendigung des Programms aber trotzdem.

Vielleicht könnt ihr mir ja weiterhelfen. Falls ihr gezielt weitere Codestellen benötigt, reiche ich diese gerne nach. Ich wollte nur nicht gleich das ganze Projekt posten, damit es hier zu nicht unübersichtlich wird :)
;)

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

2

03.10.2010, 23:44

Es wäre evtl. doch interessant zu wissen, was die Klasse "Window" macht. Ich vermute, dass Window w beim Auslösen der Exception abgebaut wird, w wird zerstört, der Destruktor wird aufgerufen und dieser schließt das Hauptfenster, wodurch die Anwendung geschlossen wird.

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

3

04.10.2010, 00:29

Die Klasse Window macht nichts weiter, als die Fensterklasse mit RegisterClassEx() zu registrieren, das Fenster mit CreateWindowEx() zu erstellen und in der klassischen Schleife Nachrichten abzuholen und darauf zu reagieren. Im Destruktor werden dann DestroyWindow() und UnregisterClass() aufgerufen.

Ich habe inzwischen herausgefunden, dass die Meldung von Visual Studio nur auf eine ausgelöste Exception hinweist, die im Programm behandelt wird (also mehr eine Information als ein Fehler). Dennoch bleibt das Problem, dass die MessageBox nicht angezeigt wird (sondern nur der Error-Sound selbiger abgespielt wird).

An der Direct3D-Klasse scheint es im Übrigen nicht (direkt) zu liegen: Wenn ich das ganze Direct3D-Objekt im Hauptprogramm weglasse und nur ein Window-Objekt erstelle und aus dessen Methoden eine Exception auslöse, tritt genau dasselbe Problem auf. Auch hier löst das Auskommentieren von DestroyWindow() im Destruktor der Window-Klasse scheinbar das Problem. Aber das kann ja keine vernünftige Lösung sein.
;)

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

4

04.10.2010, 14:06

Eigentlich müsstest du DestroyWindow() doch gar nicht aufrufen, da das Window doch sowieso zerstört wird, wenn die Anwendug beendet wird. DestroyWindow() schließt dein Parentwindow, wodurch die Anwendug geschlossen wird. Deswegen wird die MessageBox nicht angezeigt.

http://msdn.microsoft.com/en-us/library/ms632682(VS.85).aspx

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

5

07.10.2010, 11:55

Falls es noch jemanden interessiert: Es liegt nicht direkt an DestroyWindow(), sondern am dadurch ausgelösten Aufruf von PostQuitMessage(). Dieser sorgt aber offenbar sonst nur dafür, dass GetMessage() bzw. PeekMessage() aus der Hauptschleife herausspringen. Wenn man das also durch ein entsprechendes Flag ersetzt, kann man PostQuitMessage() umgehen und das Programm dennoch ordnungsgemäß beenden.
;)

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

6

07.10.2010, 12:04

Dieser sorgt aber offenbar sonst nur dafür, dass GetMessage() bzw. PeekMessage() aus der Hauptschleife herausspringen.


Warum herumspekulieren, wenn man einfach mal in der Doku nachlesen, was die Funktion tatsächlich macht?

Zitat von »MSDN«

The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message.

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

7

07.10.2010, 12:10

Was heißt hier "herumspekulieren"? Dass GetMessage() bei WM_QUIT 0 zurückgibt und somit aus der Hauptschleife springt, ist ja wohl bekannt. Mir ging es darum, herauszufinden, ob PostQuitMessage() darüber hinaus noch etwas wichtiges erledigt, was durch ein einfaches Flag dann nicht abgedeckt wäre. In diesem Fall wäre der Workaround natürlich nicht "zulässig", doch darüber macht dein MSDN-Eintrag eben leider keine deutlichen Aussagen.
;)

Werbeanzeige