Hinzufügen und anzeigen eines Bitmap-Backgrounds

Stay Tuned

Grünschnabel
Hallo.

Ich arbeite zur Zeit an einer MFC Version des Spieles TicTacToe.

Mein Programm ist soweit fertig und zum Schluss hin wollte ich noch einen schönen Hintergrund einfügen.

Im Moment sieht das Programm noch so aus:

http://img222.imageshack.us/img222/1441/hintergrundwh7.jpg


Nun möchte ich diesen einfachen Farb-Hintergrund ( Hautfarbe ) entfernen und ein richtiges Bitmap hinzufügen. Einfach damit es schöner ausschaut.


Mein erster gedanke ist irgendwas in der OnDraw zu verändern, da ich dort ja auch die Hintergrundfarbe bestimme. So sieht meine OnDraw aus

Code:
{
	CTTTDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// ZU ERLEDIGEN: Hier Code zum Zeichnen der ursprünglichen Daten hinzufügen

// Hier wird ein in Bezug auf Farbtiefe und Abmessungen zu pDC kompatibler
// Memory-Device-Kontext im RAM erzeugt.
	CDC *mempDC = new CDC;
	mempDC->CreateCompatibleDC( pDC );

	CRect clientRect;
	GetClientRect( &clientRect );

// Hier wird ein in Bezug auf Farbtiefe und Abmessungen zu pDC kompatibles
// Bitmap erzeugt.
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap( pDC, clientRect.right, clientRect.bottom );

// Das Bitmap wird zum Zeichnen in den Memory-Device-Kontext geladen.
	CBitmap *pOldBitmap = mempDC->SelectObject( &bitmap );

// Weil der Memory-Device-Kontext mit zufälligem Inhalt ínitialisiert ist, 
// und OnEraseBkgnd deaktiviert wurde, wird er mit einem einfarbigen 
// Rechteck ausgefüllt. 
	mempDC->FillSolidRect( &clientRect, RGB(255,133,100) );


	GetClientRect(cr); // ABMESSUNG DES CLIENTBEREICHES

//GROßES FELD

		int hoehe=(cr.Height()-cr.Height()*0.4)/3.15;	// HÖHE VOM GROßEN FELD EINRICHTEN
		int breite=(cr.Width()-cr.Width()*0.4)/3;		// BREITE VOM GROßEN FELD EINRICHTEN

		int offsethorizontal=cr.Width()*0.2;			// POSITION HORIZONTAL EINRICHTEN	( - )
		int offsetvertikal=cr.Height()*0.215;			// POSITION VERTIKAL EINRICHTEN		( | )


		for(int p=0; p<3; p++){
			for(int o=0; o<3; o++){
				m_feld[p][o].left=breite*p+offsethorizontal;
				m_feld[p][o].top=hoehe*o+offsetvertikal;
				m_feld[p][o].right=m_feld[p][o].left+breite;
				m_feld[p][o].bottom=m_feld[p][o].top+hoehe;
			}
		}


//HIER WIRD DAS GROßE FELD GEZEICHNET

		for(int i=0; i<3; i++){
			for(int j=0; j<3; j++){

				m_strich.CreatePen(PS_SOLID,m_feld[i][j].m_rand,RGB(0,0,0));
				m_grau.CreateSolidBrush(m_feld[i][j].m_farbe);

				CPen* pOldPen=mempDC->SelectObject(&m_strich);
				CBrush* pOldBrush=mempDC->SelectObject(&m_grau);

				mempDC->Rectangle(m_feld[i][j]);

				mempDC->SelectObject(pOldPen);
				mempDC->SelectObject(pOldBrush);

				m_strich.DeleteObject();
				m_grau.DeleteObject();
			}
		}


	
//KLEINES FELD

		int m_hoehe=(cr.Height()-cr.Height()*0.7)/4.7;	// HÖHE VOM KLEINEN FELD EINRICHTEN
		int m_breite=(cr.Width()-cr.Width()*0.5)/7.75;	// BREITE VOM KLEINEN FELD EINRICHTEN

		int m_offsethorizontal=cr.Width()*0.2655;		// POSITION HORIZONTAL EINRICHTEN	( - )
		int m_offsetvertikal=cr.Height()*0.27;			// POSITION VERTIKAL EINRICHTEN		( | )

		m_mini.left		=	breite*p+m_offsethorizontal;
		m_mini.top		=	hoehe+m_offsetvertikal;
		m_mini.right	=	m_mini.left+m_breite;
		m_mini.bottom	=	m_mini.top+m_hoehe;
			

//HIER WIRD DAS KLEINE FELD GEZEICHNET

		m_strich.CreatePen(PS_SOLID,m_mini.mM_rand,RGB(0,0,0));
		m_grau.CreateSolidBrush(m_mini.m_farbe );

		CPen* pOldPen=mempDC->SelectObject(&m_strich);
		CBrush* pOldBrush=mempDC->SelectObject(&m_grau);

		mempDC->Rectangle(m_mini);

		mempDC->SelectObject(pOldPen);
		mempDC->SelectObject(pOldBrush);

		m_strich.DeleteObject();
		m_grau.DeleteObject();


//AUSGABE
		CString str;

/*ROT ( SPIELER 1 HAT GEWONNEN )*/	
		if( m_win == 1){

			str.Format("%s hat nach seinem %i. Zug gewonnen. Gebrauchte Zeit: %i Sekunde(n)", m_gamer1,m_count_rot,m_zeit );
			mempDC->TextOut(m_feld[0][0].left,m_feld[2][2].bottom,str);
		}

/*BLAU ( SPIELER 2 HAT GEWONNEN )*/ 		
		if( m_win == 2){

			str.Format("%s hat nach seinem %i. Zug gewonnen. Gebrauchte Zeit: %i Sekunde(n)", m_gamer2,m_count_blau,m_zeit );
			mempDC->TextOut(m_feld[0][0].left,m_feld[2][2].bottom,str);
		}

//UNENTSCHIEDEN

		if( m_unentschieden == 9 && m_win != 1 && m_win != 2){

			str.Format("Unentschieden. Gebrauchte Zeit: %i Sekunde(n)",m_zeit );
			mempDC->TextOut(m_feld[0][0].left,m_feld[2][2].bottom,str);
		}

//INFORMATIONEN LINKS OBEN IM SPIELFELD

		str.Format( "Spieldauer: %i Sekunde(n)",m_zeit ); // AUSGABE DER AKTUELLEN SPIELDAUER IN SEKUNDEN
		mempDC->TextOut(10,50,str);

		str.Format("Spieler 1: %s", m_gamer1 ); // AUSGABE VOM NAMEN VON SPIELER 1
		mempDC->TextOut(10,10,str);

		str.Format("Spieler 2: %s", m_gamer2 ); // AUSGABE VOM NAMEN VON SPIELER 2
		mempDC->TextOut(10,30,str);


// Das fertige Bitmap wird in den Ausgabe-Device-Kontext kopiert und sichtbar 
// gemacht.
		pDC->BitBlt( 0, 0, clientRect.right, clientRect.bottom, mempDC, 0, 0, SRCCOPY );

		mempDC->SelectObject( pOldBitmap );
		mempDC->SelectObject( pOldBrush );
	
// Der dynamisch reservierte Speicher wird freigegeben.
		delete mempDC;
}

Ich habe bereits nach einigen Tuts gegooglt, habe aber nichts gefunden was ich wirklich benutzen kann.

Unter Ressourcen habe ich das Bitmap bereits importiert, ihm eine eindeutige ID zugewiesen und danach wusste ich nicht wirklich weiter... hab vieles ausprobiert, nach der try'n'error Methode, hilft aber alles nichts.

Wer könnte mir kurz ( oder auch ausführlich ) erklären, wie ich das Bitmap als Hintergrund einrichten kann.


Mit freundlichen Grüßen

Stay Tuned
 

langer1801

Erfahrenes Mitglied
Hi,

ich würde die Klasse CPicture verwenden und in OnEraseBkgrnd() die Größe des Client-Bereiches ermitteln und mit CPicture::Draw(....) die Bitmap malen lassen. Die Klasse CPicture findet man schnell über Google. Ich finde, das ist die beste Klasse, um einfach mit Bitmaps zu arbeiten.

Mfg

langer
 

MCoder

Erfahrenes Mitglied
Hallo,

in der OnDraw-Methode kannst du auch ein Hintergrundbitmap mit zeichnen.

Erzeuge einfach einen zweiten Memory-DC, der nur das Bitmap aufnimmt und kopiere es (vor allen anderen Zeichenoperationen) auf den Memory-DC, auf dem du dann alles weitere zeichnest. Falls du das Bitmap skalieren willst, nimm statt "BitBlt" die Methode "StretchBlt".
Hier mal eine kurze Skizzierung der Lösung:
C++:
// ...

CDC memDCBmp;
memDCBmpCreateCompatibleDC(pDC);

CBitmap bgBitmap;
bgBitmap.LoadBitmap(ID_MYBITMAP);
CBitmap *pOldBgBmp = memDCBmp.SelectObject(&bgBitmap);

mempDC->BitBlt( 0,
                0, 
                nWidth,  /* TODO: Breite */
                nHeight, /* TODO: Höhe   */ 
	            &memDCBmp,
                0,
                0,
                SCRCOPY );
                
                
// ...

memDCBmp.SelectObject(&pOldBgBmp);

// ...
Gruß
MCoder