SkinGlobals.cpp
上传用户:weijiexitu
上传日期:2007-01-18
资源大小:54k
文件大小:11k
源码类别:

菜单

开发平台:

WINDOWS

  1. // SkinGlobals.cpp: implementation of the CSkinGlobals class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SkinGlobals.h"
  6. #include "skinbase.h"
  7. #include "skincolors.h"
  8. #ifndef NO_SKIN_INI
  9. #include "Skininifile.h"
  10. #endif
  11. #ifdef _DEBUG
  12. #undef THIm_FILE
  13. static char THIm_FILE[]=__FILE__;
  14. #define new DEBUG_NEW
  15. #endif
  16. // statics
  17. CPen CSkinGlobals::s_pen;
  18. CBrush CSkinGlobals::s_brush;
  19. CFont CSkinGlobals::s_font;
  20. //////////////////////////////////////////////////////////////////////
  21. // Construction/Destruction
  22. //////////////////////////////////////////////////////////////////////
  23. CSkinGlobals::CSkinGlobals() : m_nFontPointSize(0), m_nFontHeight(0)
  24. {
  25. }
  26. CSkinGlobals::~CSkinGlobals()
  27. {
  28. ResetFonts();
  29. ResetColors();
  30. ResetCtrls();
  31. }
  32. void CSkinGlobals::ResetFonts()
  33. {
  34. m_fontMarlett.DeleteObject();
  35. m_fontMenu.DeleteObject();
  36. m_fontTip.DeleteObject();
  37. m_fontMessage.DeleteObject();
  38. m_fontCaption.DeleteObject();
  39. }
  40. void CSkinGlobals::ResetCtrls()
  41. {
  42. // delete control bitmap info
  43. for (int nCtl = 0; nCtl < SKCB_LAST; nCtl++)
  44. {
  45. CSkinBitmap* pSkb = NULL;
  46. if (m_mapCtrlBitmaps.Lookup(nCtl, pSkb))
  47. {
  48. delete pSkb;
  49. m_mapCtrlBitmaps.RemoveKey(nCtl);
  50. }
  51. }
  52. }
  53. void CSkinGlobals::ResetColors()
  54. {
  55. CBrush* pBrush = NULL;
  56. COLORREF color = 0;
  57. POSITION pos = m_mapBrushes.GetStartPosition();
  58. while (pos)
  59. {
  60. m_mapBrushes.GetNextAssoc(pos, color, pBrush);
  61. if (pBrush)
  62. pBrush->DeleteObject();
  63. delete pBrush;
  64. }
  65. CPen* pPen = NULL;
  66. pos = m_mapPens.GetStartPosition();
  67. while (pos)
  68. {
  69. m_mapPens.GetNextAssoc(pos, color, pPen);
  70. if (pPen)
  71. pPen->DeleteObject();
  72. delete pPen;
  73. }
  74. m_mapBrushes.RemoveAll();
  75. m_mapPens.RemoveAll();
  76. m_mapColors.RemoveAll();
  77. }
  78. #ifndef NO_SKIN_INI
  79. BOOL CSkinGlobals::LoadSkin(const CSkinIniGlobalsFile* pIniFile)
  80. {
  81. if (!pIniFile)
  82. return FALSE;
  83. // font
  84. ResetFonts();
  85. CSkinFont font;
  86. pIniFile->GetGlobalFont(font);
  87. // find the first acceptable font
  88. CString sFont;
  89. int nPointSize = 0, nHeight = 0;
  90. for (int nFont = 0; nFont < font.aFonts.GetSize(); nFont++)
  91. {
  92. sFont = font.aFonts[nFont].sFaceName;
  93. if (sFont.IsEmpty())
  94. continue;
  95. if (CSkinBase::FontIsPresent(sFont))
  96. {
  97. nPointSize = font.aFonts[nFont].nPointSize;
  98. nHeight = font.aFonts[nFont].nHeight;
  99. break;
  100. }
  101. else
  102. {
  103. // if there is a font file path try adding before trying again
  104. if (!font.aFonts[nFont].sFilePath.IsEmpty())
  105. {
  106. if (AddFontResource(font.aFonts[nFont].sFilePath))
  107. {
  108. // verify
  109. if (CSkinBase::FontIsPresent(sFont))
  110. {
  111. nPointSize = font.aFonts[nFont].nPointSize;
  112. nHeight = font.aFonts[nFont].nHeight;
  113. break;
  114. }
  115. }
  116. }
  117. // else
  118. sFont.Empty();
  119. }
  120. }
  121. SetFont(sFont, nPointSize);
  122. // colors
  123. ResetColors();
  124. int nColor = COLOR_LAST;
  125. while (nColor--)
  126. {
  127. COLORREF color = pIniFile->GetColor(nColor);
  128. SetColor(nColor, color);
  129. }
  130. // controls
  131. ResetCtrls();
  132. pIniFile->GetControlBitmapInfo(m_mapCtrlBitmaps);
  133. return TRUE;
  134. }
  135. #endif
  136. void CSkinGlobals::Reset()
  137. {
  138. ResetFonts();
  139. ResetColors();
  140. ResetCtrls();
  141. }
  142. COLORREF CSkinGlobals::GetColor(int nColor)
  143. {
  144. COLORREF color = (COLORREF)-1;
  145. if (m_mapColors.Lookup(nColor, color) && color >= 0)
  146. {
  147. return color;
  148. }
  149. // else
  150. color = ::GetSysColor((nColor != COLOR_PARENTBKGND) ? nColor : COLOR_3DFACE);
  151. // else save 0 for transparency
  152. if (color == 0)
  153. color = 1;
  154. SetColor(nColor, color);
  155. return color;
  156. }
  157. CBrush* CSkinGlobals::GetColorBrush(int nColor)
  158. {
  159. COLORREF color = GetColor(nColor);
  160. if (color == ::GetSysColor(nColor))
  161. return CBrush::FromHandle(::GetSysColorBrush(nColor));
  162. // else
  163. return GetColorBrush(color);
  164. }
  165. CBrush* CSkinGlobals::GetColorBrush(COLORREF color)
  166. {
  167. CBrush* pBrush = NULL;
  168. if (m_mapBrushes.Lookup(color, pBrush) && pBrush)
  169. return pBrush;
  170. pBrush = new CBrush;
  171. if (pBrush->CreateSolidBrush(color))
  172. {
  173. m_mapBrushes[color] = pBrush;
  174. return pBrush;
  175. }
  176. return NULL;
  177. }
  178. CPen* CSkinGlobals::GetColorPen(int nColor, int nWidth)
  179. {
  180. COLORREF color = GetColor(nColor);
  181. return GetColorPen(GetColor(nColor), nWidth);
  182. }
  183. CPen* CSkinGlobals::GetColorPen(COLORREF color, int nWidth)
  184. {
  185. CPen* pPen = NULL;
  186. m_mapPens.Lookup(color, pPen);
  187. // check width matches
  188. if (pPen)
  189. {
  190. LOGPEN lp;
  191. if (pPen->GetLogPen(&lp) && (lp.lopnWidth.x == nWidth))
  192. return pPen;
  193. // else
  194. pPen->DeleteObject();
  195. delete pPen;
  196. }
  197. pPen = new CPen;
  198. if (pPen->CreatePen(PS_SOLID, nWidth, color))
  199. {
  200. m_mapPens[color] = pPen;
  201. return pPen;
  202. }
  203. return NULL;
  204. }
  205. void CSkinGlobals::SetColor(int nColor, COLORREF color)
  206. {
  207. COLORREF crPrev = (COLORREF)-1;
  208. // save 0 for transparency
  209. if (color == 0)
  210. color = 1;
  211. #ifdef _DEBUG
  212. CString sColor = GetColorName(nColor);
  213. #endif
  214. // delete any brush or pen associated with the old color
  215. if (m_mapColors.Lookup(nColor, crPrev) && crPrev >= 0 && crPrev != color)
  216. {
  217. CBrush* pBrush = NULL;
  218. if (m_mapBrushes.Lookup(color, pBrush) && pBrush)
  219. {
  220. pBrush->DeleteObject();
  221. delete pBrush;
  222. }
  223. CPen* pPen = NULL;
  224. if (m_mapPens.Lookup(color, pPen) && pPen)
  225. {
  226. pPen->DeleteObject();
  227. delete pPen;
  228. }
  229. }
  230. if (color == -1)
  231. m_mapColors.RemoveKey(nColor);
  232. else
  233. m_mapColors[nColor] = color;
  234. }
  235. CFont* CSkinGlobals::GetFont(int nFont)
  236. {
  237. switch (nFont)
  238. {
  239. case SBFONT_MARLETT:
  240. return GetMarlett();
  241. case SBFONT_TIP:
  242. return GetTipFont();
  243. case SBFONT_MENU:
  244. return GetMenuFont();
  245. case SBFONT_MESSAGE:
  246. return GetMessageFont();
  247. case SBFONT_CAPTION:
  248. return GetCaptionFont();
  249. }
  250. ASSERT (0);
  251. return NULL;
  252. }
  253. CFont* CSkinGlobals::GetMarlett()
  254. {
  255. if (!m_fontMarlett.GetSafeHandle())
  256. {
  257. VERIFY(m_fontMarlett.CreateFont(GetSystemMetrics(SM_CYMENUSIZE) - 6, 0, 0, 0,
  258. FW_THIN, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, _T("Marlett")));
  259. }
  260. return &m_fontMarlett;
  261. }
  262. CFont* CSkinGlobals::GetMenuFont()
  263. {
  264. if (!m_fontMenu.GetSafeHandle())
  265. {
  266. NONCLIENTMETRICS ncm;
  267. ZeroMemory(&ncm,sizeof(ncm));
  268. ncm.cbSize = sizeof(ncm);
  269. // Get the system font
  270. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID)&ncm, FALSE);
  271. VERIFY(CreateFont(&m_fontMenu, &ncm.lfMenuFont));
  272. }
  273. return &m_fontMenu;
  274. }
  275. CFont* CSkinGlobals::GetTipFont()
  276. {
  277. if (!m_fontTip.GetSafeHandle())
  278. {
  279. NONCLIENTMETRICS ncm;
  280. ZeroMemory(&ncm,sizeof(ncm));
  281. ncm.cbSize = sizeof(ncm);
  282. // Get the system font
  283. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID)&ncm, FALSE);
  284. VERIFY(CreateFont(&m_fontTip, &ncm.lfStatusFont));
  285. }
  286. return &m_fontTip;
  287. }
  288. CFont* CSkinGlobals::GetMessageFont()
  289. {
  290. if (!m_fontMessage.GetSafeHandle())
  291. {
  292. NONCLIENTMETRICS ncm;
  293. ZeroMemory(&ncm,sizeof(ncm));
  294. ncm.cbSize = sizeof(ncm);
  295. // Get the system font
  296. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID)&ncm, FALSE);
  297. VERIFY(CreateFont(&m_fontMessage, &ncm.lfMessageFont));
  298. }
  299. return &m_fontMessage;
  300. }
  301. CFont* CSkinGlobals::GetCaptionFont()
  302. {
  303. if (!m_fontCaption.GetSafeHandle())
  304. {
  305. NONCLIENTMETRICS ncm;
  306. ZeroMemory(&ncm,sizeof(ncm));
  307. ncm.cbSize = sizeof(ncm);
  308. // Get the system font
  309. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID)&ncm, FALSE);
  310. VERIFY(CreateFont(&m_fontCaption, &ncm.lfCaptionFont));
  311. }
  312. return &m_fontCaption;
  313. }
  314. BOOL CSkinGlobals::CreateFont(CFont* pFont, LOGFONT* pLF)
  315. {
  316. ASSERT (pFont && pLF);
  317. if (!(pFont && pLF))
  318. return FALSE;
  319. // override ANSI_CHARSET because some fonts do not show with it
  320. if (pLF->lfCharSet == ANSI_CHARSET)
  321. pLF->lfCharSet = DEFAULT_CHARSET;
  322. pLF->lfQuality = ANTIALIASED_QUALITY;
  323. pLF->lfOutPrecision = OUT_TT_PRECIS;
  324. if (!m_sFontName.IsEmpty())
  325. lstrcpy(pLF->lfFaceName, m_sFontName);
  326. if (m_nFontPointSize > 0)
  327. {
  328. HDC hDC = GetDC(NULL);
  329. pLF->lfHeight = -MulDiv(m_nFontPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  330. ReleaseDC(NULL, hDC);
  331. }
  332. else if (m_nFontHeight > 0)
  333. pLF->lfHeight = -m_nFontHeight;
  334. return pFont->CreateFont(pLF->lfHeight,0,0,0,pLF->lfWeight,FALSE, FALSE, FALSE,DEFAULT_CHARSET ,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH, pLF->lfFaceName);
  335. }
  336. BOOL CSkinGlobals::SetFont(LPCTSTR szFaceName, int nPointSize, int nHeight)
  337. {
  338. nPointSize = abs(nPointSize);
  339. if (nPointSize && (nPointSize < 6 || nPointSize > 24))
  340. return FALSE;
  341. if (m_sFontName.CompareNoCase(szFaceName) != 0 || m_nFontPointSize != nPointSize)
  342. {
  343. if (!CString(szFaceName).IsEmpty() && !CSkinBase::FontIsPresent(szFaceName))
  344. return FALSE;
  345. m_sFontName = szFaceName;
  346. m_nFontPointSize = nPointSize;
  347. m_nFontHeight = nHeight;
  348. // delete existing fonts
  349. ResetFonts();
  350. return TRUE;
  351. }
  352. return FALSE;
  353. }
  354. // static versions
  355. CBrush* CSkinGlobals::GetColorBrushSt(int nColor)
  356. {
  357. return GetColorBrushSt(::GetSysColor(nColor));
  358. }
  359. CBrush* CSkinGlobals::GetColorBrushSt(COLORREF color)
  360. {
  361. s_brush.DeleteObject();
  362. s_brush.CreateSolidBrush(color);
  363. return &s_brush;
  364. }
  365. CPen* CSkinGlobals::GetColorPenSt(int nColor, int nWidth)
  366. {
  367. return GetColorPenSt(::GetSysColor(nColor));
  368. }
  369. CPen* CSkinGlobals::GetColorPenSt(COLORREF color, int nWidth)
  370. {
  371. s_pen.DeleteObject();
  372. s_pen.CreatePen(PS_SOLID, nWidth, color);
  373. return &s_pen;
  374. }
  375. CFont* CSkinGlobals::GetFontSt(int nFont)
  376. {
  377. s_font.DeleteObject();
  378. if (nFont == SBFONT_MARLETT)
  379. {
  380. VERIFY(s_font.CreateFont(GetSystemMetrics(SM_CYMENUSIZE) - 6, 0, 0, 0,
  381. FW_THIN, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, _T("Marlett")));
  382. return &s_font;
  383. }
  384. return CFont::FromHandle((HFONT)::GetStockObject(ANSI_VAR_FONT));
  385. }
  386. COLORREF CSkinGlobals::GetColorSt(int nColor)
  387. {
  388. if (nColor == COLOR_PARENTBKGND)
  389. nColor = COLOR_3DFACE;
  390. return ::GetSysColor(nColor);
  391. }
  392. CBitmap* CSkinGlobals::GetControlBitmap(int nItem, int nState, COLORREF* pMask, int nAltItem)
  393. {
  394. ASSERT (nState == IM_HOT || nState == IM_COLD || nState == IM_DOWN || nState == IM_DISABLED);
  395. CSkinBitmap* pSkb = NULL;
  396. if ((m_mapCtrlBitmaps.Lookup(nItem, pSkb) && pSkb) ||
  397. (nAltItem != -1 && m_mapCtrlBitmaps.Lookup(nAltItem, pSkb) && pSkb))
  398. {
  399. if (pSkb->IsValid(IM_HOT))
  400. {
  401. if (pMask)
  402. *pMask = pSkb->crMask;
  403. return pSkb->Image(nState);
  404. }
  405. }
  406. // else
  407. return NULL;
  408. }
  409. BOOL CSkinGlobals::SetControlBitmap(int nItem, CBitmap bitmap[IM_LAST], COLORREF crMask)
  410. {
  411. ASSERT (bitmap[IM_HOT].GetSafeHandle());
  412. if (!bitmap[IM_HOT].GetSafeHandle())
  413. return FALSE;
  414. // delete existing bitmaps first
  415. CSkinBitmap* pSkb = NULL;
  416. if (m_mapCtrlBitmaps.Lookup(nItem, pSkb) && pSkb)
  417. {
  418. m_mapCtrlBitmaps.RemoveKey(nItem);
  419. delete pSkb;
  420. }
  421. // assign new bitmaps to item
  422. m_mapCtrlBitmaps[nItem] = new CSkinBitmap(bitmap, crMask);
  423. return TRUE;
  424. }
  425. BOOL CSkinGlobals::SetControlBitmap(int nItem, UINT uIDBitmap[IM_LAST], COLORREF crMask)
  426. {
  427. CBitmap bitmap[IM_LAST];
  428. int nBM = IM_LAST;
  429. while (nBM--)
  430. {
  431. if (uIDBitmap[nBM])
  432. bitmap[nBM].LoadBitmap(uIDBitmap[nBM]);
  433. }
  434. return SetControlBitmap(nItem, bitmap, crMask);
  435. }