RenderManager.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. #include "StdAfx.h"
  2. #include "RenderManager.h"
  3. #include "ImageEx.h"
  4. CRenderManager::CRenderManager(void)
  5. {
  6. m_hResInstance = NULL;
  7. SetDefaultFont(TEXT("宋体"),12,false,false,false);
  8. }
  9. CRenderManager::~CRenderManager(void)
  10. {
  11. }
  12. //创建单例
  13. CRenderManager* CRenderManager::GetInstance()
  14. {
  15. static CRenderManager _Instance;
  16. return &_Instance;
  17. }
  18. static COLORREF PixelAlpha(COLORREF clrSrc, double src_darken, COLORREF clrDest, double dest_darken)
  19. {
  20. return RGB (GetRValue (clrSrc) * src_darken + GetRValue (clrDest) * dest_darken,
  21. GetGValue (clrSrc) * src_darken + GetGValue (clrDest) * dest_darken,
  22. GetBValue (clrSrc) * src_darken + GetBValue (clrDest) * dest_darken);
  23. }
  24. static BOOL WINAPI AlphaBitBlt(HDC hDC, int nDestX, int nDestY, int dwWidth, int dwHeight, HDC hSrcDC, \
  25. int nSrcX, int nSrcY, int wSrc, int hSrc, BLENDFUNCTION ftn)
  26. {
  27. HDC hTempDC = ::CreateCompatibleDC(hDC);
  28. if (NULL == hTempDC)
  29. return FALSE;
  30. //Creates Source DIB
  31. LPBITMAPINFO lpbiSrc = NULL;
  32. // Fill in the BITMAPINFOHEADER
  33. lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
  34. if (lpbiSrc == NULL)
  35. {
  36. ::DeleteDC(hTempDC);
  37. return FALSE;
  38. }
  39. lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  40. lpbiSrc->bmiHeader.biWidth = dwWidth;
  41. lpbiSrc->bmiHeader.biHeight = dwHeight;
  42. lpbiSrc->bmiHeader.biPlanes = 1;
  43. lpbiSrc->bmiHeader.biBitCount = 32;
  44. lpbiSrc->bmiHeader.biCompression = BI_RGB;
  45. lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
  46. lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
  47. lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
  48. lpbiSrc->bmiHeader.biClrUsed = 0;
  49. lpbiSrc->bmiHeader.biClrImportant = 0;
  50. COLORREF* pSrcBits = NULL;
  51. HBITMAP hSrcDib = CreateDIBSection (
  52. hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits,
  53. NULL, NULL);
  54. if ((NULL == hSrcDib) || (NULL == pSrcBits))
  55. {
  56. delete [] lpbiSrc;
  57. ::DeleteDC(hTempDC);
  58. return FALSE;
  59. }
  60. HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib);
  61. ::StretchBlt(hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, wSrc, hSrc, SRCCOPY);
  62. ::SelectObject (hTempDC, hOldTempBmp);
  63. //Creates Destination DIB
  64. LPBITMAPINFO lpbiDest = NULL;
  65. // Fill in the BITMAPINFOHEADER
  66. lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
  67. if (lpbiDest == NULL)
  68. {
  69. delete [] lpbiSrc;
  70. ::DeleteObject(hSrcDib);
  71. ::DeleteDC(hTempDC);
  72. return FALSE;
  73. }
  74. lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  75. lpbiDest->bmiHeader.biWidth = dwWidth;
  76. lpbiDest->bmiHeader.biHeight = dwHeight;
  77. lpbiDest->bmiHeader.biPlanes = 1;
  78. lpbiDest->bmiHeader.biBitCount = 32;
  79. lpbiDest->bmiHeader.biCompression = BI_RGB;
  80. lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight;
  81. lpbiDest->bmiHeader.biXPelsPerMeter = 0;
  82. lpbiDest->bmiHeader.biYPelsPerMeter = 0;
  83. lpbiDest->bmiHeader.biClrUsed = 0;
  84. lpbiDest->bmiHeader.biClrImportant = 0;
  85. COLORREF* pDestBits = NULL;
  86. HBITMAP hDestDib = CreateDIBSection (
  87. hDC, lpbiDest, DIB_RGB_COLORS, (void **)&pDestBits,
  88. NULL, NULL);
  89. if ((NULL == hDestDib) || (NULL == pDestBits))
  90. {
  91. delete [] lpbiSrc;
  92. ::DeleteObject(hSrcDib);
  93. ::DeleteDC(hTempDC);
  94. return FALSE;
  95. }
  96. ::SelectObject (hTempDC, hDestDib);
  97. ::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDC, nDestX, nDestY, SRCCOPY);
  98. ::SelectObject (hTempDC, hOldTempBmp);
  99. double src_darken;
  100. BYTE nAlpha;
  101. for (int pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++)
  102. {
  103. nAlpha = LOBYTE(*pSrcBits >> 24);
  104. src_darken = (double) (nAlpha * ftn.SourceConstantAlpha) / 255.0 / 255.0;
  105. if( src_darken < 0.0 ) src_darken = 0.0;
  106. *pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, 1.0 - src_darken);
  107. } //for
  108. ::SelectObject (hTempDC, hDestDib);
  109. ::BitBlt (hDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
  110. ::SelectObject (hTempDC, hOldTempBmp);
  111. delete [] lpbiDest;
  112. ::DeleteObject(hDestDib);
  113. delete [] lpbiSrc;
  114. ::DeleteObject(hSrcDib);
  115. ::DeleteDC(hTempDC);
  116. return TRUE;
  117. }
  118. bool CRenderManager::GetWorkDirectory( TCHAR szWorkDirectory[], WORD wBufferCount )
  119. {
  120. //模块路径
  121. TCHAR szModulePath[MAX_PATH]=TEXT("");
  122. GetModuleFileName(AfxGetInstanceHandle(),szModulePath,CountArray(szModulePath));
  123. //分析文件
  124. for (INT i=lstrlen(szModulePath);i>=0;i--)
  125. {
  126. if (szModulePath[i]==TEXT('\\'))
  127. {
  128. szModulePath[i]=0;
  129. break;
  130. }
  131. }
  132. //设置结果
  133. ASSERT(szModulePath[0]!=0);
  134. lstrcpyn(szWorkDirectory,szModulePath,wBufferCount);
  135. return true;
  136. }
  137. //区域色块
  138. void CRenderManager::DrawColor(HDC hDC, const RECT& rc, COLORREF color)
  139. {
  140. ::SetBkColor(hDC, color);
  141. ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  142. }
  143. //渐变色块
  144. void CRenderManager::DrawGradient(HDC hDC, const RECT& rc, DWORD dwFirst, DWORD dwSecond, bool bVertical, int nSteps)
  145. {
  146. typedef BOOL (WINAPI *LPALPHABLEND)(HDC, int, int, int, int,HDC, int, int, int, int, BLENDFUNCTION);
  147. static LPALPHABLEND lpAlphaBlend = (LPALPHABLEND) ::GetProcAddress(::GetModuleHandle(_T("msimg32.dll")), "AlphaBlend");
  148. if( lpAlphaBlend == NULL ) lpAlphaBlend = AlphaBitBlt;
  149. typedef BOOL (WINAPI *PGradientFill)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
  150. static PGradientFill lpGradientFill = (PGradientFill) ::GetProcAddress(::GetModuleHandle(_T("msimg32.dll")), "GradientFill");
  151. BYTE bAlpha = (BYTE)(((dwFirst >> 24) + (dwSecond >> 24)) >> 1);
  152. if( bAlpha == 0 ) return;
  153. int cx = rc.right - rc.left;
  154. int cy = rc.bottom - rc.top;
  155. RECT rcPaint = rc;
  156. HDC hPaintDC = hDC;
  157. HBITMAP hPaintBitmap = NULL;
  158. HBITMAP hOldPaintBitmap = NULL;
  159. if( bAlpha < 255 )
  160. {
  161. rcPaint.left = rcPaint.top = 0;
  162. rcPaint.right = cx;
  163. rcPaint.bottom = cy;
  164. hPaintDC = ::CreateCompatibleDC(hDC);
  165. hPaintBitmap = ::CreateCompatibleBitmap(hDC, cx, cy);
  166. ASSERT(hPaintDC);
  167. ASSERT(hPaintBitmap);
  168. hOldPaintBitmap = (HBITMAP) ::SelectObject(hPaintDC, hPaintBitmap);
  169. }
  170. if( lpGradientFill != NULL )
  171. {
  172. TRIVERTEX triv[2] =
  173. {
  174. { rcPaint.left, rcPaint.top, GetBValue(dwFirst) << 8, GetGValue(dwFirst) << 8, GetRValue(dwFirst) << 8, 0xFF00 },
  175. { rcPaint.right, rcPaint.bottom, GetBValue(dwSecond) << 8, GetGValue(dwSecond) << 8, GetRValue(dwSecond) << 8, 0xFF00 }
  176. };
  177. GRADIENT_RECT grc = { 0, 1 };
  178. lpGradientFill(hPaintDC, triv, 2, &grc, 1, bVertical ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H);
  179. }
  180. else
  181. {
  182. // Determine how many shades
  183. int nShift = 1;
  184. if( nSteps >= 64 ) nShift = 6;
  185. else if( nSteps >= 32 ) nShift = 5;
  186. else if( nSteps >= 16 ) nShift = 4;
  187. else if( nSteps >= 8 ) nShift = 3;
  188. else if( nSteps >= 4 ) nShift = 2;
  189. int nLines = 1 << nShift;
  190. for( int i = 0; i < nLines; i++ )
  191. {
  192. // Do a little alpha blending
  193. BYTE bR = (BYTE) ((GetBValue(dwSecond) * (nLines - i) + GetBValue(dwFirst) * i) >> nShift);
  194. BYTE bG = (BYTE) ((GetGValue(dwSecond) * (nLines - i) + GetGValue(dwFirst) * i) >> nShift);
  195. BYTE bB = (BYTE) ((GetRValue(dwSecond) * (nLines - i) + GetRValue(dwFirst) * i) >> nShift);
  196. // ... then paint with the resulting color
  197. HBRUSH hBrush = ::CreateSolidBrush(RGB(bR,bG,bB));
  198. RECT r2 = rcPaint;
  199. if( bVertical )
  200. {
  201. r2.bottom = rc.bottom - ((i * (rc.bottom - rc.top)) >> nShift);
  202. r2.top = rc.bottom - (((i + 1) * (rc.bottom - rc.top)) >> nShift);
  203. if( (r2.bottom - r2.top) > 0 ) ::FillRect(hDC, &r2, hBrush);
  204. }
  205. else
  206. {
  207. r2.left = rc.right - (((i + 1) * (rc.right - rc.left)) >> nShift);
  208. r2.right = rc.right - ((i * (rc.right - rc.left)) >> nShift);
  209. if( (r2.right - r2.left) > 0 ) ::FillRect(hPaintDC, &r2, hBrush);
  210. }
  211. ::DeleteObject(hBrush);
  212. }
  213. }
  214. if( bAlpha < 255 )
  215. {
  216. BLENDFUNCTION bf = { AC_SRC_OVER, 0, bAlpha, AC_SRC_ALPHA };
  217. lpAlphaBlend(hDC, rc.left, rc.top, cx, cy, hPaintDC, 0, 0, cx, cy, bf);
  218. ::SelectObject(hPaintDC, hOldPaintBitmap);
  219. ::DeleteObject(hPaintBitmap);
  220. ::DeleteDC(hPaintDC);
  221. }
  222. }
  223. //绘制线条
  224. void CRenderManager::DrawLine(HDC hDC, const RECT& rc, int nSize, COLORREF dwPenColor,int nStyle/* = PS_SOLID*/)
  225. {
  226. ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);
  227. LOGPEN lg;
  228. lg.lopnColor = dwPenColor;
  229. lg.lopnStyle = nStyle;
  230. lg.lopnWidth.x = nSize;
  231. HPEN hPen = CreatePenIndirect(&lg);
  232. HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
  233. POINT ptTemp = { 0 };
  234. ::MoveToEx(hDC, rc.left, rc.top, &ptTemp);
  235. ::LineTo(hDC, rc.right, rc.bottom);
  236. ::SelectObject(hDC, hOldPen);
  237. ::DeleteObject(hPen);
  238. }
  239. //绘制矩形
  240. void CRenderManager::DrawRect(HDC hDC, const RECT& rc, int nSize, COLORREF dwPenColor)
  241. {
  242. ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);
  243. HPEN hPen = ::CreatePen(PS_SOLID | PS_INSIDEFRAME, nSize, dwPenColor);
  244. HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
  245. ::SelectObject(hDC, ::GetStockObject(HOLLOW_BRUSH));
  246. ::Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
  247. ::SelectObject(hDC, hOldPen);
  248. ::DeleteObject(hPen);
  249. }
  250. //圆角矩形
  251. void CRenderManager::DrawRoundRect(HDC hDC, const RECT& rc, int width, int height, int nSize, COLORREF dwPenColor)
  252. {
  253. ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);
  254. HPEN hPen = ::CreatePen(PS_SOLID | PS_INSIDEFRAME, nSize, dwPenColor);
  255. HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
  256. ::SelectObject(hDC, ::GetStockObject(HOLLOW_BRUSH));
  257. ::RoundRect(hDC, rc.left, rc.top, rc.right, rc.bottom, width, height);
  258. ::SelectObject(hDC, hOldPen);
  259. ::DeleteObject(hPen);
  260. }
  261. //文字尺寸
  262. SIZE CRenderManager::GetTextSize(HDC hDC, LPCTSTR pstrText, HFONT hFont, UINT uStyle)
  263. {
  264. SIZE size = {0,0};
  265. ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);
  266. if( pstrText == NULL ) return size;
  267. ::SetBkMode(hDC, TRANSPARENT);
  268. HFONT hOldFont = (HFONT)::SelectObject(hDC, hFont);
  269. GetTextExtentPoint32(hDC, pstrText, _tcslen(pstrText) , &size);
  270. ::SelectObject(hDC, hOldFont);
  271. return size;
  272. }
  273. void CRenderManager::SetDefaultFont( LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic )
  274. {
  275. LOGFONT lf = { 0 };
  276. ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
  277. _tcsncpy_s(lf.lfFaceName, pStrFontName, LF_FACESIZE);
  278. lf.lfCharSet = DEFAULT_CHARSET;
  279. lf.lfHeight = -nSize;
  280. if( bBold ) lf.lfWeight += FW_BOLD;
  281. if( bUnderline ) lf.lfUnderline = TRUE;
  282. if( bItalic ) lf.lfItalic = TRUE;
  283. m_hDefaultFont = ::CreateFontIndirect(&lf);
  284. if( m_hDefaultFont == NULL ) throw TEXT("创建字体失败");
  285. }
  286. //获取图片
  287. CImageEx * CRenderManager::GetImage( LPCTSTR lpszFileName,LPCTSTR lpszResType/*=NULL*/ )
  288. {
  289. map<LPCTSTR,tagImageInfo*>::iterator iter;
  290. pair<std::map<LPCTSTR, tagImageInfo *>::iterator, bool> pairInsert;
  291. tagImageInfo * pImageInfo = NULL;
  292. CImageEx * pImage=NULL;
  293. if (NULL == lpszFileName || NULL == *lpszFileName)
  294. return NULL;
  295. iter = m_ArrayImage.find(lpszFileName);
  296. if (iter != m_ArrayImage.end())
  297. {
  298. pImageInfo = iter->second;
  299. if (pImageInfo != NULL)
  300. {
  301. pImageInfo->nRef++;
  302. pImageInfo->pImage->DestroyImage();
  303. //路径加载资源
  304. if( lpszResType == NULL )
  305. {
  306. TCHAR szWorkDirectory[MAX_PATH]={0};
  307. GetWorkDirectory(szWorkDirectory,MAX_PATH);
  308. StrCat(szWorkDirectory,TEXT("\\"));
  309. StrCat(szWorkDirectory,lpszFileName);
  310. CFileFind fileFind;
  311. //判断是否exe目录下的资源
  312. if ( fileFind.FindFile(szWorkDirectory) )
  313. pImageInfo->pImage->LoadImage(szWorkDirectory);
  314. else //lpszFileName为完整路径
  315. pImageInfo->pImage->LoadImage(lpszFileName);
  316. }
  317. else
  318. {
  319. pImageInfo->pImage->LoadImage(m_hResInstance,lpszFileName,lpszResType);
  320. }
  321. return pImageInfo->pImage;
  322. }
  323. else
  324. {
  325. return NULL;
  326. }
  327. }
  328. else
  329. {
  330. pImageInfo = new tagImageInfo;
  331. pImage = new CImageEx;
  332. if (NULL == pImageInfo || NULL == pImage)
  333. {
  334. SafeDelete(pImageInfo);
  335. SafeDelete(pImage);
  336. return NULL;
  337. }
  338. pairInsert = m_ArrayImage.insert(pair<LPCTSTR, tagImageInfo *>(lpszFileName, pImageInfo));
  339. if (!pairInsert.second)
  340. {
  341. SafeDelete(pImageInfo);
  342. SafeDelete(pImage);
  343. return NULL;
  344. }
  345. bool bReturn = false;
  346. //路径加载资源
  347. if( lpszResType == NULL )
  348. {
  349. TCHAR szWorkDirectory[MAX_PATH]={0};
  350. GetWorkDirectory(szWorkDirectory,MAX_PATH);
  351. StrCat(szWorkDirectory,TEXT("\\"));
  352. StrCat(szWorkDirectory,lpszFileName);
  353. //sprintf_s(szWorkDirectory,_TRUNCATE,TEXT("\\%s"),lpszFileName);
  354. CFileFind fileFind;
  355. //判断是否exe目录下的资源
  356. if ( fileFind.FindFile(szWorkDirectory) )
  357. bReturn = pImage->LoadImage(szWorkDirectory);
  358. else //lpszFileName为完整路径
  359. bReturn = pImage->LoadImage(lpszFileName);
  360. }
  361. else
  362. {
  363. bReturn = pImage->LoadImage(m_hResInstance,lpszFileName,lpszResType);
  364. }
  365. if (!bReturn)
  366. {
  367. m_ArrayImage.erase(pairInsert.first);
  368. SafeDelete(pImageInfo);
  369. SafeDelete(pImage);
  370. return NULL;
  371. }
  372. pImageInfo->pImage = pImage;
  373. pImageInfo->nRef = 1;
  374. return pImage;
  375. }
  376. }
  377. //删除图片
  378. void CRenderManager::RemoveImage( CImageEx *&pImage )
  379. {
  380. map<LPCTSTR, tagImageInfo *>::iterator iter;
  381. tagImageInfo * pImageInfo;
  382. if (NULL == pImage) return;
  383. for (iter = m_ArrayImage.begin(); iter != m_ArrayImage.end(); iter++)
  384. {
  385. pImageInfo = iter->second;
  386. if (pImageInfo != NULL)
  387. {
  388. if (pImageInfo->pImage == pImage)
  389. {
  390. pImageInfo->nRef--;
  391. if (pImageInfo->nRef <= 0)
  392. {
  393. pImageInfo->pImage->DestroyImage();
  394. SafeDelete(pImageInfo->pImage);
  395. SafeDelete(pImageInfo);
  396. m_ArrayImage.erase(iter);
  397. }
  398. pImage = NULL;
  399. break;
  400. }
  401. }
  402. }
  403. }
  404. //删除所有
  405. void CRenderManager::ClearImage()
  406. {
  407. map<LPCTSTR, tagImageInfo *>::iterator iter;
  408. tagImageInfo * pImageInfo;
  409. for (iter = m_ArrayImage.begin(); iter != m_ArrayImage.end(); iter++)
  410. {
  411. pImageInfo = iter->second;
  412. if (pImageInfo != NULL)
  413. {
  414. if (pImageInfo->pImage != NULL)
  415. {
  416. pImageInfo->pImage->DestroyImage();
  417. SafeDelete(pImageInfo->pImage);
  418. }
  419. SafeDelete(pImageInfo);
  420. }
  421. }
  422. m_ArrayImage.clear();
  423. }
  424. void CRenderManager::AddFont( LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic )
  425. {
  426. LOGFONT lf = { 0 };
  427. ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
  428. _tcsncpy_s(lf.lfFaceName, pStrFontName, LF_FACESIZE);
  429. lf.lfCharSet = DEFAULT_CHARSET;
  430. lf.lfHeight = -nSize;
  431. if( bBold ) lf.lfWeight += FW_BOLD;
  432. if( bUnderline ) lf.lfUnderline = TRUE;
  433. if( bItalic ) lf.lfItalic = TRUE;
  434. HFONT hFont = ::CreateFontIndirect(&lf);
  435. if( hFont != NULL )
  436. m_ArrayFont.push_back(hFont);
  437. }
  438. HFONT CRenderManager::GetFont( int nIndex )
  439. {
  440. if ( nIndex>m_ArrayFont.size() ) return NULL;
  441. return m_ArrayFont.at(nIndex);
  442. }
  443. HFONT CRenderManager::GetEndFont()
  444. {
  445. return *(m_ArrayFont.end()-1);
  446. }