BOOL WriteWindowToDIB(LPTSTR szFile,
CWnd *pWnd )
{
CBitmap bitmap;
CWindowDC dc(pWnd);
CDC memDC;
CRect rect;
pWnd->GetWindowRect(rect);
Anschließend wird ein kompatibler Kontext erzeugt und mit dessen Hilfe eine kompatible Bitmap, deren Größe den Ausmaßen des Fensters entspricht.
memDC.CreateCompatibleDC(&dc);
bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
Die Ausgangsbitmap läßt sich nun in den Speicherkontext selektieren und kopieren.
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, rect.Width(),rect.Height(),
&dc, 0, 0, SRCCOPY);
Damit ist jedoch erst die halbe Arbeit getan. Die andere Hälfte besteht darin, die logische Palette zu ermitteln, die für die Bitmap eingesetzt wird, sofern logische Paletten verwendet werden. Ob eine logische Palette benutzt wird, kann über die API-Funktion GetDeviceCaps() ermittelt werden.
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
{
Wird eine Palette benutzt, allokiert die Funktion ausreichend Speicher zur Aufnahme der Palette in Form einer LOGPALETTE-Struktur, die dann über einen Aufruf der API-Funktion GetSystemPaletteEntries() mit den Einträgen der Systempalette gefüllt wird.
UINT nSize = sizeof(LOGPALETTE) +
(sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = GetSystemPaletteEntries(
dc, 0, 255, pLP->palPalEntry );
Anhand der LOGPALETTE-Struktur kann nun die logische Palette erzeugt und der Speicher der LOGPALETTE-Struktur freigegeben werden.
pal.CreatePalette( pLP );
delete[] pLP;
}
Nach dem Zurückselektieren der Bitmap steht die Abbildung des Fensters im Objekt bitmap.
memDC.SelectObject(pOldBitmap);
Die nun vorliegende Bitmap wird mit Hilfe der Funktion DDBToDIB(), die in Kapitel 5/2.1.10.9 vorgestellt wurde, in eine DIB konvertiert.
HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, &pal);
Liegt ein gültiges Handle vor, kann die DIB anschließend durch WriteDIB(), die in Kapitel 5/2.1.10.12 beschrieben wurde, in eine BMP-Datei geschrieben werden.
if( hDIB == NULL )
return FALSE;
WriteDIB( szFile, hDIB );
Abschließend ist der von DDBToDIB() allokierte Speicher wieder freizugeben und das Funktionsergebnis zu belegen.
GlobalFree( hDIB );
return TRUE;
}
Damit ist das aktuelle Fenster gespeichert. Zu beachten ist hierbei, daß die Funktion GetWindowRect() die tatsächliche Position des Fensters liefert. Dies sagt jedoch nichts darüber aus, daß dieses Fenster auch komplett sichtbar ist. Vielmehr kann ein Teil des Fensters durch andere Fenster verdeckt sein. Gegebenenfalls muß eine Anwendung vor dem Aufruf der Funktion WriteWindow ToDIB() die Sichtbarkeit des zu speichernden Fensters sicherstellen, indem die API-Funktion BringWindowToTop() vor dem Aktivieren von WriteWindowToDIB() aufgerufen wird.
|