Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
6.7 KiB

  1. #include "pre.h"
  2. PBITMAPINFO CreateBitmapInfoStruct
  3. (
  4. HBITMAP hBmp
  5. )
  6. {
  7. BITMAP bmp;
  8. PBITMAPINFO pbmi;
  9. WORD cClrBits;
  10. // Retrieve the bitmap's color format, width, and height.
  11. if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
  12. return NULL;
  13. // Convert the color format to a count of bits.
  14. cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
  15. if (cClrBits == 1)
  16. cClrBits = 1;
  17. else if (cClrBits <= 4)
  18. cClrBits = 4;
  19. else if (cClrBits <= 8)
  20. cClrBits = 8;
  21. else if (cClrBits <= 16)
  22. cClrBits = 16;
  23. else if (cClrBits <= 24)
  24. cClrBits = 24;
  25. else cClrBits = 32;
  26. // Allocate memory for the BITMAPINFO structure. (This structure
  27. // contains a BITMAPINFOHEADER structure and an array of RGBQUAD
  28. // data structures.)
  29. if (cClrBits != 24)
  30. {
  31. pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
  32. sizeof(BITMAPINFOHEADER) +
  33. sizeof(RGBQUAD) * (1<< cClrBits));
  34. }
  35. else
  36. {
  37. // There is no RGBQUAD array for the 24-bit-per-pixel format.
  38. pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
  39. }
  40. if (pbmi)
  41. {
  42. // Initialize the fields in the BITMAPINFO structure.
  43. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  44. pbmi->bmiHeader.biWidth = bmp.bmWidth;
  45. pbmi->bmiHeader.biHeight = bmp.bmHeight;
  46. pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
  47. pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
  48. if (cClrBits < 24)
  49. pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
  50. // If the bitmap is not compressed, set the BI_RGB flag.
  51. pbmi->bmiHeader.biCompression = BI_RGB;
  52. // Compute the number of bytes in the array of color
  53. // indices and store the result in biSizeImage.
  54. pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8
  55. * pbmi->bmiHeader.biHeight
  56. * cClrBits;
  57. // Set biClrImportant to 0, indicating that all of the
  58. // device colors are important.
  59. pbmi->bmiHeader.biClrImportant = 0;
  60. }
  61. return pbmi;
  62. }
  63. BOOL CreateBMPFile
  64. (
  65. LPTSTR pszFile,
  66. PBITMAPINFO pbi,
  67. HBITMAP hBMP,
  68. HDC hDC
  69. )
  70. {
  71. HANDLE hf; // file handle
  72. BITMAPFILEHEADER hdr; // bitmap file-header
  73. PBITMAPINFOHEADER pbih; // bitmap info-header
  74. LPBYTE lpBits; // memory pointer
  75. DWORD dwTotal; // total count of bytes
  76. DWORD cb; // incremental count of bytes
  77. BYTE *hp; // byte pointer
  78. DWORD dwTmp;
  79. pbih = (PBITMAPINFOHEADER) pbi;
  80. lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
  81. if (!lpBits)
  82. return FALSE;
  83. // Retrieve the color table (RGBQUAD array) and the bits
  84. // (array of palette indices) from the DIB.
  85. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS))
  86. {
  87. return FALSE;
  88. }
  89. // Create the .BMP file.
  90. hf = CreateFile(pszFile,
  91. GENERIC_READ | GENERIC_WRITE,
  92. (DWORD) 0,
  93. NULL,
  94. CREATE_ALWAYS,
  95. FILE_ATTRIBUTE_NORMAL,
  96. (HANDLE) NULL);
  97. if (hf == INVALID_HANDLE_VALUE)
  98. return FALSE;
  99. hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
  100. // Compute the size of the entire file.
  101. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
  102. pbih->biSize + pbih->biClrUsed
  103. * sizeof(RGBQUAD) + pbih->biSizeImage);
  104. hdr.bfReserved1 = 0;
  105. hdr.bfReserved2 = 0;
  106. // Compute the offset to the array of color indices.
  107. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
  108. pbih->biSize + pbih->biClrUsed
  109. * sizeof (RGBQUAD);
  110. // Copy the BITMAPFILEHEADER into the .BMP file.
  111. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
  112. (LPDWORD) &dwTmp, NULL))
  113. {
  114. return FALSE;
  115. }
  116. // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
  117. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
  118. + pbih->biClrUsed * sizeof (RGBQUAD),
  119. (LPDWORD) &dwTmp, ( NULL)))
  120. {
  121. return FALSE;
  122. }
  123. // Copy the array of color indices into the .BMP file.
  124. dwTotal = cb = pbih->biSizeImage;
  125. hp = lpBits;
  126. if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
  127. {
  128. return FALSE;
  129. }
  130. // Close the .BMP file.
  131. if (!CloseHandle(hf))
  132. {
  133. return FALSE;
  134. }
  135. // Free memory.
  136. GlobalFree((HGLOBAL)lpBits);
  137. return TRUE;
  138. }
  139. BOOL CopyBitmapRectToFile
  140. (
  141. HBITMAP hbm,
  142. LPRECT lpRect,
  143. LPTSTR lpszFileName
  144. )
  145. {
  146. HDC hSrcDC, hDestDC; // screen DC and memory DC
  147. HDC hScreenDC;
  148. HBITMAP hBitmap, hOldBitmap, hOldSrcBitmap;
  149. PBITMAPINFO pbmi;
  150. BOOL bRet;
  151. // check for an empty rectangle
  152. if (IsRectEmpty(lpRect))
  153. return FALSE;
  154. // get the Source Window DC and create
  155. // a memory DC compatible to screen DC
  156. hScreenDC = GetDC(NULL);
  157. hSrcDC = CreateCompatibleDC(hScreenDC);
  158. hDestDC = CreateCompatibleDC(hScreenDC);
  159. // create a dest bitmap
  160. hBitmap = CreateCompatibleBitmap(hScreenDC, RECTWIDTH(*lpRect), RECTHEIGHT(*lpRect));
  161. // select new bitmap into memory DC
  162. hOldBitmap = (HBITMAP)SelectObject(hDestDC, hBitmap);
  163. // Select the passed in BMP into the SrcDC
  164. hOldSrcBitmap = (HBITMAP)SelectObject(hSrcDC, hbm);
  165. // bitblt screen DC to memory DC
  166. BitBlt(hDestDC,
  167. 0,
  168. 0,
  169. RECTWIDTH(*lpRect),
  170. RECTHEIGHT(*lpRect),
  171. hSrcDC,
  172. lpRect->left,
  173. lpRect->top,
  174. SRCCOPY);
  175. pbmi = CreateBitmapInfoStruct(hBitmap);
  176. if (pbmi)
  177. {
  178. bRet = CreateBMPFile(lpszFileName, pbmi, hBitmap, hDestDC);
  179. LocalFree(pbmi);
  180. pbmi = NULL;
  181. }
  182. // clean up
  183. DeleteObject(SelectObject(hDestDC, hOldBitmap));
  184. SelectObject(hSrcDC, hOldSrcBitmap);
  185. DeleteDC(hSrcDC);
  186. DeleteDC(hDestDC);
  187. ReleaseDC(NULL, hScreenDC);
  188. return bRet;
  189. }