1 BOOL SaveHwndToBmp( HWND hWnd, LPCTSTR lpszFile )
2 {
3 BOOL bRet;
4 HDC hDC, hMemDC;
5 HBITMAP hBitmap, hBitmapOld;
6 RECT rc;
7 int nWidth, nHeight;
8 BITMAPINFOHEADER BitmapInfoHeader;
9 BITMAPFILEHEADER BitmapFileHeader;
10 HANDLE hFile;
11 DWORD dwBytes;
12
13
14 ::GetWindowRect( hWnd, &rc );
15 nWidth = rc.right - rc.left;
16 nHeight = rc.bottom - rc.top;
17
18 memset( &BitmapInfoHeader, 0, sizeof( BITMAPINFOHEADER ) );
19 BitmapInfoHeader.biSize = sizeof( BITMAPINFOHEADER );
20 BitmapInfoHeader.biWidth = nWidth;
21 BitmapInfoHeader.biHeight = nHeight;
22 BitmapInfoHeader.biPlanes = 1;
23 BitmapInfoHeader.biBitCount = 24;
24 BitmapInfoHeader.biCompression = BI_RGB;
25 BitmapInfoHeader.biSizeImage = ( ( ( nWidth * 24 + 31 ) & ~31 ) >> 3 ) * nHeight;
26 //BitmapInfoHeader.biXPelsPerMeter = 0;
27 //BitmapInfoHeader.biYPelsPerMeter = 0;
28 //BitmapInfoHeader.biClrUsed = 0;
29 //BitmapInfoHeader.biClrImportant = 0;
30
31
32 hDC = ::GetWindowDC( hWnd );
33 hMemDC = ::CreateCompatibleDC( hDC );
34 hBitmap = ::CreateCompatibleBitmap( hDC, nWidth, nHeight );
35 hBitmapOld = ( HBITMAP )::SelectObject( hMemDC, ( HGDIOBJ )hBitmap );
36
37 if ( !::PrintWindow( hWnd, hMemDC, 0 ) )
38 {
39 bRet = FALSE;
40 goto err_exit;
41 }
42
43 if ( ::GetDIBits( hMemDC, hBitmap, 0, nHeight, ( LPVOID )g_ImgBuff, ( LPBITMAPINFO )&BitmapInfoHeader, DIB_RGB_COLORS ) != nHeight )
44 {
45 bRet = FALSE;
46 goto err_exit;
47 }
48
49 memset( &BitmapFileHeader, 0, sizeof( BITMAPFILEHEADER ) );
50 BitmapFileHeader.bfType = 0x4d42;
51 BitmapFileHeader.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + BitmapInfoHeader.biSizeImage;
52 //BitmapFileHeader.bfReserved1 = 0;
53 //BitmapFileHeader.bfReserved2 = 0;
54 BitmapFileHeader.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
55
56 hFile = ::CreateFile( lpszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
57 if ( hFile == INVALID_HANDLE_VALUE )
58 {
59 bRet = FALSE;
60 goto err_exit;
61 }
62
63 bRet = ::WriteFile( hFile, &BitmapFileHeader, sizeof( BITMAPFILEHEADER ), &dwBytes, NULL );
64 if ( !bRet || dwBytes != sizeof( BITMAPFILEHEADER ) )
65 {
66 ::CloseHandle( hFile );
67 bRet = FALSE;
68 goto err_exit;
69 }
70
71 bRet = ::WriteFile( hFile, &BitmapInfoHeader, sizeof( BITMAPINFOHEADER ), &dwBytes, NULL );
72 if ( !bRet || dwBytes != sizeof( BITMAPINFOHEADER ) )
73 {
74 ::CloseHandle( hFile );
75 bRet = FALSE;
76 goto err_exit;
77 }
78
79 bRet = ::WriteFile( hFile, g_ImgBuff, BitmapInfoHeader.biSizeImage, &dwBytes, NULL );
80 if ( !bRet || dwBytes != BitmapInfoHeader.biSizeImage )
81 {
82 ::CloseHandle( hFile );
83 bRet = FALSE;
84 goto err_exit;
85 }
86
87 ::CloseHandle( hFile );
88 err_exit:
89 ::SelectObject( hMemDC, ( HGDIOBJ )hBitmapOld );
90 ::DeleteObject( ( HGDIOBJ )hBitmap );
91 ::DeleteDC( hMemDC );
92 ::ReleaseDC( hWnd, hDC );
93 return bRet;
94 }