/tags/JSTUDIO3D_2_6_0/source/Tools/Editor/MfcUtil.cpp

# · C++ · 621 lines · 376 code · 127 blank · 118 comment · 65 complexity · 175eb95bce28343eb726c53669875f87 MD5 · raw file

  1. /****************************************************************************************/
  2. /* MFCUTIL.CPP */
  3. /* */
  4. /* Author: */
  5. /* Description: */
  6. /* */
  7. /* The contents of this file are subject to the Jet3D Public License */
  8. /* Version 1.02 (the "License"); you may not use this file except in */
  9. /* compliance with the License. You may obtain a copy of the License at */
  10. /* http://www.jet3d.com */
  11. /* */
  12. /* Software distributed under the License is distributed on an "AS IS" */
  13. /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
  14. /* the License for the specific language governing rights and limitations */
  15. /* under the License. */
  16. /* */
  17. /* The Original Code is Jet3D, released December 12, 1999. */
  18. /* Copyright (C) 1996-2006 Eclipse Entertainment, L.L.C. All Rights Reserved */
  19. /* */
  20. /****************************************************************************************/
  21. #include "stdafx.h"
  22. #include "..\Resource.h"
  23. #include "MfcUtil.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. void PositionDialogUnderTabs( CDialog * pDlg )
  30. {
  31. RECT rect;
  32. RECT TabRect ;
  33. CTabCtrl * pTC ;
  34. int i ;
  35. int nTabs ;
  36. pTC = (CTabCtrl*)pDlg->GetParent( ) ;
  37. nTabs = pTC->GetItemCount() ;
  38. TabRect.top = TabRect.left = 1000 ;
  39. TabRect.bottom = TabRect.right = 0 ;
  40. for( i=0; i< nTabs; i++ )
  41. {
  42. pTC->GetItemRect( i, &rect );
  43. if( rect.left < TabRect.left )
  44. TabRect.left = rect.left ;
  45. if( rect.right > TabRect.right )
  46. TabRect.right = rect.right ;
  47. if( rect.top < TabRect.top )
  48. TabRect.top = rect.top ;
  49. if( rect.bottom > TabRect.bottom )
  50. TabRect.bottom = rect.bottom ;
  51. }
  52. pDlg->SetWindowPos
  53. (
  54. NULL,
  55. TabRect.left + GetSystemMetrics(SM_CXDLGFRAME),
  56. TabRect.bottom + GetSystemMetrics(SM_CYDLGFRAME),
  57. 0, 0,
  58. SWP_NOZORDER|SWP_NOSIZE
  59. ) ;
  60. }// PositionDialogUnderTabs
  61. // LoadBMPImage - Loads a BMP file and creates a bitmap GDI object
  62. // also creates logical palette for it.
  63. // Returns - TRUE for success
  64. // sBMPFile - Full path of the BMP file
  65. // bitmap - The bitmap object to initialize
  66. // pPal - Will hold the logical palette. Can be NULL
  67. BOOL LoadBMPImage( LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal )
  68. {
  69. CFile file ;
  70. BITMAPFILEHEADER bmfHeader ; // Read file header
  71. WORD nColors ;
  72. if( !file.Open( sBMPFile, CFile::modeRead) )
  73. return FALSE ;
  74. if( file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader) )
  75. return FALSE; // File type should be 'BM'
  76. if( bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
  77. return FALSE;
  78. // Get length of the remainder of the file and allocate memory
  79. DWORD nPackedDIBLen = (DWORD)(file.GetLength() - sizeof(BITMAPFILEHEADER));
  80. HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
  81. if( hDIB == 0 )
  82. return FALSE; // Read the remainder of the bitmap file.
  83. if( file.Read((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
  84. {
  85. ::GlobalFree(hDIB);
  86. return FALSE;
  87. }
  88. BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
  89. BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
  90. // If bmiHeader.biClrUsed is zero we have to infer the number
  91. // of colors from the number of bits used to specify it.
  92. nColors = (bmiHeader.biClrUsed)
  93. ? (WORD) bmiHeader.biClrUsed
  94. : (WORD)(1 << bmiHeader.biBitCount);
  95. LPVOID lpDIBBits;
  96. if( bmInfo.bmiHeader.biBitCount > 8 )
  97. lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
  98. ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
  99. else
  100. lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
  101. // Create the logical palette
  102. if( pPal != NULL )
  103. { // Create the palette
  104. if( nColors <= 256 )
  105. {
  106. UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
  107. LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  108. pLP->palVersion = 0x300;
  109. pLP->palNumEntries = nColors;
  110. for( int i=0; i < nColors; i++)
  111. {
  112. pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
  113. pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
  114. pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
  115. pLP->palPalEntry[i].peFlags = 0;
  116. }
  117. pPal->CreatePalette( pLP );
  118. delete[] pLP;
  119. }
  120. }
  121. CClientDC dc(NULL);
  122. CPalette* pOldPalette = NULL;
  123. if( pPal )
  124. {
  125. pOldPalette = dc.SelectPalette( pPal, FALSE );
  126. dc.RealizePalette();
  127. }
  128. HBITMAP hBmp = CreateDIBitmap
  129. (
  130. dc.m_hDC, // handle to device context
  131. &bmiHeader, // pointer to bitmap size and format data
  132. CBM_INIT, // initialization flag
  133. lpDIBBits, // pointer to initialization data
  134. &bmInfo, // pointer to bitmap color-format data
  135. DIB_RGB_COLORS // color-data usage
  136. );
  137. bitmap.Attach( hBmp );
  138. if( pOldPalette )
  139. dc.SelectPalette( pOldPalette, FALSE );
  140. ::GlobalFree(hDIB) ;
  141. return TRUE ;
  142. }// LoadBMPImage
  143. void TrimString( CString &strString )
  144. {
  145. strString.TrimRight() ;
  146. strString.TrimLeft() ;
  147. }// TrimString
  148. void TrimStringByPixelCount( HDC hDC, char * psz, const int nMaxPixels )
  149. {
  150. int nLen = strlen( psz ) ;
  151. SIZE size ;
  152. do
  153. {
  154. ::GetTextExtentPoint32( hDC, psz, nLen, &size ) ;
  155. if( size.cx > nMaxPixels )
  156. psz[--nLen] = 0 ;
  157. }while( (size.cx > nMaxPixels) && (nLen>0) ) ;
  158. }// TrimStringByPixelCount
  159. void SetupTemplateDialogIcons( CDialog * pDlg )
  160. {
  161. HICON hIcon ;
  162. CWinApp * pApp ;
  163. pApp = AfxGetApp() ;
  164. hIcon = pApp->LoadIcon( IDI_CUBE );
  165. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACECUBE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon) ;
  166. hIcon = pApp->LoadIcon( IDI_SPHERE ) ;
  167. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACESPHEROID, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon) ;
  168. hIcon = pApp->LoadIcon( IDI_CYLINDER ) ;
  169. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACECYLINDER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon) ;
  170. hIcon = pApp->LoadIcon( IDI_STAIRS ) ;
  171. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACESTAIRCASE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon) ;
  172. hIcon = pApp->LoadIcon( IDI_ARCH ) ;
  173. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACEARCH, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  174. hIcon = pApp->LoadIcon( IDI_CONE ) ;
  175. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACECONE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  176. hIcon = pApp->LoadIcon( IDI_LIGHT ) ;
  177. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACELIGHT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  178. hIcon = pApp->LoadIcon( IDI_ENTITY ) ;
  179. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACEENTITY, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  180. hIcon = pApp->LoadIcon( IDI_TERRAIN ) ;
  181. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACETERRAIN, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  182. hIcon = pApp->LoadIcon( IDI_SHEET ) ;
  183. pDlg->SendDlgItemMessage( IDM_TOOLS_PLACESHEET, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon ) ;
  184. }// SetupTemplateDialogIcons
  185. HTREEITEM TreeViewIsInBranch( CTreeCtrl *pTV, HTREEITEM hItem, const char * psz)
  186. {
  187. HTREEITEM hChild ;
  188. CString cstr ;
  189. ASSERT( pTV != NULL ) ;
  190. ASSERT( psz != NULL ) ;
  191. if( pTV->ItemHasChildren( hItem ) == 0 )
  192. return NULL ;
  193. hChild = pTV->GetChildItem( hItem ) ;
  194. do
  195. {
  196. cstr = pTV->GetItemText( hChild ) ;
  197. if( cstr.Compare( psz ) == 0 )
  198. return hChild ;
  199. hChild = pTV->GetNextSiblingItem( hChild ) ;
  200. }while( hChild != NULL ) ;
  201. return NULL ;
  202. }// TreeViewIsInBranch
  203. //----------------------------------------------------------
  204. // BMP-Utils
  205. #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
  206. #define PALVERSION 0x300
  207. #define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
  208. #define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)
  209. #define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top)
  210. #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
  211. WORD WINAPI DIBNumColors(LPSTR lpbi)
  212. {
  213. WORD wBitCount; // DIB bit count
  214. /* If this is a Windows-style DIB, the number of colors in the
  215. * color table can be less than the number of bits per pixel
  216. * allows for (i.e. lpbi->biClrUsed can be set to some value).
  217. * If this is the case, return the appropriate value.
  218. */
  219. if (IS_WIN30_DIB(lpbi))
  220. {
  221. DWORD dwClrUsed;
  222. dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  223. if (dwClrUsed != 0)
  224. return (WORD)dwClrUsed;
  225. }
  226. /* Calculate the number of colors in the color table based on
  227. * the number of bits per pixel for the DIB.
  228. */
  229. if (IS_WIN30_DIB(lpbi))
  230. wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
  231. else
  232. wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
  233. /* return number of colors based on bits per pixel */
  234. switch (wBitCount)
  235. {
  236. case 1:
  237. return 2;
  238. case 4:
  239. return 16;
  240. case 8:
  241. return 256;
  242. default:
  243. return 0;
  244. }
  245. }
  246. WORD WINAPI PaletteSize(LPSTR lpbi)
  247. {
  248. /* calculate the size required by the palette */
  249. if (IS_WIN30_DIB (lpbi))
  250. return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
  251. else
  252. return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
  253. }
  254. /*************************************************************************
  255. *
  256. * SaveDIB()
  257. *
  258. * Saves the specified DIB into the specified CFile. The CFile
  259. * is opened and closed by the caller.
  260. *
  261. * Parameters:
  262. *
  263. * HDIB hDib - Handle to the dib to save
  264. *
  265. * CFile& file - open CFile used to save DIB
  266. *
  267. * Return value: TRUE if successful, else FALSE or CFileException
  268. *
  269. *************************************************************************/
  270. #include "ErrorLog.h"
  271. jeBoolean SaveDIB(jeVFile * pF, jePtrMgr *pPtrMgr ,HANDLE hDib)
  272. {
  273. BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
  274. LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure
  275. DWORD dwDIBSize;
  276. if (hDib == NULL)
  277. return JE_FALSE;
  278. /*
  279. * Get a pointer to the DIB memory, the first of which contains
  280. * a BITMAPINFO structure
  281. */
  282. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  283. if (lpBI == NULL)
  284. return JE_FALSE;
  285. if (!IS_WIN30_DIB(lpBI))
  286. {
  287. ::GlobalUnlock((HGLOBAL) hDib);
  288. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "SaveDIB: Unsupported DIB", "Jet3D");
  289. return JE_FALSE; // It's an other-style DIB (save not supported)
  290. }
  291. /*
  292. * Fill in the fields of the file header
  293. */
  294. /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
  295. bmfHdr.bfType = DIB_HEADER_MARKER; // "BM"
  296. // Calculating the size of the DIB is a bit tricky (if we want to
  297. // do it right). The easiest way to do this is to call GlobalSize()
  298. // on our global handle, but since the size of our global memory may have
  299. // been padded a few bytes, we may end up writing out a few too
  300. // many bytes to the file (which may cause problems with some apps).
  301. //
  302. // So, instead let's calculate the size manually (if we can)
  303. //
  304. // First, find size of header plus size of color table. Since the
  305. // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
  306. // the size of the structure, let's use this.
  307. dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI); // Partial Calculation
  308. // Now calculate the size of the image
  309. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  310. {
  311. // It's an RLE bitmap, we can't calculate size, so trust the
  312. // biSizeImage field
  313. dwDIBSize += lpBI->biSizeImage;
  314. }
  315. else
  316. {
  317. DWORD dwBmBitsSize; // Size of Bitmap Bits only
  318. // It's not RLE, so size is Width (DWORD aligned) * Height
  319. dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
  320. dwDIBSize += dwBmBitsSize;
  321. // Now, since we have calculated the correct size, why don't we
  322. // fill in the biSizeImage field (this will fix any .BMP files which
  323. // have this field incorrect).
  324. lpBI->biSizeImage = dwBmBitsSize;
  325. }
  326. // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
  327. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  328. bmfHdr.bfReserved1 = 0;
  329. bmfHdr.bfReserved2 = 0;
  330. /*
  331. * Now, calculate the offset the actual bitmap bits will be in
  332. * the file -- It's the Bitmap file header plus the DIB header,
  333. * plus the size of the color table.
  334. */
  335. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
  336. // Write the file header
  337. if(jeVFile_Write( pF, &bmfHdr, sizeof(BITMAPFILEHEADER) ) == JE_FALSE )
  338. { ::GlobalUnlock((HGLOBAL) hDib);
  339. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "SaveDIB: Write of BMP-Header failed", "Jet3D");
  340. return JE_FALSE;
  341. }
  342. // Write the DIB header and the bits
  343. if(jeVFile_Write( pF, lpBI, dwDIBSize ) == JE_FALSE )
  344. { ::GlobalUnlock((HGLOBAL) hDib);
  345. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "SaveDIB: Write of BMP-Body failed", "Jet3D");
  346. return JE_FALSE;
  347. }
  348. ::GlobalUnlock((HGLOBAL) hDib);
  349. return TRUE;
  350. }
  351. // DDBToDIB - Creates a DIB from a DDB
  352. // bitmap - Device dependent bitmap
  353. // dwCompression - Type of compression - see BITMAPINFOHEADER
  354. // pPal - Logical palette
  355. HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
  356. {
  357. BITMAP bm;
  358. BITMAPINFOHEADER bi;
  359. LPBITMAPINFOHEADER lpbi;
  360. DWORD dwLen;
  361. HANDLE hDIB;
  362. HANDLE handle;
  363. HDC hDC;
  364. HPALETTE hPal;
  365. ASSERT( bitmap.GetSafeHandle() );
  366. // The function has no arg for bitfields
  367. if( dwCompression == BI_BITFIELDS )
  368. return NULL;
  369. // If a palette has not been supplied use defaul palette
  370. hPal = (HPALETTE) pPal->GetSafeHandle();
  371. if (hPal==NULL)
  372. hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
  373. // Get bitmap information
  374. bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
  375. // Initialize the bitmapinfoheader
  376. bi.biSize = sizeof(BITMAPINFOHEADER);
  377. bi.biWidth = (bm.bmWidth/4+1)*4;
  378. bi.biHeight = bm.bmHeight;
  379. bi.biPlanes = 1;
  380. bi.biBitCount = 0; //Icestorm: GetDIBits want this to be 0 th first time
  381. bi.biCompression = dwCompression;
  382. bi.biSizeImage = 0;
  383. bi.biXPelsPerMeter = 0;
  384. bi.biYPelsPerMeter = 0;
  385. bi.biClrUsed = 0;
  386. bi.biClrImportant = 0;
  387. // Compute the size of the infoheader and the color table
  388. int nColors = (1 << (bm.bmPlanes * bm.bmBitsPixel));
  389. if( nColors > 256 )
  390. nColors = 0;
  391. dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
  392. // We need a device context to get the DIB from
  393. hDC = GetDC(NULL);
  394. hPal = SelectPalette(hDC,hPal,FALSE);
  395. RealizePalette(hDC);
  396. // Allocate enough memory to hold bitmapinfoheader and color table
  397. hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
  398. if (!hDIB){
  399. SelectPalette(hDC,hPal,FALSE);
  400. ReleaseDC(NULL,hDC);
  401. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "DDBToDIB: No mem left", "Jet3D");
  402. return NULL;
  403. }
  404. lpbi = (LPBITMAPINFOHEADER)hDIB;
  405. *lpbi = bi;
  406. // Call GetDIBits with a NULL lpBits param, so the device driver
  407. // will calculate the biSizeImage field
  408. GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
  409. (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
  410. bi = *lpbi;
  411. // If the driver did not fill in the biSizeImage field, then compute it
  412. // Each scan line of the image is aligned on a DWORD (32bit) boundary
  413. if (bi.biSizeImage == 0){
  414. bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
  415. * bi.biHeight;
  416. // If a compression scheme is used the result may infact be larger
  417. // Increase the size to account for this.
  418. if (dwCompression != BI_RGB)
  419. bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  420. }
  421. // Realloc the buffer so that it can hold all the bits
  422. dwLen += bi.biSizeImage;
  423. if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
  424. hDIB = handle;
  425. else{
  426. GlobalFree(hDIB);
  427. // Reselect the original palette
  428. SelectPalette(hDC,hPal,FALSE);
  429. ReleaseDC(NULL,hDC);
  430. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "DDBToDIB: GlobalReAlloc failed", "Jet3D");
  431. return NULL;
  432. }
  433. // Get the bitmap bits
  434. lpbi = (LPBITMAPINFOHEADER)hDIB;
  435. // FINALLY get the DIB
  436. BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
  437. 0L, // Start scan line
  438. (DWORD)bi.biHeight, // # of scan lines
  439. (LPBYTE)lpbi // address for bitmap bits
  440. + (bi.biSize /*+ nColors * sizeof(RGBQUAD)*/), //Icestorm: GetDIBBits copies the table,too
  441. (LPBITMAPINFO)lpbi, // address of bitmapinfo
  442. (DWORD)DIB_RGB_COLORS); // Use RGB for color table
  443. if( !bGotBits )
  444. {
  445. GlobalFree(hDIB);
  446. SelectPalette(hDC,hPal,FALSE);
  447. ReleaseDC(NULL,hDC);
  448. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "DDBToDIB: GetDIBits failed", "Jet3D");
  449. return NULL;
  450. }
  451. SelectPalette(hDC,hPal,FALSE);
  452. ReleaseDC(NULL,hDC);
  453. return hDIB;
  454. }
  455. jeBoolean WriteWindowToDIB( jeVFile * pF, jePtrMgr *pPtrMgr , CWnd *pWnd )
  456. {
  457. CBitmap bitmap;
  458. CWindowDC dc(pWnd);
  459. CDC memDC;
  460. CRect rect;
  461. BOOL ret;
  462. memDC.CreateCompatibleDC(&dc);
  463. pWnd->GetWindowRect(rect);
  464. bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
  465. CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
  466. memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
  467. // Create logical palette if device support a palette
  468. CPalette pal;
  469. if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
  470. {
  471. UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
  472. LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  473. pLP->palVersion = 0x300;
  474. pLP->palNumEntries =
  475. GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
  476. // Create the palette
  477. pal.CreatePalette( pLP );
  478. delete[] pLP;
  479. }
  480. memDC.SelectObject(pOldBitmap);
  481. // Convert the bitmap to a DIB
  482. HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );
  483. if( hDIB == NULL )
  484. {
  485. GlobalFree( hDIB );
  486. jeErrorLog_AddString( JE_ERR_WINDOWS_API_FAILURE, "WriteWindowToDIB: bitmap to a DIB failed", "Jet3D");
  487. return JE_FALSE;
  488. }
  489. // Write it to file
  490. ret = SaveDIB( pF, pPtrMgr, hDIB );
  491. // Free the memory allocated by DDBToDIB for the DIB
  492. GlobalFree( hDIB );
  493. return JE_TRUE;
  494. }