HDC/GDI+ - Frage zum leeren des HDC's



  • Hi Leute,

    ich versuche mich gerade in GDI+ einzuarbeiten. Ich habe mit GetDC() ein Device Context erstellt. Wenn ich ein bestimmtes Element meines TreeView-Controls
    anklicke, soll ein Bild+Text gezeichnet werden. Soweit funktioniert auch alles jedoch habe ich bemerkt, das, wenn ich noch einmal darauf klicke,
    der Inhalt nochmal auf den vorhandenen Inhalt gezeichnet wird. Klicke ich 5-mal drauf, so erscheint der Text "Fett"(weil er 5-mal aufeinander gezeichnet wurde).

    Meine Frage, wie kann ich vor erneutem Zeichnen den HDC "leeren".
    Hoffe, ich habe mich verständlich ausgedrückt.
    Bitte um Antworten, danke!



  • Du zeichnest ein Rechteck in der Hintergrundfarbe drüber.



  • Dann zeichne ich je nur was neues drüber. Kann man den Inhalt denn nicht leeren?
    Das muss doch irgendwie gehen.



  • Du zeichnest nicht "drüber". Stell dir das wie ein Gitter mit Pixeln vor. Das Gitter ist flach, jeder Pixel hat genau einen Farbwert. Wenn du ein Rechteck "drüberzeichnest", ersetzt du den Wert und hast es somit "gelöscht".
    Dass der Text bei dir so ausschaut, dass er mehrmals "drübergezeichnet" worden wäre, hat wohl andere Gründe, wahrscheinlich passt die Position nicht ganz.



  • Du zeichnest nicht "drüber". Stell dir das wie ein Gitter mit Pixeln vor. Das Gitter ist flach, jeder Pixel hat genau einen Farbwert. Wenn du ein Rechteck "drüberzeichnest", ersetzt du den Wert und hast es somit "gelöscht".

    Ok, das hab ich verstanden.

    Dass der Text bei dir so ausschaut, dass er mehrmals "drübergezeichnet" worden wäre, hat wohl andere Gründe, wahrscheinlich passt die Position nicht ganz.

    Wie soll es denn an der Position liegen? Ich verändere doch nichts. Wenn ich noch mal klicke,
    überschreibt er die Pixel nicht. Wenn ich z.b. den Text in grau zeichne und dann nochmal drücke, so wird er dunkler und (optisch) dicker. Drücke ich jetzt 10 mal,
    dann habe ich einen schwarzen (dicken)Text.

    Aber ich verstehe schon, was du meinst. BeginPaint() macht ja auch nichts anderes,
    als die Hintergrundfarbe neu zu zeichnen und den vorherigen Inhalt so zu überschreiben.
    Wie mache ich das denn am besten, ich könnte das ganze Fenster wieder auf die Hintegrundfarbe setzten, doch
    was ist, wenn es nur ein Teil sein soll? Wie mache ich das am besten?



  • hi schrieb:

    Wie soll es denn an der Position liegen?

    Zeig mal ein bisschen Code.

    BeginPaint zeichnet oder löscht selbst nichts. Das verschickt evtl. eine WM_ERASEBKGND Nachricht. Die Standardimplementierung überschreibt dann das Fenster mit der Hintergrundfarbe. Du könnntest aber selber auf die Nachricht reagieren und was anderes machen (z.B. nichts).

    Wenn du einen Teil überschreiben willst, zeichnest du halt ein Rechteckt mit der entsprechenden Größe...



  • Folgender Codeteil zeichnet das Bild+Text:

    grafik.DrawImage(&bild, 11, 103, 580, 282);
    grafik.DrawString(wcstring, -1, &title50, origin, &blackBrush);
    

    Mehr passiert da auch nicht.

    Folgender Code ruft die entsprechende Funktion auf:

    case WM_NOTIFY:
    		{
    			switch (((LPNMHDR)lParam)->code)
    			{
    			case TVN_SELCHANGED:
    				{
    					switch(((LPNMTREEVIEW)lParam)->itemNew.lParam)
    					{
    					case TV_ROOT_ALLGEMEINES:
    						SendMessage (g_hStatusBar, SB_SETTEXT , 0, (LPARAM)"Allgemeines");
    						break;
    
    					case TV_ITEM_ALLGEMEINES_UN:
    						{
    							SendMessage (g_hStatusBar, SB_SETTEXT , 0, (LPARAM)"Allgemeines -> UN");
    							TVStatus = Status_Allgemein_UN;
    							InitGdi(hDC, 50);
    						}
    						break;
    					}
    				}
    				break;
    			}
    		}
    		break;
    

    Beim Klick auf TV_ITEM_ALLGEMEINES_UN wird das Bild und der Text gezeichnet.

    Wenn du einen Teil überschreiben willst, zeichnest du halt ein Rechteckt mit der entsprechenden Größe...

    Ok danke, hätte ich selber drauf kommen können 🙂



  • Lass bitte dieses Denglisch, das ist grauenhaft. Und am besten gar keine deutschen Bezeichner verwenden. Das ist immer nur inkonsistent und schränkt dich später evtl. auch ein (stell dir vor, du willst Teile vom Code mal als Open Source freigeben, oder musst die Frage zu einer Third Party Komponente an den Hersteller schreiben und Beispielcode von dir posten).

    Ich seh nicht, wo die Funktion aufgerufen wird. Ist es die InitGdi Funktion? Ich seh z.B. einen origin Parameter, sicher, dass er immer gleich ist?



  • Lass bitte dieses Denglisch, das ist grauenhaft.

    Nein, eben nicht. Für öffentliche sachen nutze ich English. Für meinen eigenen Code mache ich es so,
    wie es mir gefällt. Ich kann Leute nicht leiden, die meinen, man müsse sich an der Allgemeinheit orientieren
    und in "Englisch" coden. Für mich ist eben das grauenhaft. Du wirst jetzt wahrscheinlich wieder mit deiner Meinung kommen und mir sagen, das ist eine blöde Angewohnheit habe.
    Ich bin jedoch kein volldepp, der bei einem öffentlichen Projekt oder so nicht auf nur "englisch" umschalten kann.

    Und am besten gar keine deutschen Bezeichner verwenden.

    Doch.

    Das ist immer nur inkonsistent und schränkt dich später evtl. auch ein (stell dir vor, du willst Teile vom Code mal als Open Source freigeben, oder musst die Frage zu einer Third Party Komponente an den Hersteller schreiben und Beispielcode von dir posten).

    Ich glaube, als Mensch mit normalem Verstand ist es für einen überhaupt kein Problem, sich in so einer Situation umzustimmen.

    Ich seh nicht, wo die Funktion aufgerufen wird. Ist es die InitGdi Funktion? Ich seh z.B. einen origin Parameter, sicher, dass er immer gleich ist?

    Ja, es ist die InitGdi(). Der origin-Parameter ist kein variabler Wert, sondern ist in InitGdi() fest "integriert"
    und hat dementsprechend bei jedem Funktionsaufruf den gleichen Wert.

    Nur damit das klar ist, ich wollte mit mein oben geschriebenes nichts gegen dich Mechanics sagen. Ich wollte
    lediglich darauf hinweisen, das es, wenn es um eigenen Code geht(kein Open Source), es im Endeffekt Geschmackssache ist, wie man seine Bezeichner nennt.
    Also nichts für ungut 🙂



  • Ich mache es jetzt so, das ich einfach ein Rechteck zeichne. Klappt super.

    PS: Allen ein frohes neues 2014! 😃 😃 😃



  • hi schrieb:

    Du wirst jetzt wahrscheinlich wieder mit deiner Meinung kommen und mir sagen, das ist eine blöde Angewohnheit habe.

    Hmm, ja 😉 Ist aber nur meine Meinung. Wenn du das bewusst machst, ist mir das egal. Ich wollts nur mal ansprechen, weils zu 99% nur Anfänger machen, die aus schlechten deutschen Büchern gelernt haben. Hier gibts aber auch paar sehr erfahrene Leute im Forum, die deutsche Bezeichner verwenden. Ich finds tatsächlich amateurhaft und hässlich, aber wenn dus machen willst, dann machs, ich will keinen zu irgendwas bekehren.

    Wenn die Position immer gleich ist und der Text trotzdem jedesmal dunkler wird, könnte es an Anti Aliasing liegen. Da wird evtl. die Hintergrundfarbe mit reingerechnet, weiß jetzt aber nicht genau, wie das funktioniert.


Anmelden zum Antworten