CDC und CImage aus der ATL



  • Folgender Code:

    CPaintDC dc(&m_graph);
    CImage image;		
    image.Attach(dc.GetCurrentBitmap()->operator HBITMAP());		
    
    image.Save(dlg.GetPathName());
    

    m_graph ist ein CStatic. Er speichert ein Bild, aber nicht nur das CStatic, sondern immer ein Bild des gesamten Dialoges. Warum? Ich hab doch ein DC auf das Static und nicht auf den Dialog. Es ist auch egal, ob ich den DC so wie oben erstelle oder m_graph.GetDC benutze.

    MfG Pellaeon



  • versuch es mal so:

    CImage Image;
    	CWindowDC dc((CWnd*)&m_graph);
    	CRect rect;
    	dc.GetClipBox(rect);
    	Image.Create(rect.Width(),rect.Height(),32);
    	CDC pDC;
    	pDC.Attach(Image.GetDC());
    	pDC.BitBlt(0,0,rect.Width(),rect.Height(),(CDC*)&dc,0,0,SRCCOPY);
    	pDC.Detach();
    	Image.ReleaseDC();
    	Image.Save("c:\\image.jpg");
    

    Gruß



  • Ok danke, ich werd das gleich mal testen. Hab auch gerade festgestellt, dass Vista und BitBlt sich nicht mögen oO
    Gibts da Alternativen?



  • Soar also dein Code funzt, THX.

    Aber das BitBlt überhaupt net. Scheine auch net der einzige zu sein. Google spuckt da auch viele Threads aus mit Leuten, die da Probs haben. Leider stehen da irgendwie nie Lösungen. Folgender HINtergrund:

    void CMyStatic::initBuffer()
    {
    	CRect rect;
    	GetClientRect(rect);
    
    	CPaintDC dc(this);	
    	CBitmap bm;
    
    	m_memDC.width  = rect.Width();
    	m_memDC.height = rect.Height();	
    
    	m_memDC.dc.CreateCompatibleDC(&dc);	
    	bm.CreateCompatibleBitmap(&m_memDC.dc,m_memDC.width,m_memDC.height);
    	m_memDC.dc.SelectObject(&bm);        
    	m_memDC.dc.FillSolidRect(0,0,m_memDC.width,m_memDC.height,RGB(255,0,0));
    }
    

    Das mit dem CreateCompatibleBitmap ist schon neu. Unter Xp hat es ja gereicht nur den CD entsprechend anzulegen.

    In der Paint will ich dann den MemDC in den paintDC blitten. Aber da kommt immer nur Müll raus.

    CPaintDC dc(this); // device context for painting
    dc.BitBlt(0,0,m_memDC.width,m_memDC.height,&m_memDC.dc,0,0,SRCCOPY);
    

    Ist der BitBlt generell für Vista nicht mehr einsetzbar?



  • Also ich weiss ja net was du machst, aber das gepostete beispiel läuft bei mir unter vista allerbestens.

    Das mit dem CreateCompatibleBitmap ist schon neu. Unter Xp hat es ja gereicht nur den CD entsprechend anzulegen.

    Jetzt stellste aber ne ganz besondere behauptung auf, das du unter xp in nen erstelle DC gezeichnet hast, ohne ne bitmap dafür zu erzeugen. Also ich benutze schon die MFC seit es VC++ 6 gibt und ich hab noch nie erfolg gehabt in nen DC zu zeichnen ohne eine bitmap anzulegen.

    Und warum Mist bei dir raus kommt kann ich dir auch sagen, weil du die Bitmap in InitBuffer lokal erstellst, und dann drauf zeichnest, ist deine initBuffer beendet wird die bitmap weggeschmissen, also verschieb den konstuctor von CBitmap bm in deine m_memDC-Klasse (wo ich denke das sie auch hingehört und lasse alles über die klasse laufen und fertig



  • Erstmal danke für deine Hilfe.
    Meine BEhauptung zieh ich mal offiziell zurück^^ Hab zu lange nicht mehr mit WinGDI rumgemehrt.
    Das mit dem Bitmap ist aber nicht der Grund für den Fehler. Auch wenn das CBitmap lokal ist, wird das interne HBITMAP im Destruktor nicht gelöscht. Daher muss man ja (leider) immer per Hand die release-Funktionen aufrufen. Der Fehler in meinem Code oben ist folgender:

    bm.CreateCompatibleBitmap(&m_memDC.dc,m_memDC.width,m_memDC.height);

    Warum auch immer, das mag er nicht. Setze ich dort dc, also den Kontext vom Fenster, dann funktioniert es.

    MfG Pellaeon



  • Wobei das eigentlich doch auch egal ist welchen der beiden DC du benutzt. Aber ich muß noch mal auf deine ausgangsfrage zurück konmen, ursprünglich wolltest du das doch über CImage in eine Datei sichern und jetzt blittest du das in der Paint war die urspüngliche frage nur so ne idee?



  • Nein sind 2 getrennte Dinge. Ich wollte nur keinen neuen Thread aufmachen, weil die Themen ähnlich sind.

    Das ursprüngliche war wirklich, den Inhalt des CStatics als Bild zu speichern. Das andere betrifft Sachen, wie das Bidl entsteht, was das CStatic anzeigt. Das ganze ist eine kleine Testumgebung für einen Raytracer.
    Bisher hat der Raytracer das Bild in einem std::vector abgelegt und in der Paint wurde dann in 2 for-Schleifen mit setPixelV das Bild rüberkopiert. Unelegant und langsam, aber ich wollte ja auch nur schnell was sehen. Dafür hats gelangt.

    Heute wollt ich das Umstellen, dass der direkt in den MemDC rendert und ich dann das Ergebnis nur blitten muss. Aber ich habe vorns festgestellt, der CDC scheint sich nicht mit MT zu vertragen. Bei den Threads ist gesichert, dass sie nie auf denselben Speicherbereich schreiben, weil jeder einen anderen Teil des Bildes zeichnet. Aber den SetPixelV ist das anscheinend egal^^ Der mag das nicht.



  • na ich sag mal SetPixel oder SetPixelV sind auch keine routienen die man benutzen sollte ^^. Wünsch dir aber auf jeden fall Erfolg bei deinem vorhaben



  • Joar naja, aber die Farben kommen halt Pixelweise an. Und mal einfach was in den CDC reinkopieren, was nicht auch aus einem anderen CDC kommt, geht garnet so einfach.
    Ach ja btw, das Bild speichern von dir klappt unter Vista wunderbar. Wie ich bei einer Vorführung heute gemerkt habe: unter XP nicht . Murphy hat zugeschlagen^^

    Naja ich probier mal noch ein bisschen rum. Wenn ich ne Lösung habe, stell ich sie mit rein.

    MfG Pellaeon


Anmelden zum Antworten