Source code of Windows XP (NT5)
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.

747 lines
18 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: Cbitmap.cpp
  3. //
  4. // Desc: CBitmap class is an object that wraps around a Windows bitmap.
  5. //
  6. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "common.hpp"
  9. #include "id3dsurf.h"
  10. //@@BEGIN_MSINTERNAL
  11. #ifdef DDKBUILD
  12. //HMODULE g_MSImg32 = NULL;
  13. //ALPHABLEND g_AlphaBlend = NULL;
  14. #endif
  15. //@@END_MSINTERNAL
  16. BOOL DI_AlphaBlend(
  17. HDC hdcDest, // handle to destination DC
  18. int nXOriginDest, // x-coord of upper-left corner
  19. int nYOriginDest, // y-coord of upper-left corner
  20. int nWidthDest, // destination width
  21. int nHeightDest, // destination height
  22. HDC hdcSrc, // handle to source DC
  23. int nXOriginSrc, // x-coord of upper-left corner
  24. int nYOriginSrc, // y-coord of upper-left corner
  25. int nWidthSrc, // source width
  26. int nHeightSrc // source height
  27. )
  28. {
  29. LPBYTE pbDestBits = NULL;
  30. HBITMAP hTempDestDib = NULL;
  31. int nXOriginDestLogical = nXOriginDest, nYOriginDestLogical = nYOriginDest;
  32. // Convert nXOriginDest and nYOriginDest from logical coord to device coord
  33. POINT pt = {nXOriginDest, nYOriginDest};
  34. LPtoDP(hdcDest, &pt, 1);
  35. nXOriginDest = pt.x;
  36. nYOriginDest = pt.y;
  37. // Convert nXOriginSrc and nYOriginSrc from logical coord to device coord
  38. pt.x = nXOriginSrc;
  39. pt.y = nYOriginSrc;
  40. LPtoDP(hdcSrc, &pt, 1);
  41. nXOriginSrc = pt.x;
  42. nYOriginSrc = pt.y;
  43. // Get the bits for both source and destination first
  44. // Every BITMAP used in the UI is created with CreateDIBSection, so we know we can get the bits.
  45. HBITMAP hSrcBmp, hDestBmp;
  46. DIBSECTION SrcDibSec, DestDibSec;
  47. hSrcBmp = (HBITMAP)GetCurrentObject(hdcSrc, OBJ_BITMAP);
  48. GetObject(hSrcBmp, sizeof(DIBSECTION), &SrcDibSec);
  49. hDestBmp = (HBITMAP)GetCurrentObject(hdcDest, OBJ_BITMAP);
  50. GetObject(hDestBmp, sizeof(DIBSECTION), &DestDibSec);
  51. if (!SrcDibSec.dsBm.bmBits) return FALSE; // Not necessary, but to be absolutely safe.
  52. // Calculate the rectangle to perform the operation.
  53. if (nXOriginSrc + nWidthSrc > SrcDibSec.dsBm.bmWidth) nWidthSrc = SrcDibSec.dsBm.bmWidth - nXOriginSrc;
  54. if (nYOriginSrc + nHeightSrc > SrcDibSec.dsBm.bmHeight) nHeightSrc = SrcDibSec.dsBm.bmHeight - nYOriginSrc;
  55. if (nXOriginDest + nWidthDest > DestDibSec.dsBm.bmWidth) nWidthDest = DestDibSec.dsBm.bmWidth - nXOriginDest;
  56. if (nYOriginDest + nHeightDest > DestDibSec.dsBm.bmHeight) nHeightDest = DestDibSec.dsBm.bmHeight - nYOriginDest;
  57. if (nWidthDest > nWidthSrc) nWidthDest = nWidthSrc;
  58. if (nHeightDest > nHeightSrc) nHeightDest = nHeightSrc;
  59. if (nWidthSrc > nWidthDest) nWidthSrc = nWidthDest;
  60. if (nHeightSrc > nHeightDest) nHeightSrc = nHeightDest;
  61. BITMAPINFO bmi;
  62. ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
  63. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  64. bmi.bmiHeader.biWidth = nWidthDest;
  65. bmi.bmiHeader.biHeight = nHeightDest;
  66. bmi.bmiHeader.biPlanes = 1;
  67. bmi.bmiHeader.biBitCount = 32;
  68. bmi.bmiHeader.biCompression = BI_RGB;
  69. // Bitmap will have the same width as the dest, but only lines covered in the subrect.
  70. hTempDestDib = CreateDIBSection(hdcDest, &bmi, DIB_RGB_COLORS, (LPVOID*)&pbDestBits, NULL, NULL);
  71. if (!hTempDestDib)
  72. return FALSE;
  73. HDC hTempDC = CreateCompatibleDC(hdcDest);
  74. if (!hTempDC)
  75. {
  76. DeleteObject(hTempDestDib);
  77. return FALSE;
  78. }
  79. HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hTempDC, hTempDestDib);
  80. BOOL res = BitBlt(hTempDC, 0, 0, nWidthDest, nHeightDest, hdcDest, nXOriginDestLogical, nYOriginDestLogical, SRCCOPY);
  81. SelectObject(hTempDC, hOldTempBmp);
  82. DeleteDC(hTempDC);
  83. if (!res)
  84. {
  85. DeleteObject(hTempDestDib);
  86. return FALSE;
  87. }
  88. // We have the bits. Now do the blend.
  89. for (int j = 0; j < nHeightSrc; ++j)
  90. {
  91. assert(j >= 0 &&
  92. j < nHeightDest);
  93. LPBYTE pbDestRGB = (LPBYTE)&((DWORD*)pbDestBits)[j * nWidthDest];
  94. assert(nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc >= 0 &&
  95. nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc < SrcDibSec.dsBm.bmHeight);
  96. LPBYTE pbSrcRGBA = (LPBYTE)&((DWORD*)SrcDibSec.dsBm.bmBits)[(j+nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc)
  97. * SrcDibSec.dsBm.bmWidth + nXOriginSrc];
  98. for (int i = 0; i < nWidthSrc; ++i)
  99. {
  100. // Blend
  101. if (pbSrcRGBA[3] == 255)
  102. {
  103. // Alpha is 255. straight copy.
  104. *(LPDWORD)pbDestRGB = *(LPDWORD)pbSrcRGBA;
  105. } else
  106. if (pbSrcRGBA[3])
  107. {
  108. // Alpha is non-zero
  109. pbDestRGB[0] = pbSrcRGBA[0] + (((255-pbSrcRGBA[3]) * pbDestRGB[0]) >> 8);
  110. pbDestRGB[1] = pbSrcRGBA[1] + (((255-pbSrcRGBA[3]) * pbDestRGB[1]) >> 8);
  111. pbDestRGB[2] = pbSrcRGBA[2] + (((255-pbSrcRGBA[3]) * pbDestRGB[2]) >> 8);
  112. }
  113. pbDestRGB += sizeof(DWORD);
  114. pbSrcRGBA += sizeof(DWORD);
  115. } // for
  116. } // for
  117. HDC hdcTempDest = CreateCompatibleDC(hdcDest);
  118. if (hdcTempDest)
  119. {
  120. HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hdcTempDest, hTempDestDib); // Select the temp dib for blitting
  121. // Get logical coord for device coord of dest origin
  122. POINT pt = {nXOriginDest, nYOriginDest};
  123. DPtoLP(hdcDest, &pt, 1);
  124. BitBlt(hdcDest, pt.x, pt.y, nWidthDest, nHeightDest,
  125. hdcTempDest, 0, 0, SRCCOPY);
  126. SelectObject(hdcTempDest, hOldTempBmp);
  127. DeleteDC(hdcTempDest);
  128. }
  129. DeleteObject(hTempDestDib);
  130. return TRUE;
  131. }
  132. CBitmap::~CBitmap()
  133. {
  134. if (m_hbm != NULL)
  135. DeleteObject(m_hbm);
  136. m_hbm = NULL;
  137. m_bSizeKnown = FALSE;
  138. }
  139. HDC CreateAppropDC(HDC hDC)
  140. {
  141. return CreateCompatibleDC(hDC);
  142. }
  143. HBITMAP CreateAppropBitmap(HDC hDC, int cx, int cy)
  144. {
  145. if (hDC != NULL)
  146. return CreateCompatibleBitmap(hDC, cx, cy);
  147. HWND hWnd = GetDesktopWindow();
  148. HDC hWDC = GetWindowDC(hWnd);
  149. HBITMAP hbm = NULL;
  150. if (hWDC != NULL)
  151. {
  152. hbm = CreateCompatibleBitmap(hWDC, cx, cy);
  153. ReleaseDC(hWnd, hWDC);
  154. }
  155. return hbm;
  156. }
  157. CBitmap *CBitmap::CreateFromResource(HINSTANCE hInst, LPCTSTR tszName)
  158. {
  159. return CreateViaLoadImage(hInst, tszName, IMAGE_BITMAP, 0, 0,
  160. LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
  161. }
  162. CBitmap *CBitmap::CreateFromFile(LPCTSTR tszFileName)
  163. {
  164. return CreateViaD3DX(tszFileName);
  165. }
  166. // Use D3DX API to load our surface with image content.
  167. CBitmap *CBitmap::CreateViaD3DX(LPCTSTR tszFileName, LPDIRECT3DSURFACE8 pUISurf)
  168. {
  169. HRESULT hr;
  170. LPDIRECT3D8 pD3D = NULL;
  171. LPDIRECT3DDEVICE8 pD3DDev = NULL;
  172. LPDIRECT3DTEXTURE8 pTex = NULL;
  173. LPDIRECT3DSURFACE8 pSurf = NULL;
  174. HBITMAP hDIB = NULL;
  175. __try
  176. {
  177. //@@BEGIN_MSINTERNAL
  178. pSurf = GetCloneSurface(512, 512); /*
  179. //@@END_MSINTERNAL
  180. // If the UI surface is NULL, create a new device. Otherwise, use existing device.
  181. if (!pUISurf)
  182. {
  183. pD3D = Direct3DCreate8(D3D_SDK_VERSION);
  184. if (!pD3D)
  185. return NULL;
  186. OutputDebugString(_T("D3D created\n"));
  187. D3DDISPLAYMODE Mode;
  188. pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode);
  189. D3DPRESENT_PARAMETERS d3dpp;
  190. d3dpp.BackBufferWidth = 1;
  191. d3dpp.BackBufferHeight = 1;
  192. d3dpp.BackBufferFormat = Mode.Format;
  193. d3dpp.BackBufferCount = 1;
  194. d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
  195. d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
  196. d3dpp.hDeviceWindow = NULL;
  197. d3dpp.Windowed = TRUE;
  198. d3dpp.EnableAutoDepthStencil = FALSE;
  199. d3dpp.FullScreen_RefreshRateInHz = 0;
  200. d3dpp.FullScreen_PresentationInterval = 0;
  201. d3dpp.Flags = 0;
  202. hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, GetActiveWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDev);
  203. if (FAILED(hr))
  204. {
  205. TCHAR tszMsg[MAX_PATH];
  206. _stprintf(tszMsg, _T("CreateDevice returned 0x%X\n"), hr);
  207. OutputDebugString(tszMsg);
  208. return NULL;
  209. }
  210. } else
  211. {
  212. hr = pUISurf->GetDevice(&pD3DDev);
  213. if (FAILED(hr))
  214. return NULL;
  215. }
  216. OutputDebugString(_T("D3D device createed\n"));
  217. hr = pD3DDev->CreateTexture(512, 512, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTex);
  218. if (FAILED(hr))
  219. return NULL;
  220. OutputDebugString(_T("D3D texture createed\n"));
  221. hr = pTex->GetSurfaceLevel(0, &pSurf);
  222. if (FAILED(hr))
  223. return NULL;
  224. OutputDebugString(_T("Surface interface obtained\n"));
  225. //@@BEGIN_MSINTERNAL
  226. */
  227. //@@END_MSINTERNAL
  228. D3DXIMAGE_INFO d3dii;
  229. if (FAILED(D3DXLoadSurfaceFromFile(pSurf, NULL, NULL, tszFileName, NULL, D3DX_FILTER_NONE, 0, &d3dii)))
  230. return NULL;
  231. // Create a bitmap and copy the texture content onto it.
  232. int iDibWidth = d3dii.Width, iDibHeight = d3dii.Height;
  233. if (iDibWidth > 430) iDibWidth = 430;
  234. if (iDibHeight > 310) iDibHeight = 310;
  235. LPBYTE pDIBBits;
  236. BITMAPINFO bmi;
  237. bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  238. bmi.bmiHeader.biWidth = iDibWidth;
  239. bmi.bmiHeader.biHeight = iDibHeight;
  240. bmi.bmiHeader.biPlanes = 1;
  241. bmi.bmiHeader.biBitCount = 32;
  242. bmi.bmiHeader.biCompression = BI_RGB;
  243. bmi.bmiHeader.biSizeImage = 0;
  244. bmi.bmiHeader.biXPelsPerMeter = 0;
  245. bmi.bmiHeader.biYPelsPerMeter = 0;
  246. bmi.bmiHeader.biClrUsed = 0;
  247. bmi.bmiHeader.biClrImportant = 0;
  248. hDIB = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (LPVOID*)&pDIBBits, NULL, 0);
  249. if (!hDIB)
  250. return NULL;
  251. // Pre-process the pixel data based on alpha for AlphaBlend()
  252. D3DLOCKED_RECT lrc;
  253. pSurf->LockRect(&lrc, NULL, NULL);
  254. BYTE *pbData = (LPBYTE)lrc.pBits;
  255. {
  256. for (DWORD i = 0; i < 512 * 512; ++i)
  257. {
  258. BYTE bAlpha = pbData[i * 4 + 3];
  259. pbData[i * 4] = pbData[i * 4] * bAlpha / 255;
  260. pbData[i * 4 + 1] = pbData[i * 4 + 1] * bAlpha / 255;
  261. pbData[i * 4 + 2] = pbData[i * 4 + 2] * bAlpha / 255;
  262. }
  263. }
  264. pSurf->UnlockRect();
  265. // Lock the surface
  266. D3DLOCKED_RECT D3DRect;
  267. hr = pSurf->LockRect(&D3DRect, NULL, 0);
  268. if (FAILED(hr))
  269. return NULL;
  270. // Copy the bits
  271. // Note that the image is reversed in Y direction, so we need to re-reverse it.
  272. for (int y = 0; y < iDibHeight; ++y)
  273. CopyMemory(pDIBBits + ((iDibHeight-1-y) * iDibWidth * 4), (LPBYTE)D3DRect.pBits + (y * D3DRect.Pitch), iDibWidth * 4);
  274. // Unlock
  275. pSurf->UnlockRect();
  276. CBitmap *pbm = new CBitmap;
  277. if (!pbm) return NULL;
  278. pbm->m_hbm = hDIB;
  279. hDIB = NULL;
  280. pbm->FigureSize();
  281. return pbm;
  282. }
  283. __finally
  284. {
  285. if (hDIB) DeleteObject(hDIB);
  286. if (pSurf) pSurf->Release();
  287. if (pTex) pTex->Release();
  288. if (pD3DDev) pD3DDev->Release();
  289. if (pD3D) pD3D->Release();
  290. }
  291. //@@BEGIN_MSINTERNAL
  292. /*
  293. //@@END_MSINTERNAL
  294. return NULL;
  295. //@@BEGIN_MSINTERNAL
  296. */
  297. //@@END_MSINTERNAL
  298. }
  299. CBitmap *CBitmap::CreateViaLoadImage(HINSTANCE hInst, LPCTSTR tszName, UINT uType, int cx, int cy, UINT fuLoad)
  300. {
  301. if (fuLoad & LR_SHARED)
  302. {
  303. assert(0);
  304. return NULL;
  305. }
  306. CBitmap *pbm = new CBitmap;
  307. if (pbm == NULL)
  308. return NULL;
  309. HANDLE handle = ::LoadImage(hInst, tszName, uType, cx, cy, fuLoad);
  310. if (handle == NULL)
  311. {
  312. delete pbm;
  313. return NULL;
  314. }
  315. pbm->m_hbm = (HBITMAP)handle;
  316. pbm->FigureSize();
  317. return pbm;
  318. }
  319. BOOL CBitmap::FigureSize()
  320. {
  321. BITMAP bm;
  322. if (0 == GetObject((HGDIOBJ)m_hbm, sizeof(BITMAP), (LPVOID)&bm))
  323. return FALSE;
  324. m_size.cx = abs(bm.bmWidth);
  325. m_size.cy = abs(bm.bmHeight);
  326. return m_bSizeKnown = TRUE;
  327. }
  328. CBitmap *CBitmap::StealToCreate(HBITMAP &refbm)
  329. {
  330. if (refbm == NULL)
  331. return NULL;
  332. CBitmap *pbm = new CBitmap;
  333. if (pbm == NULL)
  334. return NULL;
  335. pbm->m_hbm = refbm;
  336. refbm = NULL;
  337. pbm->FigureSize();
  338. return pbm;
  339. }
  340. BOOL CBitmap::GetSize(SIZE *psize)
  341. {
  342. if (m_hbm == NULL || !m_bSizeKnown || psize == NULL)
  343. return FALSE;
  344. *psize = m_size;
  345. return TRUE;
  346. }
  347. void CBitmap::AssumeSize(SIZE size)
  348. {
  349. m_size = size;
  350. m_bSizeKnown = TRUE; //m_hbm != NULL;
  351. }
  352. CBitmap *CBitmap::CreateResizedTo(SIZE size, HDC hDC, int iStretchMode, BOOL bStretch)
  353. {
  354. CBitmap *pbm = new CBitmap;
  355. HDC hSrcDC = NULL;
  356. HDC hDestDC = NULL;
  357. HBITMAP hBitmap = NULL;
  358. HGDIOBJ hOldSrcBitmap = NULL, hOldDestBitmap = NULL;
  359. BOOL bRet = FALSE;
  360. int oldsm = 0;
  361. POINT brushorg;
  362. if (pbm == NULL || size.cx < 1 || size.cy < 1 || m_hbm == NULL || !m_bSizeKnown)
  363. goto error;
  364. hSrcDC = CreateAppropDC(hDC);
  365. hDestDC = CreateAppropDC(hDC);
  366. if (hSrcDC == NULL || hDestDC == NULL)
  367. goto error;
  368. hBitmap = CreateAppropBitmap(hDC, size.cx, size.cy);
  369. if (hBitmap == NULL)
  370. goto error;
  371. if (bStretch)
  372. {
  373. if (GetStretchBltMode(hDestDC) != iStretchMode)
  374. {
  375. if (iStretchMode == HALFTONE)
  376. GetBrushOrgEx(hDestDC, &brushorg);
  377. oldsm = SetStretchBltMode(hDestDC, iStretchMode);
  378. if (iStretchMode == HALFTONE)
  379. SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL);
  380. }
  381. }
  382. hOldSrcBitmap = SelectObject(hSrcDC, m_hbm);
  383. hOldDestBitmap = SelectObject(hDestDC, hBitmap);
  384. if (bStretch)
  385. bRet = StretchBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, m_size.cx, m_size.cy, SRCCOPY);
  386. else
  387. bRet = BitBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, SRCCOPY);
  388. SelectObject(hDestDC, hOldDestBitmap);
  389. SelectObject(hSrcDC, hOldSrcBitmap);
  390. if (bStretch)
  391. {
  392. if (oldsm != 0)
  393. {
  394. if (oldsm == HALFTONE)
  395. GetBrushOrgEx(hDestDC, &brushorg);
  396. SetStretchBltMode(hDestDC, oldsm);
  397. if (oldsm == HALFTONE)
  398. SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL);
  399. }
  400. }
  401. if (!bRet)
  402. goto error;
  403. pbm->m_hbm = hBitmap;
  404. hBitmap = NULL;
  405. pbm->AssumeSize(size);
  406. goto cleanup;
  407. error:
  408. if (pbm != NULL)
  409. delete pbm;
  410. pbm = NULL;
  411. cleanup:
  412. if (hBitmap != NULL)
  413. DeleteObject(hBitmap);
  414. if (hSrcDC != NULL)
  415. DeleteDC(hSrcDC);
  416. if (hDestDC != NULL)
  417. DeleteDC(hDestDC);
  418. return pbm;
  419. }
  420. HDC CBitmap::BeginPaintInto(HDC hCDC)
  421. {
  422. if (m_hDCInto != NULL)
  423. {
  424. assert(0);
  425. return NULL;
  426. }
  427. m_hDCInto = CreateAppropDC(hCDC);
  428. if (m_hDCInto == NULL)
  429. return NULL;
  430. m_hOldBitmap = SelectObject(m_hDCInto, m_hbm);
  431. return m_hDCInto;
  432. }
  433. void CBitmap::EndPaintInto(HDC &hDC)
  434. {
  435. if (hDC == NULL || hDC != m_hDCInto)
  436. {
  437. assert(0);
  438. return;
  439. }
  440. SelectObject(m_hDCInto, m_hOldBitmap);
  441. DeleteDC(m_hDCInto);
  442. m_hDCInto = NULL;
  443. hDC = NULL;
  444. }
  445. void CBitmap::PopOut()
  446. {
  447. if (m_hDCInto == NULL)
  448. {
  449. assert(0);
  450. return;
  451. }
  452. SelectObject(m_hDCInto, m_hOldBitmap);
  453. }
  454. void CBitmap::PopIn()
  455. {
  456. if (m_hDCInto == NULL)
  457. {
  458. assert(0);
  459. return;
  460. }
  461. m_hOldBitmap = SelectObject(m_hDCInto, m_hbm);
  462. }
  463. BOOL CBitmap::Draw(HDC hDC, POINT origin, SIZE crop, BOOL bAll)
  464. {
  465. if (hDC == NULL || m_hbm == NULL)
  466. return FALSE;
  467. if (bAll && !m_bSizeKnown)
  468. return FALSE;
  469. if (bAll)
  470. crop = m_size;
  471. HDC hDCbm = CreateAppropDC(hDC);
  472. if (hDCbm == NULL)
  473. return FALSE;
  474. BOOL bPop = m_hDCInto != NULL;
  475. if (bPop)
  476. PopOut();
  477. HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm);
  478. BOOL bRet = BitBlt(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, SRCCOPY);
  479. SelectObject(hDCbm, hOldBitmap);
  480. DeleteDC(hDCbm);
  481. if (bPop)
  482. PopIn();
  483. return bRet;
  484. }
  485. BOOL CBitmap::Blend(HDC hDC, POINT origin, SIZE crop, BOOL bAll)
  486. {
  487. if (hDC == NULL || m_hbm == NULL)
  488. return FALSE;
  489. if (bAll && !m_bSizeKnown)
  490. return FALSE;
  491. if (bAll)
  492. crop = m_size;
  493. HDC hDCbm = CreateAppropDC(hDC);
  494. if (hDCbm == NULL)
  495. return FALSE;
  496. BOOL bPop = m_hDCInto != NULL;
  497. if (bPop)
  498. PopOut();
  499. #ifndef AC_SRC_ALPHA
  500. #define AC_SRC_ALPHA AC_SRC_NO_PREMULT_ALPHA
  501. #endif
  502. HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm);
  503. BOOL bRet;
  504. //@@BEGIN_MSINTERNAL
  505. /* if (!g_AlphaBlend) // If AlphaBlend is not available, use BitBlt instead.
  506. {
  507. bRet = BitBlt(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, SRCPAINT);
  508. }
  509. else
  510. {
  511. BLENDFUNCTION blendfn = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
  512. bRet = g_AlphaBlend(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, m_size.cx, m_size.cy, blendfn);
  513. }*/
  514. //@@END_MSINTERNAL
  515. bRet = DI_AlphaBlend(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, m_size.cx, m_size.cy);
  516. SelectObject(hDCbm, hOldBitmap);
  517. DeleteDC(hDCbm);
  518. if (bPop)
  519. PopIn();
  520. return bRet;
  521. }
  522. CBitmap *CBitmap::Dup()
  523. {
  524. SIZE t;
  525. if (!GetSize(&t))
  526. return NULL;
  527. return CreateResizedTo(t, NULL, COLORONCOLOR, FALSE);
  528. }
  529. CBitmap *CBitmap::Create(SIZE size, HDC hCDC)
  530. {
  531. CBitmap *pbm = new CBitmap;
  532. if (pbm == NULL)
  533. return NULL;
  534. pbm->m_hbm = CreateAppropBitmap(hCDC, size.cx, size.cy);
  535. if (pbm->m_hbm == NULL)
  536. {
  537. delete pbm;
  538. return NULL;
  539. }
  540. pbm->AssumeSize(size);
  541. return pbm;
  542. }
  543. CBitmap *CBitmap::Create(SIZE size, COLORREF color, HDC hCDC)
  544. {
  545. CBitmap *pbm = Create(size, hCDC);
  546. if (pbm == NULL)
  547. return NULL;
  548. HDC hDC = pbm->BeginPaintInto();
  549. if (hDC == NULL)
  550. {
  551. delete pbm;
  552. return NULL;
  553. }
  554. HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(color), hOldBrush;
  555. if (hBrush)
  556. {
  557. hOldBrush = SelectObject(hDC, hBrush);
  558. Rectangle(hDC, -1, -1, size.cx + 1, size.cy + 1);
  559. SelectObject(hDC, hOldBrush);
  560. DeleteObject(hBrush);
  561. }
  562. pbm->EndPaintInto(hDC);
  563. return pbm;
  564. }
  565. BOOL CBitmap::Get(HDC hDC, POINT point)
  566. {
  567. if (!m_bSizeKnown)
  568. return FALSE;
  569. return Get(hDC, point, m_size);
  570. }
  571. BOOL CBitmap::Get(HDC hDC, POINT point, SIZE size)
  572. {
  573. if (m_hDCInto != NULL || hDC == NULL)
  574. return FALSE;
  575. HDC hDCInto = BeginPaintInto(hDC);
  576. if (hDCInto == NULL)
  577. return FALSE;
  578. BOOL bRet = BitBlt(hDCInto, 0, 0, size.cx, size.cy, hDC, point.x, point.y, SRCCOPY);
  579. EndPaintInto(hDCInto);
  580. return bRet;
  581. }
  582. CBitmap *CBitmap::CreateHorzGradient(const RECT &rect, COLORREF rgbLeft, COLORREF rgbRight)
  583. {
  584. SIZE size = GetRectSize(rect);
  585. COLORREF rgbMid = RGB(
  586. (int(GetRValue(rgbLeft)) + int(GetRValue(rgbRight))) / 2,
  587. (int(GetGValue(rgbLeft)) + int(GetGValue(rgbRight))) / 2,
  588. (int(GetBValue(rgbLeft)) + int(GetBValue(rgbRight))) / 2);
  589. return Create(size, rgbMid);
  590. }
  591. BOOL CBitmap::MapToDC(HDC hDCTo, HDC hDCMapFrom)
  592. {
  593. if (hDCTo == NULL || !m_bSizeKnown || m_hDCInto != NULL)
  594. return FALSE;
  595. HBITMAP hbm = CreateAppropBitmap(hDCTo, m_size.cx, m_size.cy);
  596. if (hbm == NULL)
  597. return FALSE;
  598. HDC hDCFrom = NULL;
  599. HDC hDCInto = NULL;
  600. HGDIOBJ hOld = NULL;
  601. BOOL bRet = FALSE;
  602. hDCFrom = BeginPaintInto(hDCMapFrom);
  603. if (!hDCFrom)
  604. goto cleanup;
  605. hDCInto = CreateCompatibleDC(hDCTo);
  606. if (!hDCInto)
  607. goto cleanup;
  608. hOld = SelectObject(hDCInto, (HGDIOBJ)hbm);
  609. bRet = BitBlt(hDCInto, 0, 0, m_size.cx, m_size.cy, hDCFrom, 0, 0, SRCCOPY);
  610. SelectObject(hDCInto, hOld);
  611. cleanup:
  612. if (hDCFrom)
  613. EndPaintInto(hDCFrom);
  614. if (hDCInto)
  615. DeleteDC(hDCInto);
  616. if (bRet)
  617. {
  618. if (m_hbm)
  619. DeleteObject((HGDIOBJ)m_hbm);
  620. m_hbm = hbm;
  621. hbm = NULL;
  622. }
  623. if (hbm)
  624. DeleteObject((HGDIOBJ)hbm);
  625. return bRet;
  626. }