Verständnisfrage (DC per Referenz übergeben, ReleaseDC) ...
-
Guten Tach!
Ich habe in meiner Anwendung ein GDI-Leck gefunden, dass ich nicht ganz verstehe.
Ich rufe in WM_MOUSEMOVE eine Funktion DepthOfField() auf, der ich einen Zeiger auf den in WM_MOUSEMOVE erstellten DC (hdc) übergebe. Somit wird per Referenz übergeben, also keine Kopie der Variablen erstellt. Nach meinem Verständnis muss ich ReleaseDC() für diese eine Variable auch nur einmal aufrufen (und zwar in WM_MOUSEMOVE, da sie dort erstellt wurde).
Auf die Sache aufmerksam geworden bin ich durch das erwähnte (und da in WM_MOUSEMOVE sehr heftige) GDI-Leck. Nach viel 'Rumprobieren (nein, nicht das Getränk!) habe ich herausgefunden, dass ich das Leck stopfen kann, indem ich in DepthOfField() ebenfalls ReleaseDC() verwende. Dabei wurde doch lediglich die Adresse von hdc übergeben. Meiner Meinung nach müsste in DepthOfField() gar nicht releast werden, sondern nur in WM_MOUSEMOVE. Sehe ich das falsch?
Also, wo bitteschön ist mein Denkfehler bzw. meine Wissenslücke?
Gruß Matze
case WM_MOUSEMOVE: { UINT mX=LOWORD(lParam); UINT mY=HIWORD(lParam); // HDC hdc=::GetDC(hWnd); //<= hdc erzeugen //POINT pn; GetCursorPos(&pnCursor); ScreenToClient(hWnd,&pnCursor); if(wParam==VK_RBUTTON) { HDC hdc=GetDC(hWnd); POINT pn; pn.x=LOWORD(lParam); pn.y=HIWORD(lParam); DepthOfField(&hWnd,&hdc,pn); //<= hdc per Referenz übergeben } ::ReleaseDC(hWnd,hdc); //<= hdc freigeben return 0; } void DepthOfField(HWND *hWnd,HDC *hdc,POINT pnStart) { // . // . // . ReleaseDC(*hWnd,*hdc); //<= auch hier muss hdc freigegeben werden }
-
Du hast im case-Zweig zwei GetDC()-Aufrufe (der zweite am Anfang des if-Blockes) und mußt natürlich auch für jeden einen korrespondierenden ReleaseDC-Aufruf einbauen.
-
HMPFH!
Danke, du hast natürlich Recht. Das war die Sache mit dem Wald und den Bäumen...
Und dass hier kein Compiler-Fehler wegen doppeltem Bezeichner kommt, liegt wahrscheinlich daran, dass der zweite hdc in einem eigenen Block (if) deklariert wird, richtig?
-
Gut erkannt - der if-Block definiert einen eigenen Scope und dort verdeckt das hdc seinen Namensvetter. (aber warum du überhaupt zwei DCs für das Fenster anforderst, ist die andere Frage)
-
Die Frage ist leicht beantwortet: Die WM_MOUSEMOVE-Behandlung ist wesentlich größer als gepostet, das meiste habe ich der Übersicht halber 'rausgeschmissen (und auch, da es sich um firmeninternen Code handelt). Da muss ich wohl vergessen haben, dass ich mir bereits einen DC hole. Mangels Compiler-Error ist mir das nicht aufgefallen.
Ohne C/C++ schlecht machen zu wollen: In jeder anderen mir vertrauten Sprache wäre das nicht passiert. Daran sieht man auch, dass es in C++ wesentlich mehr Tücken gibt und der Lernprozess deutlich länger (ein Leben lang?) anhält. Mittlerweile geht es ja ganz gut. Wenn ich dran denke, wie aufgeschmissen ich vor 4 Monaten erstmal war, als ich versucht habe, meine ersten C++-Programme zu schreiben...
Gruß Matze
-
_matze schrieb:
Da muss ich wohl vergessen haben, dass ich mir bereits einen DC hole.
Mangels Compiler-Error ist mir das nicht aufgefallen.Böse Schlussfolgerung : Ein Kompiler prüft nicht die Programm-Logik.
-
@merker:
Lies doch meine Posts zu Ende. Ich sagte ja, dass dieses Verhalten in den mir bekannten Sprachen (z.B. Clipper, VB) eher unüblich ist. Ein Statement wie
HDC hdc=::GetDC(hWnd); HDC hdc=::GetDC(hWnd);würde unweigerlich zu einem Compiler-Fehler führen. Dass ich in C++ in einem geschlossenen Block dennoch denselben Bezeichner wiederverwenden kann, ist doch eher eine spezielle Geschichte und mir durch genannte Sprachen nicht bekannt gewesen. Einem Anfänger möge man diese Unwissenheit verzeihen.
Übrigens schreibt man Compiler mit "C". Wenn du die deutsche Variante benutzen möchtest (was ich nicht verkehrt finde), dann kannst du "Kompilierer" schreiben.
Dies ist sowieso eine Unsitte, die im Internet von vielen gepflegt wird. Genauso schreibt man Vektor eben mit "k", und nicht mit "c", dennoch trifft man sehr häufig auf diese falsche Schreibweise.
Gruß Matze
-
_matze schrieb:
Dies ist sowieso eine Unsitte, die im Internet von vielen gepflegt wird. Genauso schreibt man Vektor eben mit "k", und nicht mit "c", dennoch trifft man sehr häufig auf diese falsche Schreibweise.
Das hängt aber von den Umständen ab - ich schreibe z.B. den mathematischen Vektor mit "k" und den std::vector<> aus der C++ Standardbibliothek mit "c"

-
Vielleicht können wir uns ja darauf einigen, dass wir den std::vector (der mit dem mathematischen Vektor ja auch nicht viel zu tun hat) entsprechend der englischen Schreibweise klein und mit "c" schreiben und den mathematischen Vektor dann eben groß und mit "k".
Allerdings ist diese Regel vielleicht doch nicht ausreichend. Wenn nun jemand darauf besteht, für den mathematischen Vektor die englische Schreibweise zu nutzen (in der Hoch-Zeit des Denglisch durchaus denkbar), dann müsste er wiederum "vector" schreiben...
Nun ja, vielleicht verzichte ich in Zukunft einfach auf Wörter, die ein "c" oder "k" enthalten. Der Verwirrungsfactor ist einfach zu hoch... Am Ende lande ich noch mit Hirncrämpfen im Crankenhaus...

Gruß Matze
-
Und jetzt sollten wir diese (unterhaltsame) Diskussion abbrechen. Schließlich geht es hier im Forum um K/K++ (der musste sein)...
Gruß Matze
-
_matze schrieb:
Vielleicht können wir uns ja darauf einigen, dass wir den std::vector (der mit dem mathematischen Vektor ja auch nicht viel zu tun hat) entsprechend der englischen Schreibweise klein und mit "c" schreiben und den mathematischen Vektor dann eben groß und mit "k".
Gegenvorschlag: Jeder schreibt so, daß der Gegenüber ihn versteht - wer dagegen verstößt, wird drauf hingewiesen und stellt die Missverständnisse klar

Nun ja, vielleicht verzichte ich in Zukunft einfach auf Wörter, die ein "c" oder "k" enthalten. Der Verwirrungsfactor ist einfach zu hoch... Am Ende lande ich noch mit Hirncrämpfen im Crankenhaus...

Nihts für mih - da önnte ih noh niht mal meinen Namen ausshreiben
