EnBitmap.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. #include "stdafx.h"
  2. #include "EnBitmap.h"
  3. #include <AFXPRIV.H>
  4. #ifdef _DEBUG
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #define new DEBUG_NEW
  8. #endif
  9. const int HIMETRIC_INCH = 2540;
  10. enum
  11. {
  12. FT_BMP,
  13. FT_ICO,
  14. FT_JPG,
  15. FT_GIF,
  16. FT_UNKNOWN
  17. };
  18. CEnBitmap::CEnBitmap()
  19. {
  20. }
  21. CEnBitmap::~CEnBitmap()
  22. {
  23. }
  24. BOOL CEnBitmap::LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack)
  25. {
  26. ASSERT(m_hObject == NULL); // only attach once, detach on destroy
  27. if (m_hObject != NULL)
  28. return FALSE;
  29. return Attach(LoadImageResource(uIDRes, szResourceType, hInst, crBack));
  30. }
  31. BOOL CEnBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack)
  32. {
  33. //如果原先存在就去除
  34. if (m_hObject != NULL)
  35. {
  36. DeleteObject();
  37. Detach();
  38. }
  39. return Attach(LoadImageFile(szImagePath, crBack));
  40. }
  41. HBITMAP CEnBitmap::LoadImageFile(LPCTSTR szImagePath, COLORREF crBack)
  42. {
  43. int nType = GetFileType(szImagePath);
  44. switch (nType)
  45. {
  46. // the reason for this is that i suspect it is more efficient to load
  47. // bmps this way since it avoids creating device contexts etc that the
  48. // IPicture methods requires. that method however is still valuable
  49. // since it handles other image types and transparency
  50. case FT_BMP:
  51. return (HBITMAP)::LoadImage(NULL, szImagePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  52. case FT_UNKNOWN:
  53. return NULL;
  54. default: // all the rest
  55. {
  56. USES_CONVERSION;
  57. IPicture* pPicture = NULL;
  58. HBITMAP hbm = NULL;
  59. HRESULT hr = OleLoadPicturePath(LPOLESTR(szImagePath), NULL, 0, crBack, IID_IPicture, (LPVOID *)&pPicture);
  60. if (pPicture)
  61. {
  62. hbm = ExtractBitmap(pPicture, crBack);
  63. pPicture->Release();
  64. }
  65. return hbm;
  66. }
  67. }
  68. return NULL; // can't get here
  69. }
  70. HBITMAP CEnBitmap::LoadImageResource(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack)
  71. {
  72. BYTE* pBuff = NULL;
  73. int nSize = 0;
  74. HBITMAP hbm = NULL;
  75. // first call is to get buffer size
  76. if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, 0, nSize))
  77. {
  78. if (nSize > 0)
  79. {
  80. pBuff = new BYTE[nSize];
  81. // this loads it
  82. if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, pBuff, nSize))
  83. {
  84. IPicture* pPicture = LoadFromBuffer(pBuff, nSize);
  85. if (pPicture)
  86. {
  87. hbm = ExtractBitmap(pPicture, crBack);
  88. pPicture->Release();
  89. }
  90. }
  91. delete[] pBuff;
  92. }
  93. }
  94. return hbm;
  95. }
  96. IPicture* CEnBitmap::LoadFromBuffer(BYTE* pBuff, int nSize)
  97. {
  98. bool bResult = false;
  99. HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);
  100. void* pData = GlobalLock(hGlobal);
  101. memcpy(pData, pBuff, nSize);
  102. GlobalUnlock(hGlobal);
  103. IStream* pStream = NULL;
  104. IPicture* pPicture = NULL;
  105. if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
  106. {
  107. HRESULT hr = OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&pPicture);
  108. pStream->Release();
  109. }
  110. return pPicture; // caller releases
  111. }
  112. BOOL CEnBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize)
  113. {
  114. HRSRC hResInfo;
  115. HANDLE hRes;
  116. LPSTR lpRes = NULL;
  117. int nLen = 0;
  118. bool bResult = FALSE;
  119. // Find the resource
  120. hResInfo = FindResource(hInst, lpName, lpType);
  121. if (hResInfo == NULL)
  122. return false;
  123. // Load the resource
  124. hRes = LoadResource(hInst, hResInfo);
  125. if (hRes == NULL)
  126. return false;
  127. // Lock the resource
  128. lpRes = (char*)LockResource(hRes);
  129. if (lpRes != NULL)
  130. {
  131. if (pResource == NULL)
  132. {
  133. nBufSize = SizeofResource(hInst, hResInfo);
  134. bResult = true;
  135. }
  136. else
  137. {
  138. if (nBufSize >= (int)SizeofResource(hInst, hResInfo))
  139. {
  140. memcpy(pResource, lpRes, nBufSize);
  141. bResult = true;
  142. }
  143. }
  144. UnlockResource(hRes);
  145. }
  146. // Free the resource
  147. FreeResource(hRes);
  148. return bResult;
  149. }
  150. HBITMAP CEnBitmap::ExtractBitmap(IPicture* pPicture, COLORREF crBack)
  151. {
  152. ASSERT(pPicture);
  153. if (!pPicture)
  154. return NULL;
  155. CBitmap bmMem;
  156. CDC dcMem;
  157. CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
  158. if (dcMem.CreateCompatibleDC(pDC))
  159. {
  160. long hmWidth;
  161. long hmHeight;
  162. pPicture->get_Width(&hmWidth);
  163. pPicture->get_Height(&hmHeight);
  164. int nWidth = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH);
  165. int nHeight = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH);
  166. if (bmMem.CreateCompatibleBitmap(pDC, nWidth, nHeight))
  167. {
  168. CBitmap* pOldBM = dcMem.SelectObject(&bmMem);
  169. if (crBack != -1)
  170. dcMem.FillSolidRect(0, 0, nWidth, nHeight, crBack);
  171. HRESULT hr = pPicture->Render(dcMem, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL);
  172. dcMem.SelectObject(pOldBM);
  173. }
  174. }
  175. CWnd::GetDesktopWindow()->ReleaseDC(pDC);
  176. return (HBITMAP)bmMem.Detach();
  177. }
  178. int CEnBitmap::GetFileType(LPCTSTR szImagePath)
  179. {
  180. CString sPath(szImagePath);
  181. sPath.MakeUpper();
  182. if (sPath.Find(_T(".BMP")) > 0)
  183. return FT_BMP;
  184. else if (sPath.Find(_T(".ICO")) > 0)
  185. return FT_ICO;
  186. else if (sPath.Find(_T(".JPG")) > 0 || sPath.Find(_T(".JPEG")) > 0)
  187. return FT_JPG;
  188. else if (sPath.Find(_T(".GIF")) > 0)
  189. return FT_GIF;
  190. // else
  191. return FT_UNKNOWN;
  192. }
  193. /////////////////////////////////////////////////////////////////////
  194. // Converts a bitmap to a region
  195. //
  196. // BitmapToRegion : Create a region from the "non-transparent" pixels of a bitmap
  197. // Author : Jean-Edouard Lachand-Robert (http://www.geocities.com/Paris/LeftBank/1160/resume.htm), June 1998.
  198. //
  199. // hBmp : Source bitmap
  200. // cTransparentColor : Color base for the "transparent" pixels (default is black)
  201. // cTolerance : Color tolerance for the "transparent" pixels.
  202. //
  203. // A pixel is assumed to be transparent if the value of each of its 3 components (blue, green and red) is
  204. // greater or equal to the corresponding value in cTransparentColor and is lower or equal to the
  205. // corresponding value in cTransparentColor + cTolerance.
  206. //
  207. HRGN CEnBitmap::BitmapToRegion(COLORREF cTransparentColor, COLORREF cTolerance)
  208. {
  209. HBITMAP hBmp = (HBITMAP)GetSafeHandle();
  210. HRGN hRgn = NULL;
  211. if (hBmp)
  212. {
  213. // Create a memory DC inside which we will scan the bitmap content
  214. HDC hMemDC = CreateCompatibleDC(NULL);
  215. if (hMemDC)
  216. {
  217. // Get bitmap size
  218. BITMAP bm;
  219. ::GetObject(hBmp, sizeof(bm), &bm);
  220. // Create a 32 bits depth bitmap and select it into the memory DC
  221. BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
  222. sizeof(BITMAPINFOHEADER), // biSize
  223. bm.bmWidth, // biWidth;
  224. bm.bmHeight, // biHeight;
  225. 1, // biPlanes;
  226. 32, // biBitCount
  227. BI_RGB, // biCompression;
  228. 0, // biSizeImage;
  229. 0, // biXPelsPerMeter;
  230. 0, // biYPelsPerMeter;
  231. 0, // biClrUsed;
  232. 0 // biClrImportant;
  233. };
  234. VOID * pbits32;
  235. HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
  236. if (hbm32)
  237. {
  238. HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
  239. // Create a DC just to copy the bitmap into the memory DC
  240. HDC hDC = CreateCompatibleDC(hMemDC);
  241. if (hDC)
  242. {
  243. // Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
  244. BITMAP bm32;
  245. ::GetObject(hbm32, sizeof(bm32), &bm32);
  246. while (bm32.bmWidthBytes % 4)
  247. bm32.bmWidthBytes++;
  248. // Copy the bitmap into the memory DC
  249. HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
  250. BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
  251. // For better performances, we will use the ExtCreateRegion() function to create the
  252. // region. This function take a RGNDATA structure on entry. We will add rectangles by
  253. // amount of ALLOC_UNIT number in this structure.
  254. #define ALLOC_UNIT 100
  255. DWORD maxRects = ALLOC_UNIT;
  256. HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
  257. RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
  258. pData->rdh.dwSize = sizeof(RGNDATAHEADER);
  259. pData->rdh.iType = RDH_RECTANGLES;
  260. pData->rdh.nCount = pData->rdh.nRgnSize = 0;
  261. SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
  262. // Keep on hand highest and lowest values for the "transparent" pixels
  263. BYTE lr = GetRValue(cTransparentColor);
  264. BYTE lg = GetGValue(cTransparentColor);
  265. BYTE lb = GetBValue(cTransparentColor);
  266. BYTE hr = min(0xff, lr + GetRValue(cTolerance));
  267. BYTE hg = min(0xff, lg + GetGValue(cTolerance));
  268. BYTE hb = min(0xff, lb + GetBValue(cTolerance));
  269. // Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
  270. BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
  271. for (int y = 0; y < bm.bmHeight; y++)
  272. {
  273. // Scan each bitmap pixel from left to right
  274. for (int x = 0; x < bm.bmWidth; x++)
  275. {
  276. // Search for a continuous range of "non transparent pixels"
  277. int x0 = x;
  278. LONG *p = (LONG *)p32 + x;
  279. while (x < bm.bmWidth)
  280. {
  281. BYTE b = GetRValue(*p);
  282. if (b >= lr && b <= hr)
  283. {
  284. b = GetGValue(*p);
  285. if (b >= lg && b <= hg)
  286. {
  287. b = GetBValue(*p);
  288. if (b >= lb && b <= hb)
  289. // This pixel is "transparent"
  290. break;
  291. }
  292. }
  293. p++;
  294. x++;
  295. }
  296. if (x > x0)
  297. {
  298. // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
  299. if (pData->rdh.nCount >= maxRects)
  300. {
  301. GlobalUnlock(hData);
  302. maxRects += ALLOC_UNIT;
  303. hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
  304. pData = (RGNDATA *)GlobalLock(hData);
  305. }
  306. RECT *pr = (RECT *)&pData->Buffer;
  307. SetRect(&pr[pData->rdh.nCount], x0, y, x, y + 1);
  308. if (x0 < pData->rdh.rcBound.left)
  309. pData->rdh.rcBound.left = x0;
  310. if (y < pData->rdh.rcBound.top)
  311. pData->rdh.rcBound.top = y;
  312. if (x > pData->rdh.rcBound.right)
  313. pData->rdh.rcBound.right = x;
  314. if (y + 1 > pData->rdh.rcBound.bottom)
  315. pData->rdh.rcBound.bottom = y + 1;
  316. pData->rdh.nCount++;
  317. // On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
  318. // large (ie: > 4000). Therefore, we have to create the region by multiple steps.
  319. if (pData->rdh.nCount == 2000)
  320. {
  321. HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
  322. if (hRgn)
  323. {
  324. CombineRgn(hRgn, hRgn, h, RGN_OR);
  325. ::DeleteObject(h);
  326. }
  327. else
  328. hRgn = h;
  329. pData->rdh.nCount = 0;
  330. SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
  331. }
  332. }
  333. }
  334. // Go to next row (remember, the bitmap is inverted vertically)
  335. p32 -= bm32.bmWidthBytes;
  336. }
  337. // Create or extend the region with the remaining rectangles
  338. HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
  339. if (hRgn)
  340. {
  341. CombineRgn(hRgn, hRgn, h, RGN_OR);
  342. ::DeleteObject(h);
  343. }
  344. else
  345. hRgn = h;
  346. // Clean up
  347. GlobalFree(hData);
  348. SelectObject(hDC, holdBmp);
  349. DeleteDC(hDC);
  350. }
  351. ::DeleteObject(SelectObject(hMemDC, holdBmp));
  352. }
  353. DeleteDC(hMemDC);
  354. }
  355. }
  356. return hRgn;
  357. }
  358. BOOL CEnBitmap::Draw(CDC *pDC, LPRECT r)
  359. {
  360. CDC dc;
  361. dc.CreateCompatibleDC(pDC);
  362. CBitmap * bmp = dc.SelectObject(this);
  363. pDC->BitBlt(r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, 0, 0, SRCCOPY);
  364. dc.SelectObject(bmp);
  365. return TRUE;
  366. }
  367. // TransparentBlt - Copies a bitmap transparently onto the destination DC
  368. // hdcDest - Handle to destination device context
  369. // nXDest - x-coordinate of destination rectangle's upper-left corner
  370. // nYDest - y-coordinate of destination rectangle's upper-left corner
  371. // nWidth - Width of destination rectangle
  372. // nHeight - height of destination rectangle
  373. // hBitmap - Handle of the source bitmap
  374. // nXSrc - x-coordinate of source rectangle's upper-left corner
  375. // nYSrc - y-coordinate of source rectangle's upper-left corner
  376. // colorTransparent - The transparent color
  377. // hPal - Logical palette to be used with bitmap. Can be NULL
  378. /************************************************************************/
  379. /* 函数:TransparentBlt[8/23/2016 IT];
  380. /* 描述:将透明位图拷贝到目标;
  381. /* 参数:;
  382. /* [IN] :;
  383. /* [OUT] :;
  384. /* [IN/OUT] :;
  385. /* 返回:void;
  386. /* 注意:;
  387. /* 示例:;
  388. /*
  389. /* 修改:;
  390. /* 日期:;
  391. /* 内容:;
  392. /************************************************************************/
  393. void CEnBitmap::TransparentBlt(IN CDC &dc, IN CRect rc, IN UINT colorTransparent)
  394. {
  395. CDC pDC;
  396. pDC.CreateCompatibleDC(&dc);
  397. HBITMAP hOldBmp = (HBITMAP) ::SelectObject(pDC.m_hDC, m_hObject);
  398. ::TransparentBlt(dc.GetSafeHdc(), rc.left, rc.top, rc.Width(), rc.Height(), pDC.GetSafeHdc(), 0, 0, GetWidth(), GetHeight(), colorTransparent);
  399. ::SelectObject(pDC.m_hDC, hOldBmp);
  400. pDC.DeleteDC();
  401. }
  402. // DrawGreyScale - Draws a bitmap in Grey scale
  403. // pDC - Pointer to target device context
  404. // hDIB - Handle of device-independent bitmap
  405. //
  406. void CEnBitmap::DrawGreyScale(CDC *pDC)
  407. {
  408. CPalette pal;
  409. CPalette *pOldPalette = 0;
  410. HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
  411. // allocate memory for extended image information
  412. BITMAPINFO &bmInfo = *(LPBITMAPINFO) new BYTE[sizeof(BITMAPINFO) + 8];
  413. memset(&bmInfo, 0, sizeof(BITMAPINFO) + 8);
  414. bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  415. // get extended information about image (length, compression, length of color table if exist, ...)
  416. DWORD res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS);
  417. // allocate memory for image data (colors)
  418. LPBYTE pBits = new BYTE[bmInfo.bmiHeader.biSizeImage + 4];
  419. res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS);
  420. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
  421. 1 << bmInfo.bmiHeader.biBitCount;
  422. int nWidth = bmInfo.bmiHeader.biWidth;
  423. int nHeight = bmInfo.bmiHeader.biHeight;
  424. // Compute the address of the bitmap bits
  425. LPVOID lpDIBBits;
  426. if (bmInfo.bmiHeader.biBitCount > 8)
  427. lpDIBBits = (LPVOID)((LPDWORD)(pBits +
  428. bmInfo.bmiHeader.biClrUsed) +
  429. ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
  430. else
  431. lpDIBBits = (LPVOID)(pBits + nColors);
  432. // Create the palette if needed
  433. if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256)
  434. {
  435. // The device supports a palette and bitmap has color table
  436. // Allocate memory for a palette
  437. UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
  438. LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  439. pLP->palVersion = 0x300;
  440. pLP->palNumEntries = nColors;
  441. for (int i = 0; i < nColors; i++)
  442. {
  443. int nGrey = Grey(bmInfo.bmiColors[i].rgbRed, bmInfo.bmiColors[i].rgbGreen,
  444. bmInfo.bmiColors[i].rgbBlue);
  445. pLP->palPalEntry[i].peRed = nGrey;
  446. pLP->palPalEntry[i].peGreen = nGrey;
  447. pLP->palPalEntry[i].peBlue = nGrey;
  448. pLP->palPalEntry[i].peFlags = 0;
  449. }
  450. pal.CreatePalette(pLP);
  451. delete[] pLP;
  452. // Select the palette
  453. pOldPalette = pDC->SelectPalette(&pal, FALSE);
  454. pDC->RealizePalette();
  455. }
  456. else
  457. {
  458. // Modify the bitmaps pixels directly
  459. // Note : This ends up changing the DIB. If that is not acceptable then
  460. // copy the DIB and then change the copy rather than the original
  461. if (bmInfo.bmiHeader.biBitCount == 24 || bmInfo.bmiHeader.biBitCount == 32)
  462. {
  463. BYTE *dst = (BYTE*)lpDIBBits;
  464. int Size = nWidth*nHeight;
  465. while (Size--)
  466. {
  467. int nGrey = Grey(dst[2], dst[1], dst[0]);
  468. dst[0] = (BYTE)nGrey;
  469. dst[1] = (BYTE)nGrey;
  470. dst[2] = (BYTE)nGrey;
  471. dst += 4;
  472. }
  473. }
  474. else if (bmInfo.bmiHeader.biBitCount == 16)
  475. {
  476. WORD *dst = (WORD*)lpDIBBits;
  477. int Size = nWidth*nHeight;
  478. while (Size--)
  479. {
  480. BYTE b = (BYTE)((*dst)&(0x1F));
  481. BYTE g = (BYTE)(((*dst) >> 5)&(0x1F));
  482. BYTE r = (BYTE)(((*dst) >> 10)&(0x1F));
  483. int nGrey = Grey(r, g, b);
  484. *dst++ = ((WORD)(((BYTE)(nGrey) | ((WORD)((BYTE)(nGrey)) << 5)) | (((DWORD)(BYTE)(nGrey)) << 10)));
  485. }
  486. }
  487. }
  488. // Draw the image
  489. ::SetDIBitsToDevice(pDC->m_hDC, // hDC
  490. 0, // XDest
  491. 0, // YDest
  492. nWidth, // nDestWidth
  493. nHeight, // nDestHeight
  494. 0, // XSrc
  495. 0, // YSrc
  496. 0, // nStartScan
  497. nHeight, // nNumScans
  498. lpDIBBits, // lpBits
  499. &bmInfo, // lpBitsInfo
  500. DIB_RGB_COLORS); // wUsage
  501. if (pOldPalette)
  502. pDC->SelectPalette(pOldPalette, FALSE);
  503. }
  504. //
  505. // DitherBlt : Draw a bitmap dithered (3D grayed effect like disabled buttons in toolbars) into a destination DC
  506. // Author : Jean-Edouard Lachand-Robert (iamwired@geocities.com), June 1997.
  507. //
  508. // hdcDest : destination DC
  509. // nXDest : x coordinate of the upper left corner of the destination rectangle into the DC
  510. // nYDest : y coordinate of the upper left corner of the destination rectangle into the DC
  511. // nWidth : width of the destination rectangle into the DC
  512. // nHeight : height of the destination rectangle into the DC
  513. // hbm : the bitmap to draw (as a part or as a whole)
  514. // nXSrc : x coordinates of the upper left corner of the source rectangle into the bitmap
  515. // nYSrc : y coordinates of the upper left corner of the source rectangle into the bitmap
  516. //
  517. void CEnBitmap::DitherBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth,
  518. int nHeight, HBITMAP hbm, int nXSrc, int nYSrc)
  519. {
  520. ASSERT(hdcDest && hbm);
  521. ASSERT(nWidth > 0 && nHeight > 0);
  522. // Create a generic DC for all BitBlts
  523. HDC hDC = CreateCompatibleDC(hdcDest);
  524. ASSERT(hDC);
  525. if (hDC)
  526. {
  527. // Create a DC for the monochrome DIB section
  528. HDC bwDC = CreateCompatibleDC(hDC);
  529. ASSERT(bwDC);
  530. if (bwDC)
  531. {
  532. // Create the monochrome DIB section with a black and white palette
  533. struct {
  534. BITMAPINFOHEADER bmiHeader;
  535. RGBQUAD bmiColors[2];
  536. } RGBBWBITMAPINFO = {
  537. { // a BITMAPINFOHEADER
  538. sizeof(BITMAPINFOHEADER), // biSize
  539. nWidth, // biWidth;
  540. nHeight, // biHeight;
  541. 1, // biPlanes;
  542. 1, // biBitCount
  543. BI_RGB, // biCompression;
  544. 0, // biSizeImage;
  545. 0, // biXPelsPerMeter;
  546. 0, // biYPelsPerMeter;
  547. 0, // biClrUsed;
  548. 0 // biClrImportant;
  549. },
  550. {
  551. { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
  552. }
  553. };
  554. VOID *pbitsBW;
  555. HBITMAP hbmBW = CreateDIBSection(bwDC,
  556. (LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
  557. ASSERT(hbmBW);
  558. if (hbmBW)
  559. {
  560. // Attach the monochrome DIB section and the bitmap to the DCs
  561. SelectObject(bwDC, hbmBW);
  562. SelectObject(hDC, hbm);
  563. // BitBlt the bitmap into the monochrome DIB section
  564. BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
  565. // Paint the destination rectangle in gray
  566. FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
  567. nHeight), GetSysColorBrush(COLOR_3DFACE));
  568. // BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
  569. // The magic ROP comes from the Charles Petzold's book
  570. HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
  571. HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
  572. BitBlt(hdcDest, nXDest + 1, nYDest + 1, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
  573. // BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
  574. hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
  575. ::DeleteObject(SelectObject(hdcDest, hb));
  576. BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
  577. ::DeleteObject(SelectObject(hdcDest, oldBrush));
  578. }
  579. VERIFY(DeleteDC(bwDC));
  580. }
  581. VERIFY(DeleteDC(hDC));
  582. }
  583. }
  584. // CreateReservedPalette - Create a palette using the PC_RESERVED flag
  585. // Limit the colors to 236 colors
  586. // Returns - Handle to a palette object
  587. // hDIB - Handle to a device-independent bitmap
  588. //
  589. HPALETTE CEnBitmap::CreateReservedPalette(CDC *pDC)
  590. {
  591. HPALETTE hPal = NULL; // handle to a palette
  592. HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
  593. // get image properties
  594. //BITMAP bmp = { 0 };
  595. //::GetObject( hBmp, sizeof(BITMAP), &bmp );
  596. // allocate memory for extended image information
  597. BITMAPINFO &bmInfo = *(LPBITMAPINFO) new BYTE[sizeof(BITMAPINFO) + 8];
  598. memset(&bmInfo, 0, sizeof(BITMAPINFO) + 8);
  599. bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  600. // get extended information about image (length, compression, length of color table if exist, ...)
  601. DWORD res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS);
  602. // allocate memory for image data (colors)
  603. LPBYTE pBits = new BYTE[bmInfo.bmiHeader.biSizeImage + 4];
  604. res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS);
  605. int nWidth = bmInfo.bmiHeader.biWidth;
  606. int nHeight = bmInfo.bmiHeader.biHeight;
  607. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
  608. 1 << bmInfo.bmiHeader.biBitCount;
  609. if (nColors > 256)
  610. return NULL; // No Palette
  611. //allocate memory block for logical palette
  612. UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
  613. LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  614. // Initialize the palette version
  615. pLP->palVersion = 0x300;
  616. // If it is a 256 color DIB, then let's find the most used 236 colors
  617. // and make a palette out of those colors
  618. if (nColors > 236)
  619. {
  620. typedef struct _tagBESTCOLORS
  621. {
  622. DWORD dwColorCnt; //Count of how many times a color is used
  623. BOOL bDontUse; //Should we use this color?
  624. } BESTCOLORS;
  625. BESTCOLORS bc[256];
  626. BYTE dwLeastUsed[20]; // Least used color indices
  627. LPSTR lpBits; // pointer to D.I. bits of a DIB
  628. int nWidth, nHeight, nBytesPerLine, cx, cy;
  629. ::ZeroMemory(bc, 256 * sizeof(BESTCOLORS));
  630. lpBits = (LPSTR)(pBits + nColors);
  631. nWidth = bmInfo.bmiHeader.biWidth;
  632. nHeight = bmInfo.bmiHeader.biHeight;
  633. nBytesPerLine = ((((bmInfo.bmiHeader.biWidth *
  634. bmInfo.bmiHeader.biBitCount) + 31) & ~31) / 8);
  635. // Traverse through all of the bits in the bitmap and place the
  636. // color count of each color in the BESTCOLORS array
  637. for (cy = 0; cy < nHeight; cy++)
  638. for (cx = 0; cx < nWidth; cx++)
  639. bc[*(LPBYTE)(lpBits + cy*nBytesPerLine + cx)].dwColorCnt++;
  640. // Let's arbitrarily place the first few colors in the "Least Used" list.
  641. int nReject = nColors - 236;
  642. for (cx = 0; cx < nReject; cx++)
  643. {
  644. bc[cx].bDontUse = TRUE;
  645. dwLeastUsed[cx] = cx;
  646. }
  647. // Now, let's traverse through all of the colors and
  648. // sort out the least used
  649. for (cx = 0; cx < nColors; cx++)
  650. {
  651. cy = 0;
  652. while ((!(bc[cx].bDontUse)) && cy < nReject)
  653. {
  654. if (bc[cx].dwColorCnt < bc[dwLeastUsed[cy]].dwColorCnt)
  655. {
  656. bc[dwLeastUsed[cy]].bDontUse = FALSE;
  657. dwLeastUsed[cy] = cx;
  658. bc[cx].bDontUse = TRUE;
  659. }
  660. cy++;
  661. }
  662. }
  663. // We want only 236 colors, so that the 20 system colors
  664. // are left untouched
  665. pLP->palNumEntries = 236;
  666. cx = 0;
  667. for (int i = 0; i < nColors; i++)
  668. {
  669. // Should we use this color?
  670. if (!((bc[i].bDontUse)))
  671. {
  672. pLP->palPalEntry[cx].peRed = bmInfo.bmiColors[i].rgbRed;
  673. pLP->palPalEntry[cx].peGreen =
  674. bmInfo.bmiColors[i].rgbGreen;
  675. pLP->palPalEntry[cx].peBlue = bmInfo.bmiColors[i].rgbBlue;
  676. pLP->palPalEntry[cx].peFlags = PC_RESERVED;
  677. cx++;
  678. }
  679. }
  680. }
  681. else if (nColors)
  682. {
  683. // We have enough room for all the colors
  684. pLP->palNumEntries = nColors;
  685. // Copy the colors
  686. for (int i = 0; i < nColors; i++)
  687. {
  688. pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
  689. pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
  690. pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
  691. pLP->palPalEntry[i].peFlags = PC_RESERVED;
  692. }
  693. }
  694. hPal = CreatePalette(pLP);
  695. delete[] pLP;
  696. // return handle to DIB's palette
  697. return hPal;
  698. }
  699. // FadeColorToGrayScale - Draws a bitmap in color slowly turns it to grayscale
  700. // pDC - Pointer to target device context
  701. // hDIB - Handle of device-independent bitmap
  702. // xDest - x-coordinate of upper-left corner of dest. rect.
  703. // yDest - y-coordinate of upper-left corner of dest. rect.
  704. // nLoops - How many loops to fade the image into color
  705. // nDelay - Delay in milli-seconds between each loop
  706. //
  707. void CEnBitmap::FadeColorToGrayScale(CDC *pDC, int xDest, int yDest, int nLoops,
  708. int nDelay)
  709. {
  710. CPalette pal;
  711. CPalette *pOldPalette;
  712. PALETTEENTRY peAnimate[256];
  713. PALETTEENTRY peGray[256];
  714. PALETTEENTRY peOriginal[256];
  715. HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
  716. // get image properties
  717. //BITMAP bmp = { 0 };
  718. //::GetObject( hBmp, sizeof(BITMAP), &bmp );
  719. // allocate memory for extended image information
  720. BITMAPINFO &bmInfo = *(LPBITMAPINFO) new BYTE[sizeof(BITMAPINFO) + 8];
  721. memset(&bmInfo, 0, sizeof(BITMAPINFO) + 8);
  722. bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  723. // get extended information about image (length, compression, length of color table if exist, ...)
  724. DWORD res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS);
  725. // allocate memory for image data (colors)
  726. LPBYTE pBits = new BYTE[bmInfo.bmiHeader.biSizeImage + 4];
  727. res = GetDIBits(pDC->GetSafeHdc(), hBmp, 0, bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS);
  728. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
  729. 1 << bmInfo.bmiHeader.biBitCount;
  730. int nWidth = bmInfo.bmiHeader.biWidth;
  731. int nHeight = bmInfo.bmiHeader.biHeight;
  732. // Compute the address of the bitmap bits
  733. LPVOID lpDIBBits;
  734. if (bmInfo.bmiHeader.biBitCount > 8)
  735. lpDIBBits = (LPVOID)((LPDWORD)(pBits +
  736. bmInfo.bmiHeader.biClrUsed) +
  737. ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
  738. else
  739. lpDIBBits = (LPVOID)(pBits + nColors);
  740. int nReservedColors = nColors > 236 ? 236 : nColors;
  741. // Create the palette if needed
  742. if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256)
  743. {
  744. // The device supports a palette and bitmap has color table
  745. HPALETTE hPal = CreateReservedPalette(pDC);
  746. pal.Attach(hPal);
  747. // Now save the original colors and get the grayscale colors
  748. int i = 0;
  749. pal.GetPaletteEntries(0, nReservedColors, (LPPALETTEENTRY)&peOriginal);
  750. for (i = 0; i < nReservedColors; i++)
  751. {
  752. int nGray = Grey(peOriginal[i].peRed, peOriginal[i].peGreen, peOriginal[i].peBlue);
  753. peGray[i].peRed = nGray;
  754. peGray[i].peGreen = nGray;
  755. peGray[i].peBlue = nGray;
  756. }
  757. // Select the palette
  758. pOldPalette = pDC->SelectPalette(&pal, FALSE);
  759. pDC->RealizePalette();
  760. ::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
  761. nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
  762. // Now animate palette to set the image to grayscale
  763. for (i = 1; i <= nLoops; i++)
  764. {
  765. for (int j = 0; j < nColors; j++)
  766. {
  767. peAnimate[j].peRed = peOriginal[j].peRed -
  768. ((peOriginal[j].peRed - peGray[j].peRed)*i) / nLoops;
  769. peAnimate[j].peGreen = peOriginal[j].peGreen -
  770. ((peOriginal[j].peGreen - peGray[j].peGreen)*i)
  771. / nLoops;
  772. peAnimate[j].peBlue = peOriginal[j].peBlue -
  773. ((peOriginal[j].peBlue - peGray[j].peBlue)*i) / nLoops;
  774. peAnimate[j].peFlags = peOriginal[j].peFlags;
  775. }
  776. pal.AnimatePalette(0, nColors, (LPPALETTEENTRY)&peAnimate);
  777. // Delay...
  778. Sleep(nDelay);
  779. }
  780. // Select the old palette back
  781. pDC->SelectPalette(pOldPalette, FALSE);
  782. }
  783. else if ((pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256)
  784. {
  785. // Now change the image to grayscale
  786. for (int i = 1; i <= nLoops; i++)
  787. {
  788. BYTE *dst = (BYTE*)lpDIBBits;
  789. int Size = nWidth*nHeight;
  790. while (Size--)
  791. {
  792. int nGrey = Grey(dst[2], dst[1], dst[0]);
  793. dst[2] = (BYTE)dst[2] - ((dst[2] - nGrey)*i) / nLoops;
  794. dst[1] = (BYTE)dst[1] - ((dst[1] - nGrey)*i) / nLoops;
  795. dst[0] = (BYTE)dst[0] - ((dst[0] - nGrey)*i) / nLoops;
  796. dst += 4;
  797. }
  798. // Draw the image again
  799. ::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0,
  800. 0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo,
  801. DIB_RGB_COLORS);
  802. // Delay...
  803. Sleep(nDelay);
  804. }
  805. }
  806. else
  807. {
  808. ::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
  809. nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
  810. }
  811. }
  812. void CEnBitmap::AlphaDisplay(CDC *pDC, BYTE bAlpha)
  813. {
  814. CDC dc;
  815. dc.CreateCompatibleDC(pDC);
  816. CBitmap * bmp = dc.SelectObject(this);
  817. BLENDFUNCTION rBlendProps;
  818. rBlendProps.BlendOp = AC_SRC_OVER;
  819. rBlendProps.BlendFlags = 0;
  820. rBlendProps.AlphaFormat = 0;
  821. rBlendProps.SourceConstantAlpha = bAlpha;
  822. BITMAP bmInfo;
  823. ::GetObject(m_hObject, sizeof(BITMAP), &bmInfo);
  824. INT nWidth, nHeigh;
  825. nWidth = bmInfo.bmWidth;
  826. nHeigh = bmInfo.bmHeight;
  827. AlphaBlend(pDC->m_hDC, 0, 0, nWidth, nHeigh, dc.m_hDC, 0, 0,
  828. nWidth, nHeigh, rBlendProps);
  829. dc.SelectObject(bmp);
  830. }
  831. /* ExtCreateRegion replacement */
  832. HRGN CEnBitmap::CreateRegionExt(DWORD nCount, CONST RGNDATA *pRgnData)
  833. {
  834. HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
  835. const DWORD RDHDR = sizeof(RGNDATAHEADER);
  836. ASSERT(hRgn != NULL);
  837. LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
  838. for (int i = 0; i < (int)nCount; i++)
  839. {
  840. HRGN hr = CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
  841. VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR) != ERROR);
  842. if (hr)
  843. ::DeleteObject(hr);
  844. }
  845. ASSERT(hRgn != NULL);
  846. return hRgn;
  847. }
  848. ///////////////////////////////////////////////////////////////////
  849. // InflateRegion - Inflates a region by the x and y values
  850. // specified in nXInflate and nYInflate
  851. // Creates a new region that represents the inflated region
  852. // (retains the contents of the old region)
  853. // Returns NULL if unsuccessfull
  854. HRGN CEnBitmap::InflateRegion(HRGN hRgn, int nXInflate, int nYInflate)
  855. {
  856. // Local Variables
  857. LPRGNDATA lpData; // The RGNDATA structure
  858. LPRECT lpRect; // Pointer to the array of RECT structures
  859. DWORD BufSize; // The amount of memory required
  860. DWORD i; // General index variable
  861. HRGN hRgnNew; // The newly created region
  862. // Get the number of rectangles in the region
  863. BufSize = GetRegionData(hRgn, 0, NULL);
  864. if (BufSize == 0)
  865. return NULL;
  866. // Allocate memory for the RGNDATA structure
  867. lpData = (LPRGNDATA)malloc(BufSize);
  868. // Set the location of the RECT structures
  869. lpRect = (LPRECT)(lpData->Buffer);
  870. // Get the region data
  871. if (!GetRegionData(hRgn, BufSize, lpData))
  872. {
  873. free(lpData);
  874. return NULL;
  875. }
  876. // Expand (or contract) all the rectangles in the data
  877. for (i = 0; i < lpData->rdh.nCount; i++)
  878. InflateRect(&lpRect[i], nXInflate, nYInflate);
  879. // Create the new region
  880. hRgnNew = CreateRegionExt(lpData->rdh.nCount, lpData);
  881. free((void*)lpData);
  882. return hRgnNew;
  883. }
  884. BOOL CEnBitmap::StretchDraw(CDC *pDC, LPRECT r, LPRECT sr)
  885. {
  886. if (!r)
  887. return FALSE;
  888. CDC dc;
  889. dc.CreateCompatibleDC(pDC);
  890. CBitmap * bmp = dc.SelectObject(this);
  891. //pDC->SetStretchBltMode(COLORONCOLOR);
  892. pDC->SetStretchBltMode(STRETCH_HALFTONE); // 使界面拉伸后不模糊;
  893. if (!sr)
  894. pDC->StretchBlt(r->left, r->top, r->right, r->bottom, &dc, 0, 0, GetWidth(), GetHeight(), SRCCOPY);
  895. else
  896. pDC->StretchBlt(r->left, r->top, r->right - r->left, r->bottom - r->top,
  897. &dc, sr->left, sr->top, sr->right - sr->left, sr->bottom - sr->top, SRCCOPY);
  898. dc.SelectObject(bmp);
  899. return TRUE;
  900. }
  901. BOOL CEnBitmap::DrawImage(CEnBitmap &bmp, int nX, int nY, int nCol, int nRow)
  902. {
  903. nX -= 1;
  904. nY -= 1;
  905. //单个图片的长和宽;
  906. int w = GetWidth() / nCol;
  907. int h = GetHeight() / nRow;
  908. CBitmap *OldBmp;
  909. CDC memDC;
  910. CClientDC dc(0);
  911. memDC.CreateCompatibleDC(&dc);
  912. bmp.CreateCompatibleBitmap(&dc, w, h);
  913. OldBmp = memDC.SelectObject(&bmp);
  914. StretchDraw(&memDC, CRect(0, 0, w, h), CRect(GetWidth()*nX / nCol, GetHeight()*nY / nRow, GetWidth()*nX / nCol + w, GetHeight()*nY / nRow + h));
  915. memDC.SelectObject(OldBmp);
  916. return TRUE;
  917. }
  918. //BOLL GetBmp()
  919. CRect CEnBitmap::GetRect()
  920. {
  921. return CRect(0, 0, GetWidth(), GetHeight());
  922. }
  923. HBITMAP CEnBitmap::SetBitmap(HBITMAP hBitmap)
  924. {
  925. CEnBitmap *pBmp = (CEnBitmap *)CEnBitmap::FromHandle(hBitmap);
  926. HBITMAP hBmp = (HBITMAP)this->Detach();
  927. this->DeleteObject();
  928. pBmp->DrawImage(*this, 1, 1, 1, 1);
  929. return hBmp;
  930. }
  931. /************************************************************************/
  932. /* 函数:[8/23/2016 IT];
  933. /* 描述:;
  934. /* 参数:;
  935. /* [IN] :;
  936. /* [OUT] :;
  937. /* [IN/OUT] :;
  938. /* 返回:void;
  939. /* 注意:;
  940. /* 示例:;
  941. /*
  942. /* 修改:;
  943. /* 日期:;
  944. /* 内容:;
  945. /************************************************************************/
  946. BOOL CEnBitmap::ExtendDraw(IN CDC *pDC, IN CRect rc, IN int nX, IN int nY, IN BOOL bTran, IN UINT colorTransparent)
  947. {
  948. CEnBitmap bmp;
  949. if (ExtendDrawImage(bmp, rc, nX, nY))
  950. {
  951. if (bTran)
  952. bmp.TransparentBlt(*pDC, &rc, colorTransparent);
  953. else
  954. bmp.Draw(pDC, &rc);
  955. //
  956. return TRUE;
  957. }
  958. return FALSE;
  959. }
  960. /************************************************************************/
  961. /* 函数:ExtendDrawImage[8/23/2016 IT];
  962. /* 描述:;
  963. /* 参数:;
  964. /* [OUT] bmp:返回图片对象;
  965. /* [IN] rc:画图的目标区域;
  966. /* [IN] nX:分割点x坐标(原图坐标);
  967. /* [IN] nY:分割点y坐标(原图坐标);
  968. /* 返回:BOOL;
  969. /* 注意:;
  970. /* 示例:;
  971. /* (0,0)-------|----------|
  972. /* | | |
  973. /* | 左上 | 右上 |
  974. /* | | |
  975. /* ----------(x,y)-------|----x,y分割点坐标;
  976. /* | | |
  977. /* | 左下 | 右下 |
  978. /* | | |
  979. /* -----------|---------(r,b)-
  980. /*
  981. /* 修改:;
  982. /* 日期:;
  983. /* 内容:;
  984. /************************************************************************/
  985. BOOL CEnBitmap::ExtendDrawImage(OUT CEnBitmap &bmp, IN CRect rc, IN int nX, IN int nY)
  986. {
  987. CBitmap *OldBmp;
  988. CDC memDC;
  989. CClientDC cdc(0);
  990. memDC.CreateCompatibleDC(&cdc);
  991. bmp.CreateCompatibleBitmap(&cdc, rc.Width(), rc.Height());
  992. OldBmp = memDC.SelectObject(&bmp);
  993. if (nX == 0 && nY == 0)
  994. {
  995. StretchDraw(&memDC, &rc, GetRect());
  996. return TRUE;
  997. }
  998. CDC dc;
  999. dc.CreateCompatibleDC(&memDC);
  1000. CBitmap * Bmp = dc.SelectObject(this);
  1001. //dc.SetStretchBltMode(COLORONCOLOR);
  1002. if (nX > 0 && nY == 0)
  1003. {// 左右对半;
  1004. // 左边;
  1005. memDC.BitBlt(0, 0, nX, rc.Height(), &dc, 0, 0, SRCCOPY);
  1006. memDC.StretchBlt(nX, 0, rc.Width() - GetWidth(), rc.Height(), &dc, nX, 0, 1, GetHeight(), SRCCOPY);
  1007. // 右边;
  1008. memDC.BitBlt(rc.right - (GetWidth() - nX), 0, GetWidth() - nX, rc.Height(), &dc, nX, 0, SRCCOPY);
  1009. }
  1010. else if (nX == 0 && nY > 0)
  1011. {// 上下对半;
  1012. // 上边;
  1013. memDC.BitBlt(0, 0, rc.Width(), nY, &dc, 0, 0, SRCCOPY);
  1014. memDC.StretchBlt(0, nY, GetWidth(), rc.Height() - GetHeight(), &dc, 0, nY, GetWidth(), 1, SRCCOPY);
  1015. // 下边;
  1016. memDC.BitBlt(0, rc.bottom - (GetHeight() - nY), GetWidth(), GetHeight() - nY, &dc, 0, nY, SRCCOPY);
  1017. }
  1018. else if (nX > 0 && nY > 0)
  1019. {
  1020. //左上角;
  1021. memDC.StretchBlt(0, 0, nX, nY, &dc, 0, 0, nX, nY, SRCCOPY);
  1022. //上中;
  1023. memDC.StretchBlt(nX, 0, rc.Width() - GetWidth(), nY, &dc, nX, 0, 1, nY, SRCCOPY);
  1024. //右上角;
  1025. memDC.StretchBlt(rc.Width() - (GetWidth() - nX), 0, GetWidth() - nX, nY, &dc, nX, 0, GetWidth() - nX, nY, SRCCOPY);
  1026. //左中;
  1027. memDC.StretchBlt(0, nY, nX, rc.Height() - GetHeight(), &dc, 0, nY, nX, 1, SRCCOPY);
  1028. //正中;
  1029. memDC.StretchBlt(nX, nY, rc.Width() - GetWidth(), rc.Height() - GetHeight(), &dc, nX, nY, 1, 1, SRCCOPY);
  1030. //右中;
  1031. memDC.StretchBlt(rc.Width() - (GetWidth() - nX), nY, GetWidth() - nX, rc.Height() - GetHeight(), &dc, nX, nY, GetWidth() - nX, 1, SRCCOPY);
  1032. //左下角;
  1033. memDC.StretchBlt(0, rc.Height() - (GetHeight() - nY), nX, GetHeight() - nY, &dc, 0, nY, nX, GetHeight() - nY, SRCCOPY);
  1034. //下中;
  1035. memDC.StretchBlt(nX, rc.Height() - (GetHeight() - nY), rc.Width() - GetWidth(), GetHeight() - nY, &dc, nX, nY, 1, GetHeight() - nY, SRCCOPY);
  1036. //右下角;
  1037. memDC.StretchBlt(rc.Width() - (GetWidth() - nX), rc.Height() - (GetHeight() - nY), GetWidth() - nX, GetHeight() - nY, &dc, nX, nY, GetWidth() - nX, GetHeight() - nY, SRCCOPY);
  1038. }
  1039. dc.SelectObject(Bmp);
  1040. memDC.SelectObject(OldBmp);
  1041. return TRUE;
  1042. }