Crash nach GDI+-Funktion
-
Bei Entdeckung einer bestimmten Message an die Haupt-Fensterprozedur lasse ich eine Funktion "draw" ausführen, die mithilfe der GDI+ eine Form anzeigen soll und wie folgt lautet:
void draw(HWND hwnd) { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; PAINTSTRUCT ps; HDC hdc; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); hdc = BeginPaint(hwnd, &ps); Graphics graphics(hdc); Pen pen(Gdiplus::Color(255, 0, 0, 255), 5); graphics.DrawRectangle(&pen, 0, 0, 200, 100); EndPaint(hwnd, &ps); GdiplusShutdown(gdiplusToken); }Da scheint es irgendwo einen Fehler zu geben, der das ganze zum Absturz bringt, NACHDEM die Funktion komplett ausgeführt wurde. Wenn man aber nach jeder Zeile eine MessageBox in der Funktion selbst einfügt, dann wird die noch angezeigt. Eine MessageBox nach dem Funktionsaufruf aber nicht mehr. Zudem lässt sich der Fehler vermeiden, wenn man die Zeilen 10-12 auskommentiert.
Irgendeine Idee, was hier dahinterstecken könnte?
-
Niemand 'ne Idee?
-
Mittlerweile scheint es zu gehen. Aber auch nur, wenn ich das ganze in einem case-Block, der von der Message WM_PAINT ausgelöst wurde, ausführen lasse. In WM_INITDIALOG ging es nicht. Ich habe aber schon viele Codebeispiele im Internet gesehen, aus denen man eigentlich schließen könnte, dass das egal ist.
Also, mache ich hier irgendwas falsch, oder ist das tatsächlich so? Bitte um Aufklärung!
-
Das Problem ist, dass deine GDI+-Objekte noch "leben", wenn du GdiplusShutdown aufrufst, denn da sie Autovariablen sind, werden sie erst zerstört, wenn der Block beendet ist, in dem sie angelegt worden sind. Das ist bei dir der Fall, wenn diese draw-Funktion an ihrem Ende angekommen ist.
Du kannst die GDI+-Objekte in ihren eigenen Scope-Block einschließen, dann klappt das. Es ist aber sowieso ein wenig seltsam, für jeden Zeichenvorgang GdiplusStartup und GdiplusShutdown aufzurufen. Das ist in etwa so, als ob du beim Laufen für jeden einzelnen Schritt die Schuhe an- und wieder ausziehst. Mach das einmal, am Anfang und am Ende des Programms (Ende heißt natürlich, nachdem alle GDI+-Objekte zerstört wurden).
-
Ja, ich dachte mir schon sowas in der Art.
Nee, das was ich da im Moment mache ist nur einmal ein einziger Zeichenvorgang zum Test. Wenn ich später mehr habe, dann werde ich das natürlich auch anders managen.
-
Trotzdem gehört es eher in WinMain rein ...
-
Gibt es bei mir nicht, da ich ein Plugin für eine Anwendung in DLL-Form schreibe.
-
Dann halt bei DLL_PROCESS_ATTACH und DLL_PROCESS_DETACH in der DllMain ...
-
Im Magazin gibts einen GDI+ Artikel, da sind die Basics erklärt.
-
Hab ich gelesen. Gut geschrieben, sehr aufklärend, wenn man vorher keine Ahnung davon hatte.
