HDC reset

Thomasio

Erfahrenes Mitglied
Ich habe mir eine ziemlich lange Funktion im WM_PAINT eines Fensters gebastelt
Ganz zu Anfang steht da

Code:
HDC hdc = BeginPaint(MyWindow, &ps);
HDC IrgendwasDC = CreateCompatibleDC(hdc);
HBITMAP IrgendwasBitmap = CreateCompatibleBitmap(hdc, 300, 200);

Normal wäre, die Bitmap füllen, BitBlt nach hdc und dann mit DeleteDC() wieder löschen

Nun habe ich aber zwischen Create und Delete ein Stück Code stehen

Code:
while(irgendwas)
       {
            switch(sonstwas)
                     {
                           case x:
                           {
                                // Hier habe ich das Problem
                           }
                           break;
                     }
       }

Im case x würde ich gerne die HDC und die HBITMAP resetten, sprich was auch immer da drin ist auf NULL setzen und beides neu füllen

Probiert habe ich einfach

Code:
IrgendwasDC = NULL;
IrgendwasBitmap = NULL;
IrgendwasDC = CreateCompatibleDC(hdc);
IrgendwasBitmap = CreateCompatibleBitmap(hdc, x, y);

Aufgefallen ist mir dabei zuerst mal, wenn die neue BITMAP kleiner ist als die Alte, muss ich den Überschuss extra löschen, mit

Code:
InvalidateRect(MyParentWindow,NULL,false);

Damit funktioniert das Ganze nun, ich habe nur Bedenken, dass ich dabei ein Speicherleck erzeuge, und ich wüsste gern, wie ich die HDC und HBITMAP "sauber" resetten kann ohne das handle zu verlieren
DeleteDC() geht jedenfalls nicht, weil sie dann unterhalb vom switch() nicht mehr vorhanden ist
 
Zuletzt bearbeitet:
Hui, langsam ....

Welches Objekt löschen? HDC oder HBITMAP oder beide? Und an welcher Stelle?

Delete heisst nicht mehr vorhanden, neu create heisst nach der nächsten } nicht mehr vorhanden, wie kann ich denn unterhalb vom switch() noch auf das Objekt zugreifen, wenn das oben Erstellte gelöscht wird und das im switch() Erstellte nicht mehr vorhanden ist?

Oder versteh ich da was falsch?
 
ich wüsste gern, wie ich die HDC und HBITMAP "sauber" resetten kann ohne das handle zu verlieren
Hier weiß ich nicht genau, was du mit dem verlorenen Handle meinst. Wenn du resettest ist das Handle natürlich futsch, aber du willst es ja wieder neu zuweisen (glaube ich verstanden zu haben).

Ausgehend von deinem Code, solltest daher nicht einfach NULL setzen sondern richtig löschen:
C++:
DeleteDC(IrgendwasDC):   // alt:IrgendwasDC = NULL;
DeleteObject(IrgendwasBitmap); // alt IrgendwasBitmap = NULL;
IrgendwasDC = CreateCompatibleDC(hdc);
IrgendwasBitmap = CreateCompatibleBitmap(hdc, x, y);
wie kann ich denn unterhalb vom switch() noch auf das Objekt zugreifen, wenn das oben Erstellte gelöscht wird und das im switch() Erstellte nicht mehr vorhanden ist
Warum willst du denn löschen, wenn du später noch mal darauf zugreifen willst? Wenn du innerhalb eines "case" löscht und gleich wieder neu zuweist, sollte das doch gehen?

Gruß
MCoder
 
Zuletzt bearbeitet von einem Moderator:
Du hast das schon richtig verstanden, ich will resetten und gleich neu zuweisen, mit dem Sinn eine neue HDC und neue HBITMAP zu haben, die eine andere Grösse haben kann

Wenn ich es ganz zu Anfang die HDC definiere, dann ist sie gültig bis sie gelöscht wird
Verlasse ich die Funktion ohne sie zu löschen bleibt sie im Speicher hängen, so weit klar

Mein Problem, bzw. was ich nicht weiss ist

Wenn ich im switch() zuerst DeleteDC() mache und immer noch innerhalb vom switch() wieder neu zuweise, ist dann unterhalb vom switch() mein Handle noch gültig, so dass ich mit BitBlt drauf zugreifen und ich es hinterher mit DeleteDC() endgültig löschen kann

Soweit ich das jetzt verstanden habe würde das gehen, in dem Falle würde ich gerne verstehen warum, denn nach meinem Verständnis löscht der DeleteDC() innerhalb vom switch() das vorher erstellte Handle
Definiere ich dann innerhalb vom switch() ein Neues, wenn auch mit gleichem Namen, dann müsste es am Ende vom Switch verloren gehen und sogar im Speicher hängen bleiben

Und weil ich im Moment ganz verwirrt bin, WENN das Handle unterhalb vom switch() noch gültig ist, worauf weist es dann? Auf die alte HDC, mit der alten Grösse? Ist das evtl der Grund warum ich hinterher mit Invalidate(Parent) den Überhang löschen muss?
 
Hallo,

wenn du außerhalb vom switch eine Vraiable deklarierst ...
C++:
HDC     myDC;
HBITMAP myBmp;

switch(...)
{
    // ...
}
... kannst du sie auch außerhalb vom switch verwenden. Was dann natürlich drinsteht und ob dabei gültige Handles
vorhanden sind, hängt von den entsprechenden Zuweisungen bzw. Löschoperationen ab.

Wenn du löscht und anschließend neu zuweist, hast du einen neues Handle, das mit dem alten nichts mehr zu hat, auch wenn
du es einer schon vorhandenenm Variablen zuweist.
Der Speicher von GDI-Ressourcen wird global reserviert, unabhängig davon in welchen Gültigkeitbereich die den
entsprechenden Handle aufnehmende Variable deklariert wurde. Es muss zum Löschen immer die entsprechende Delete-Funktion
aufgerufen werden.

Übrigens hat das Löschen von GDI-Resourcen erstmal keinen Einfluss auf die Ausgabe. Wenn sich was ändert muss ein
Neuzeichnen extra angestossen werden (Invalidate).

Gruß
MCoder
 
Zurück