Einer CBitmap eine neue CBitmap zuweisen



  • Hallo,

    ich habe folgende Variablen.

    private:
    	CBitmap      m_Bitmap;
    	CBitmap      m_newBitmap;
    	CBitmap*     m_pBitmap;
    

    Die Initialisierung und die Bitmap anzeigen sieht so aus

    void CAstraImageView::OnInitialUpdate()
    {
    	CScrollView::OnInitialUpdate();
    	OnUpdate(NULL, 0, NULL);
    
    	m_Bitmap.LoadBitmap(IDB_BITMAP1);         // Bitmap von Resource laden
    	m_pBitmap = &m_Bitmap;                    // Zeiger
    	BITMAP bm;
    	m_Bitmap.GetBitmap(&bm);
    	m_ImageSize = CSize(bm.bmWidth, bm.bmHeight);
    }
    
    void CAstraImageView::OnDraw(CDC* pDC)
    {
    	...
    
    	CDC dc;
    	dc.CreateCompatibleDC(pDC);
    
            /* Nachdem ich mit der Zuweisung m_Bitmap = m_newBitmap keinen Erfolg hatte
            habe ich hier auf Zeiger umgestellt*/
    	CBitmap* pOldBitmap = dc.SelectObject(m_pBitmap/*&m_Bitmap*/);
    
    	pDC->SetStretchBltMode(HALFTONE);
    	pDC->StretchBlt(x_offset, y_offset,
    		int(m_ImageSize.cx * m_fZoomFactor),
    		int(m_ImageSize.cy * m_fZoomFactor),
    		&dc,
    		0, 0, m_ImageSize.cx, m_ImageSize.cy,
    		SRCCOPY);
    
    	dc.SelectObject(pOldBitmap);
    }
    

    Ich möchte eine neue Bitmap laden und sie m_Bitmap zuweisen.

    void CAstraImageView::OnDrawOnBitmap()
    {
            // hier erst mal fix, später über FileDialog
    	CImage img;
    	img.Load(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett.bmp");
    	CBitmap* pBitmap = CBitmap::FromHandle(img.Detach());
    	BITMAP bm;
    	pBitmap->GetBitmap(&bm);
    
    	CDC* pDC = GetDC();
    
    	//create a memory dc
    	CDC memDC;
    	memDC.CreateCompatibleDC(pDC);
    
    	//Create a memory bitmap
    //	CBitmap newbmp;
    	m_newBitmap.CreateCompatibleBitmap(pDC, bm.bmWidth, bm.bmHeight);
    
    	HGDIOBJ old = memDC.SelectObject(pBitmap);
    
    	// draw on bitmap
    	memDC.DrawText(L"test", new CRect(40, 40, 500, 500), DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    	memDC.Draw3dRect(new CRect(40, 40, 500, 500), RGB(255, 0, 0), RGB(0, 255, 0));
    
    	memDC.SelectObject(&old);
    	
    	ReleaseDC(pDC);
    	ReleaseDC(&memDC);
    
    	m_pBitmap = &m_newBitmap;     // die neue Bitmap zuweisen
    
    	ScrollbarsVisible();
    	OnUpdate(NULL, 0, NULL);
    
    	/*CImage img1;
    	img1.Attach((HBITMAP)newbmp.Detach());
    	img1.Save(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett_test.bmp");
    	img1.Detach();*/
    }
    

    Das speichern (nur zum testen) funktioniert, der Text und das 3D Rechteck ist vorhanden. Es wird aber nur eine komplett schwarze Bitmap angezeigt.

    Meine Frage:

    1. Wie kann ich m_Bitmap eine neue Bitmap zuweisen. Also ohne Zeiger
    2. Ist in OnDrawOnBitmap() alles andere soweit richtig.

    Schon mal ein Danke im voraus.
    Franz



  • @AstroFranz sagte in Einer CBitmap eine neue CBitmap zuweisen:

    	memDC.SelectObject(&old);
    	// ...
    	ReleaseDC(&memDC);
    

    Das ist schonmal falsch. Die erste Zeile sollte memDC.SelectObject(old); sein und das ReleaseDC(&memDC); gehört einfach weg.

    Wie kann ich m_Bitmap eine neue Bitmap zuweisen. Also ohne Zeiger

    Ich schätze mal gar nicht. Was stört dich an der Variante mit Zeiger? Du solltest bloss Smart-Pointer verwenden damit du dich nicht mehr manuell um das Freigeben kümmern musst.



  • @hustbaer sagte in Einer CBitmap eine neue CBitmap zuweisen:

    Du solltest bloss Smart-Pointer

    Die Änderungen ändern nichts an der Tatsche daß die Bitmap schwarz bleibt.

    Ich habe nichts gegen Zeiger. (Smart-Pointer höre ich jetzt zum ersten mal.) Deswegen seit 2 Tagen
    nach über15 Jahren der Wechsel von C# wieder zu C++.



  • Testcode

    void CAstraImageView::OnDrawOnBitmap()
    {
    	...
    
    	bool test1 = true;
    	bool test2 = true;
    
    	if (test1 == true)
    	{
    		CBitmap newbmp;
    
    		//Create a memory bitmap
    		newbmp.CreateCompatibleBitmap(pDC, bm.bmWidth, bm.bmHeight);
    
    		HGDIOBJ old = memDC.SelectObject(&newbmp);
    
    		// draw on bitmap
    		memDC.DrawText(L"test", new CRect(40, 40, 500, 500), DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    		memDC.Draw3dRect(new CRect(40, 40, 500, 500), RGB(255, 0, 0), RGB(0, 255, 0));
    
    		memDC.SelectObject(old);
    
    		CImage img1;
    		img1.Attach((HBITMAP)newbmp.Detach());
    		img1.Save(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett_test_1.bmp");
    		img1.Detach();
    	}
    
    	if (test2 == true)
    	{
    		m_newBitmap.CreateCompatibleBitmap(pDC, bm.bmWidth, bm.bmHeight);
    
    		HGDIOBJ old = memDC.SelectObject(m_newBitmap);
    
    		// draw on bitmap
    		memDC.DrawText(L"test", new CRect(180, 180, 500, 500), DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    		memDC.Draw3dRect(new CRect(180, 180, 500, 500), RGB(255, 0, 0), RGB(0, 255, 0));
    
    		memDC.SelectObject(old);
    
    		CImage img1;
    		img1.Attach((HBITMAP)m_newBitmap.Detach());
    		img1.Save(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett_test_2.bmp");
    		img1.Detach();
    	}
    
    	ReleaseDC(pDC);
    
    	ScrollbarsVisible();
    	OnUpdate(NULL, 0, NULL);
    }
    

    Beide Tests liefern als Ausgabe die richtige Bitmap,

    Somit änders sich die Frage in Wie weise ich einem Zeiger eine Bitmap zu

    Weder

    CImage m_Image;
    
    m_Image.Load(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett_test_2.bmp");
    m_pBitmap = CBitmap::FromHandle(m_Image);
    

    noch

    m_pBitmap = &m_newBitmap;
    

    zeigen die Bitmap richtig an.

    Ich bin sogar der Meinung daß die Frage eher ist. wie lade ich eine Bitmap und kann sie konstant im Speicher behalten



  • Hat sich erledigt. Wo kein Fehler ist kann auch keiner gefunden werden.

    Habe vor lauter Fehlersuche im Code CAstraImageView::OnDrawOnBitmap() den Gesammtüberblick über meinen Programmcode verloren.

            // diese Zeile ist die Lösung am Ende der Methode
    	m_ImageSize = CSize(bm.bmWidth, bm.bmHeight);
    

    So passt es.

    void CAstraImageView::OnDrawOnBitmap()
    {
    	CImage img;
    	img.Load(L"C:\\Users\\franz\\MyTestFolder\\Leotriplett.bmp");
    
    	CBitmap* pBitmap = CBitmap::FromHandle(img.Detach());
    
    	BITMAP bm;
    	pBitmap->GetBitmap(&bm);
    
    	CDC* pDC = GetDC();
    
    	//create a memory dc
    	CDC memDC;
    	memDC.CreateCompatibleDC(pDC);
    
    	m_newBitmap.CreateCompatibleBitmap(pDC, bm.bmWidth, bm.bmHeight);
    
    	HGDIOBJ old = memDC.SelectObject(&m_newBitmap);
    
    	// draw on bitmap
    	memDC.DrawText(L"test", new CRect(180, 180, 500, 500), DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    	memDC.Draw3dRect(new CRect(180, 180, 500, 500), RGB(255, 0, 0), RGB(0, 255, 0));
    
    	memDC.SelectObject(old);
    
    	ReleaseDC(pDC);
    
    	ScrollbarsVisible();
    	OnUpdate(NULL, 0, NULL);
    
    	m_pBitmap = &m_newBitmap;
    
            // diese Zeile ist die Lösung
    	m_ImageSize = CSize(bm.bmWidth, bm.bmHeight);
    }
    

    Nochmals Danke für die Berichtigung der falschen Codeteile!

    Das posten im Forum war Teil der Lösung.

    Franz


Anmelden zum Antworten