抓屏并保存为BMP文件.cpp
上传用户:shibojindu
上传日期:2013-06-09
资源大小:37k
文件大小:7k
源码类别:

屏幕保护

开发平台:

Visual C++

  1. // 抓屏并保存为BMP文件.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "抓屏并保存为BMP文件.h"
  5. #include "抓屏并保存为BMP文件Dlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CBMPApp
  13. BEGIN_MESSAGE_MAP(CBMPApp, CWinApp)
  14. //{{AFX_MSG_MAP(CBMPApp)
  15. // NOTE - the ClassWizard will add and remove mapping macros here.
  16. //    DO NOT EDIT what you see in these blocks of generated code!
  17. //}}AFX_MSG
  18. ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  19. END_MESSAGE_MAP()
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CBMPApp construction
  22. CBMPApp::CBMPApp()
  23. {
  24. // TODO: add construction code here,
  25. // Place all significant initialization in InitInstance
  26. }
  27. /////////////////////////////////////////////////////////////////////////////
  28. // The one and only CBMPApp object
  29. CBMPApp theApp;
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CBMPApp initialization
  32. BOOL CBMPApp::InitInstance()
  33. {
  34. // Standard initialization
  35. // If you are not using these features and wish to reduce the size
  36. //  of your final executable, you should remove from the following
  37. //  the specific initialization routines you do not need.
  38. CBMPDlg dlg;
  39. m_pMainWnd = &dlg;
  40. int nResponse = dlg.DoModal();
  41. if (nResponse == IDOK)
  42. {
  43. // TODO: Place code here to handle when the dialog is
  44. //  dismissed with OK
  45. }
  46. else if (nResponse == IDCANCEL)
  47. {
  48. // TODO: Place code here to handle when the dialog is
  49. //  dismissed with Cancel
  50. }
  51. // Since the dialog has been closed, return FALSE so that we exit the
  52. //  application, rather than start the application's message pump.
  53. return FALSE;
  54. }
  55. WORD WINAPI GetPaletteSize(LPSTR lpbi)
  56. {
  57. DWORD dwClrUsed;
  58.       
  59. dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  60. if (dwClrUsed == 0)
  61. switch ( ((LPBITMAPINFOHEADER)lpbi)->biBitCount )
  62. {
  63. case 1:
  64. dwClrUsed=2;
  65. break;
  66. case 4:
  67. dwClrUsed=16;
  68. break;
  69. case 8:
  70. dwClrUsed=256;
  71. break;
  72. default:
  73. dwClrUsed=0;
  74. break;
  75. }
  76. return (WORD)(dwClrUsed * sizeof(RGBQUAD));
  77. }
  78. HANDLE WINAPI BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal)
  79. {
  80. ASSERT(hBitmap);
  81.    
  82. BITMAP bm;
  83. BITMAPINFOHEADER bi;
  84. LPBITMAPINFOHEADER lpbi;
  85. DWORD dwLen;
  86. HANDLE hDib,h;
  87. HDC hDC;
  88. WORD biBits;
  89. UINT wLineLen;
  90. DWORD dwSize;
  91. DWORD wColSize;
  92. if (!hBitmap) return NULL;
  93. if (!::GetObject(hBitmap, sizeof(bm), &bm)) return NULL;
  94. if (hPal == NULL)
  95. hPal = (HPALETTE)::GetStockObject(DEFAULT_PALETTE);
  96. biBits = (WORD) (bm.bmPlanes * bm.bmBitsPixel);
  97. wLineLen = ( bm.bmWidth * biBits + 31 ) / 32 * 4;
  98. wColSize = sizeof(RGBQUAD) * (( biBits <= 8 ) ? 1 << biBits : 0 );
  99. dwSize = sizeof( BITMAPINFOHEADER ) + wColSize +
  100. (DWORD)(UINT)wLineLen * (DWORD)(UINT)bm.bmHeight;
  101. if (biBits <= 1)
  102. biBits = 1;
  103. else if (biBits <= 4)
  104. biBits = 4;
  105. else if (biBits <= 8)
  106. biBits = 8;
  107. else
  108.       biBits = 24;
  109. bi.biSize = sizeof(BITMAPINFOHEADER);
  110. bi.biWidth = bm.bmWidth;
  111. bi.biHeight = bm.bmHeight;
  112. bi.biPlanes = 1;
  113. bi.biBitCount = biBits;
  114. bi.biCompression = BI_RGB;
  115. bi.biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize;
  116. bi.biXPelsPerMeter = 0;
  117. bi.biYPelsPerMeter = 0;
  118. bi.biClrUsed = ( biBits <= 8 ) ? 1 << biBits : 0;
  119. bi.biClrImportant = 0;
  120. dwLen = bi.biSize + ::GetPaletteSize((LPSTR) &bi);
  121. hDC = ::GetDC(NULL);
  122. hPal = ::SelectPalette(hDC, hPal, FALSE);
  123. ::RealizePalette(hDC);
  124. hDib = (HANDLE)::GlobalAlloc(GHND, dwLen);
  125. if (!hDib)
  126. {
  127. ::SelectPalette(hDC, hPal, TRUE);
  128. ::RealizePalette(hDC);
  129. ::ReleaseDC(NULL, hDC);
  130. return NULL;
  131. }
  132. lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
  133. if (!lpbi)
  134. {
  135. ::SelectPalette(hDC, hPal, TRUE);
  136. ::RealizePalette(hDC);
  137. ::ReleaseDC(NULL, hDC);
  138. return NULL;
  139. }
  140. *lpbi = bi;
  141. ::GetDIBits(hDC, hBitmap, 0, (WORD)bi.biHeight, NULL, 
  142. (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
  143. bi = *lpbi;
  144. bi.biClrUsed = ( biBits <= 8 ) ? 1 << biBits : 0;
  145. ::GlobalUnlock(hDib);
  146. if (bi.biSizeImage == 0)
  147. bi.biSizeImage = ( ( ( (DWORD)bm.bmWidth * biBits ) + 31 ) / 32 * 4) * bm.bmHeight;
  148. dwLen = bi.biSize+::GetPaletteSize((LPSTR)&bi)+bi.biSizeImage;
  149. h = (HANDLE)::GlobalReAlloc(hDib, dwLen, 0);
  150. if ( h )
  151. {
  152. hDib = h;
  153. }
  154. else
  155. {
  156. ::GlobalFree(hDib);
  157. hDib = NULL;
  158. ::SelectPalette(hDC, hPal, TRUE);
  159. ::RealizePalette(hDC);
  160. ::ReleaseDC(NULL, hDC);
  161. return NULL;
  162. }
  163. lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
  164. if (!lpbi)
  165. {
  166. ::GlobalFree(hDib);
  167. hDib = NULL;
  168. ::SelectPalette(hDC, hPal, TRUE);
  169. ::RealizePalette(hDC);
  170. ::ReleaseDC(NULL, hDC);
  171. return NULL;
  172. }
  173. if (::GetDIBits(hDC,hBitmap,0,(WORD)bi.biHeight, 
  174. (LPSTR)lpbi + (WORD)lpbi->biSize + ::GetPaletteSize((LPSTR) lpbi),
  175. (LPBITMAPINFO)lpbi,DIB_RGB_COLORS) == 0)
  176.    {
  177. ::GlobalUnlock(hDib);
  178. hDib = NULL;
  179. ::SelectPalette(hDC, hPal, TRUE);
  180. ::RealizePalette(hDC);
  181. ::ReleaseDC(NULL, hDC);
  182. return NULL;
  183. }
  184.    
  185. bi = *lpbi;
  186. ::GlobalUnlock(hDib);
  187. ::SelectPalette(hDC, hPal, TRUE);
  188. ::RealizePalette(hDC);
  189. ::ReleaseDC(NULL, hDC);
  190. return hDib;
  191. }
  192. HANDLE WINAPI DIBFromWindow(CWnd *pWnd, CRect* pRect)
  193. {
  194. CBitmap     bitmap;
  195. CWindowDC dc(pWnd);
  196. CDC     memDC;
  197. CRect    rect;
  198.    
  199. memDC.CreateCompatibleDC(&dc); 
  200.    
  201. if ( pRect == NULL )
  202. {
  203. pWnd->GetWindowRect(rect);
  204. rect.OffsetRect(-rect.left,-rect.top);
  205. }
  206. else
  207. rect = *pRect;
  208.    
  209. bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
  210.    
  211. CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
  212. memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, rect.left, rect.top, SRCCOPY); 
  213. CPalette pal;
  214. if ( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
  215. {
  216. UINT nSize=sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
  217. LOGPALETTE *pLP=(LOGPALETTE *) new BYTE[nSize];
  218. pLP->palVersion=0x300;
  219. pLP->palNumEntries = (USHORT) GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
  220. pal.CreatePalette( pLP );
  221. delete[] pLP;
  222. }
  223. memDC.SelectObject(pOldBitmap);
  224. HANDLE hDib = BitmapToDIB( bitmap, pal );
  225. return hDib;
  226. }
  227. BOOL WINAPI SaveToFile(HANDLE hDib, CFile& file)
  228. {
  229. BITMAPFILEHEADER bmfHdr;
  230. LPBITMAPINFOHEADER lpBI;
  231. DWORD dwDIBSize;
  232.    
  233. if (hDib == NULL)
  234. return FALSE;
  235. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  236. if (lpBI == NULL)
  237. return FALSE;
  238. bmfHdr.bfType = ((WORD) ('M' << 8) | 'B');  // "BM"
  239.    
  240. dwDIBSize = *(LPDWORD)lpBI + ::GetPaletteSize((LPSTR)lpBI);
  241. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  242. {
  243. dwDIBSize += lpBI->biSizeImage;
  244. }
  245. else
  246. {
  247. DWORD dwBmBitsSize;
  248. dwBmBitsSize = ( ( (lpBI->biWidth)*((DWORD)lpBI->biBitCount) + 31) / 32 * 4) * lpBI->biHeight;
  249. dwDIBSize += dwBmBitsSize;
  250. lpBI->biSizeImage = dwBmBitsSize;
  251. }
  252. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  253. bmfHdr.bfReserved1 = 0;
  254. bmfHdr.bfReserved2 = 0;
  255. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
  256. + GetPaletteSize((LPSTR)lpBI);
  257. file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  258. file.WriteHuge(lpBI, dwDIBSize);
  259. ::GlobalUnlock((HGLOBAL) hDib);
  260. return TRUE;
  261. }