Beispiel 4: Bitmap-Datei, CScrollView, Toolbar, GetLastError

Ziel dieses Beispiels:
Über einen eigenen Toolbar-Button soll eine Bilddatei geladen und auf dem Bildschirm dargestellt werden. Unterstützte Formate: BMP, JPEG, GIF, PNG. Die Bitmap soll automatisch scrollen, falls sie größer als das aktuelle Fenster ist.
ACHTUNG: Wie eine Bitmap aus den Anwendungs-Resourcen geladen werden kann wird in den MFC-Schnipseln im Beispiel "Bitmap aus Ressource" gezeigt.
Hier gibt es das Beispiel zum Download: BitmapLoad.zip

Schritt 1: Anwendungsgerüst

Erstellen des Anwendungsgerüsts (SDI-Anwendung) wie in den bisherige Beispielen.
Im letzten Schritt wählen wir als View-Basisklasse "CScrollView".
ScrollView wählen


Schritt 2: Toolbar-Button

In der Toolbar soll ein neuer Button eingefügt werden, der beim Klick einen Dialog zum Öffnen der Bitmap-Datei anzeigt.
Zuerst einmal muss die Toolbar erweitert werden: Im Resourcen-Editor unter "Toolbar" die Resource IDR_MAINFRAME öffnen.
Toolbar in Resourcen
Rechts des "Hilfe"-Buttons ist ein leerer Dummy-Button. Diesen anklicken und das Bild zeichnen (ich habe im Beispiel einen Screenshot des XP-Standardicons für Bitmap-Dateien verwendet).
Toolbar-Button-Bild
Man gibt dem Button die ID "ID_LOADBITMAP".
Toolbar-Button-ID
Im Solution Explorer kann man jetzt unter "Resource Files" die Datei "Toolbar.bmp" öffnen und sieht dass unser neues Icon rechts angehängt wurde.
Startet man die Anwendung ist der Button ausgegraut. Dies geschieht weil kein Eventhandler definiert ist. Also die View-Datei (im Beispiel: "CBitmapLoadView") öffnen und in die MessageMap folgendes eintragen:
	ON_COMMAND (ID_LOADBITMAP, CBitmapLoadView::OnLoadBitmap)
Eine Methode mit folgender Signatur muss zugefügt werden:
	void CBitmapLoadView::OnLoadBitmap(void)
	{
		...
	}
In diese Methode packen wir den Code zum Laden der Bitmap. Prinzipiell ist dies trivial, da die Klasse "CImage" uns die gesamte Arbeit abnimmt. Damit wir mit CImage arbeiten können, muss in stdafx.h folgendes eingebunden werden (Gemäß Doku NACH dem Include für CString etc.)
	#include <atlimage.h>
Ich habe eine Membervariable vom Typ "CImage *" definiert. Zum Laden der Bitmap-Datei sind folgende zwei Zeilen Code nötig ("sBitmapFile" ist der Name der zu ladenden Datei, vorher in einem Öffnen-Dialog vom User eingegeben):
	this->image = new CImage ();
	HRESULT resultLoad = this->image->Load (sBitmapFile);

	if (resultLoad == S_OK)
	{
		...
	}
	else
	{
		...
	}
Im Fehlerfall (z.B. Dateiformat ungültig / Datei fehlerhaft) soll dem User eine MessageBox mit der Windows-Fehlernummer angezeigt werden. Diese erhält man (wie in fast allen Fällen) über die Methode "GetLastError":
	DWORD dwLastError = ::GetLastError();

	CString sMessage = "";
	sMessage.Format ("Bitmap-Laden schlug fehl. GetLastError = %d!", dwLastError);
	
	AfxMessageBox (sMessage);
Im Erfolgsfall muss sichergestellt werden dass die Scrollview groß genug ist um die Bitmap anzuzeigen. Also die Scroll-Weite anpassen:
	this->SetScrollSizes (MM_TEXT, CSize (this->image->GetWidth(), this->image->GetHeight()) );

Schritt 3: Zeichnen in OnDraw

Dieser Schritt ist der trivialste:
	if (this->image != NULL)
	{
		this->image->Draw ( (HDC) (*pDC), 0, 0 );
	}

Stand 15.06.2006
Historie:
12.06.2006 Beispiel zugefügt (aus SWT-Praktikum 2005, angepaßt an VS2005 und mehr Screenshots).
15.06.2006 Verweis auf "Bitmap aus Ressource"-Beispiel