Bitmaps mit GDI werden nicht richtig gezeichnet!



  • Hallo!

    Mein Programm soll ein Raster von 16*16 Quadraten mit aus Dateien geladenen Bitmaps füllen (1Kästchen = 1 Bitmap). Leider wird aber nur ein kleiner Teil des Rasters gefüllt. Das ganze hat auch eine seltsame Form (gleicht der Rundung der Fenster in XP).

    Das ganze funktioniert folgendermaßen:

    Filehandler fhImages;
    		HBITMAP* Images;
    
    		string envApps= (string)getenv("APPDATA");
    		Images = fhImages.GetImages(envApps+FDIR_TEMPDIR);
    
    		int arrIndex=0;
    		int x=0;
    		int y=0;
    		int row= 16;
    
    		while(arrIndex <= 255)
    		{
    			HDC hdcMemory= CreateCompatibleDC(hdc);
    			SelectObject(hdcMemory,Images[arrIndex]);
    			BitBlt(hdc,x,y,64,64,hdcMemory,0,0,SRCCOPY);
    			arrIndex++;
    			x+=64;
    			row--;
    			if(row ==0)
    			{
    				x=0;
    				y+=64;
    				row=16;
    			}
    		}
    

    Die Bilder werden alle geladen und dann der Reihe nach "geblittet".

    Weiß jemand, wie sowas zu Stande kommt?

    Vielen Dank schon mal im Voraus,
    veryxRV



  • Ich habe jetzt herausgefunden, dass anscheinend nur der Bereich richtig mit der GDI ausgabe gefüllt wird, der vorher von einem Dialogfeld bedeckt wurde, deswegen auch die Fensterform.

    Kann mir als jemand sagen, wie ich es anstellen kann, dass der gesamte Fensterereich damit gefüllt wird?

    Zur Info: Der Zeichencode befindet sich in einer Funktion, die bei WM_PAINT aufgerufen wird.



  • Gib mal "hdcMemory" nach "BitBlt ()" mit "DeleteDC ()" wieder frei. Sonst benimmt sich das BS seltsam.
    🙂



  • Danke, war aber Leider nicht die Lösung. InvalidateRect hat aber abhilfe geschafft, da es damit das gesamte Fenster neu Zeichnet, anstatt nur den Bereich, denn die DialogBox vorher bedeckt hatte.

    Leider habe ich jetzt ein anderes Problem:

    Hier ein Screenshot:

    http://owmod.gamondo.de/gdifehler.jpg

    Wie auf dem Screeny unschwer zu erkennen ist, lässr er die letzten 11 Bitmaps einfach aus. Woran könnte das denn liegen?

    EDIT: Auf dem Bild ist ja außer den Normalen Quadraten ein kleines Rechteck zu sehen, da da irgendwie nicht hingehört. Wenn man es ganauer betrachtet, sieht man, dass es sich dabei um eine Reihe von Symbolen handelt, die normalerweise die kleinen Buttons für "Minimieren" etc. beim Fenster darstellen. Diese sind übrigens immer verschieden, also mal das X, dann der - usw. Scheint also, als ob sich der Zeichencode für die Bilder mit dem vom Fenster überschneiden.



  • Probier mal ob bei nur einer Bitmap alles korrekt gezeichnet wird :

    // SelectObject(hdcMemory,Images[arrIndex]);
    SelectObject(hdcMemory,Images[0]);
    


  • Ja wird es. Habe den Fehler auch gefunden, kann ihn mir nur nicht wirklich begründen, aber vielleicht kann das hier ja jemand:

    Mein BITMAP Array war 256 Einträge groß, das ist genau so viel, wie die Bilder, die gezeichnet werden sollen. Erweiter ich diese 256 jetzt um 11, also genau so viele Bilder, wie vorher ausgelassen wurden, stellt er alles richtig dar. Der Speicher hat also irgendwie nicht gereicht, aber wieso werden genau 11 mehr benötigt?

    Wär super, wenn mir das hier jemand erklären könnte!



  • Du solltest bei SelectObject() den Rückgabewert merken und nach Benutzung des rein-selektierten Objekts wieder das ursprüngliche Objekt (der vorher gemerkte Rückgabewert) rein-selektieren - auch wenn das DC nachher eh gelöscht wird.
    Außerdem zu jedem CreateCompatibleDC() auch ein DeleteDC().
    Ansonsten hast du GDI-Leaks und da passieren dann die lustigsten Sachen 😉



  • geeky schrieb:

    Du solltest bei SelectObject() den Rückgabewert merken und nach Benutzung des rein-selektierten Objekts wieder das ursprüngliche Objekt (der vorher gemerkte Rückgabewert) rein-selektieren - auch wenn das DC nachher eh gelöscht wird.
    Außerdem zu jedem CreateCompatibleDC() auch ein DeleteDC().
    Ansonsten hast du GDI-Leaks und da passieren dann die lustigsten Sachen 😉

    Hmm.. Sorry aber hab ich nicht ganz verstanden ^^. Kannst du mir mal bitte ein Codebeispiel nennen? Wäre nett!



  • Wird die letzte Bitmap im Array auch korrekt gezeichnet ?

    // SelectObject(hdcMemory,Images[arrIndex]);
    SelectObject(hdcMemory,Images[255]);
    


  • Jep, wird sie.



  • Hast Du jetzt nur das Bitmap-Array von 256 auf 256 + 11 Elemente vergrössert ?
    Die angehängten Elemente werden durch den Zähler doch gar nicht erreicht ?



  • Ja habe ich. Eben das wundert mich auch, aber es hat das Problem gelöst. Wahrscheinlich weil dadurch mehr Speicher reserviert wurde. Weiß der Geier wofür...



  • Was ich meine ist:

    while(arrIndex <= 255)
    {
    	HDC hdcMemory = CreateCompatibleDC(hdc);
    	HGDIOBJ oldObj = SelectObject(hdcMemory,Images[arrIndex]);	// CreateCompatibleDC() erzeugt eine 1x1 Bitmap und selektiert diese rein, diese haben wir nun in oldObj
    		BitBlt(hdc,x,y,64,64,hdcMemory,0,0,SRCCOPY);
    	SelectObject(hdcMemory,oldObj);	// Jetzt wieder das oldObj rein-klatschen. Rückgabewert von SelectObject() wäre diesmal Images[arrIndex]
    	DeleteDC(hdcMemory);	// Löscht hdcMemory und die 1x1 Bitmap
    
    	// ...etc
    }
    

Anmelden zum Antworten