Wem gehört das Handle? (SelectObject)
-
Hallo,
ich habe eine Frage, die aus der MSDN nicht eindeutig hervorgeht. Und zwar, wird in Zeile 2 das brush-Handle an das device übergeben. Wem gehört da das Handle? Immer noch mir und es wird eine Kopie erstellt, oder wird es nicht mehr von mir verwaltet; d. h. es wird von Windows bzw. dem dispose von device automatisch mit gelöscht? Wenn das Handle nach SelectObject nicht mehr mir gehört, darf ich Zeile 8 nicht mehr aufrufen, weil es sonst irgendwann crashen könnte?
Fragen über Fragen...
MfG
Christian
brush=CreateSolidBrush(rgb); oldbrush=(HBRUSH)SelectObject(device,brush); RoundRect(device,hmrect->left,hmrect->top,hmrect->right,hmrect->bottom,roundingH,roundingV); SelectObject(device,oldbrush); DeleteObject(brush); DeleteObject(oldbrush);
-
oldbrush hast Du nicht erzeugt und gehört nicht Dir. Also lass es in Frieden.
Du bist für alle Objekte verantwortlich, die Du erzeugst.
Löschen darfst Du sie aber nur wenn sie in keinem Kontext mehr verwendet werden, ansonsten hast Du Leaks ohne Ende.HTH
-
Ok, danke für die Antwort!
-
Hmmm, das scheint ja nicht so zu stimmen denn:
bitmap=CreateCompatibleBitmap(originaldevice,rect->right,rect->bottom); if(bitmap){ SelectObject(memDC,bitmap); DeleteObject(bitmap); }Obwohl mir das Handle nicht mehr gehört, lösche ich es! Wird da eine Kopie erzeugt?
Löscht WIN32 API eigentlich alles, nach dem Aufruf von DeleteDC?
-
Doch es stimmt!
Dieser Code ist genau, dass was Memotyleaks erzeugt.Ich habe es doch geschrieben:
Löschen darfst Du sie aber nur wenn sie in keinem Kontext mehr verwendet werden, ansonsten hast Du Leaks ohne Ende.
Hier wird ein Objekt erzeugt in einen DC selektiert und dann "versucht" zu löschen. Das lässt Windows aber nicht zu und es entsteht ein GDI-Leak. Die erzeugte Bitmap wird niemals mehr freigegeben!
Zauberspiegel schrieb:
Löscht WIN32 API eigentlich alles, nach dem Aufruf von DeleteDC?
Eben nicht! Objekte können über DC Grenzen hinweg benutzt werden!
-
Martin Richter schrieb:
Eben nicht! Objekte können über DC Grenzen hinweg benutzt werden!
Das heißt ja, dass ichvor DeleteDC selber zu sorgen habe, dass das Bitmap, Pen, Brushes etc. mit DeleteObject gelöscht werden!?
-
Zauberspiegel schrieb:
Martin Richter schrieb:
Eben nicht! Objekte können über DC Grenzen hinweg benutzt werden!
Das heißt ja, dass ichvor DeleteDC selber zu sorgen habe, dass das Bitmap, Pen, Brushes etc. mit DeleteObject gelöscht werden!?
Exakt! Und wenn Du es vergisst, gibt es eben Leaks. Ganz böse.
-
Das heißt ja, dass ichvor DeleteDC selber zu sorgen habe, dass das Bitmap, Pen, Brushes etc. mit DeleteObject gelöscht werden!?
Nein. Du musst NACHDEM du den letzten DC gelöscht hast der ein Objekt verwendet dieses Objekt löschen.
Wenn du es "by the book" machen willst, dann selektierst du auch noch vor dem löschen des DCs wieder alle Objekte rein mit denen er angelegt wurde. Also inetwa so:void foo() { HBRUSH brush = CreateSolidBrush(...); // eigene brush her HDC dc = CreateDC(...); // eigenen DC her HBRUSH oldbrush = static_cast<HBRUSH>(SelectObject(dc, brush)); // eigene brush in eigenen DC reinstecken // ... SelectObject(dc,oldbrush); // alte brush wieder in den DC reinstecken DeleteDC(dc); // DC löschen DeleteObject(brush); // eigene brush löschen }
-
hustbaer schrieb:
Das heißt ja, dass ichvor DeleteDC selber zu sorgen habe, dass das Bitmap, Pen, Brushes etc. mit DeleteObject gelöscht werden!?
Nein. Du musst NACHDEM du den letzten DC gelöscht hast der ein Objekt verwendet dieses Objekt löschen.
Wenn du es "by the book" machen willst, dann selektierst du auch noch vor dem löschen des DCs wieder alle Objekte rein mit denen er angelegt wurde. Also inetwa so:void foo() { HBRUSH brush = CreateSolidBrush(...); // eigene brush her HDC dc = CreateDC(...); // eigenen DC her HBRUSH oldbrush = static_cast<HBRUSH>(SelectObject(dc, brush)); // eigene brush in eigenen DC reinstecken // ... SelectObject(dc,oldbrush); // alte brush wieder in den DC reinstecken DeleteDC(dc); // DC löschen DeleteObject(brush); // eigene brush löschen }Ähm ja...das implizierte mein Post
. Also ich mach das immer in einem Schritt, da man sich dann die Variable 'brush', in Deinem Beispiel, sparen kann!DeleteObject(SelectObject(dc, oldbrush)); DeleteDC(dc);