Leaked source code of windows server 2003
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.

842 lines
23 KiB

  1. //-------------------------------------------------------------------------
  2. // TmUtils.cpp - theme manager shared utilities
  3. //-------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "TmUtils.h"
  6. #include "ThemeFile.h"
  7. #include "loader.h"
  8. //-------------------------------------------------------------------------
  9. //---------------------------------------------------------------------------
  10. //---------------------------------------------------------------------------
  11. CMemoryDC::CMemoryDC()
  12. {
  13. _hBitmap = NULL;
  14. _hdc = NULL;
  15. _hOldBitmap = NULL;
  16. }
  17. //-------------------------------------------------------------------------
  18. CMemoryDC::~CMemoryDC()
  19. {
  20. CloseDC();
  21. }
  22. //-------------------------------------------------------------------------
  23. HRESULT CMemoryDC::OpenDC(HDC hdcSource, int iWidth, int iHeight)
  24. {
  25. HRESULT hr;
  26. BOOL fDeskDC = FALSE;
  27. if (! hdcSource)
  28. {
  29. hdcSource = GetWindowDC(NULL);
  30. if (! hdcSource)
  31. {
  32. hr = MakeErrorLast();
  33. goto exit;
  34. }
  35. fDeskDC = TRUE;
  36. }
  37. _hBitmap = CreateCompatibleBitmap(hdcSource, iWidth, iHeight);
  38. if (! _hBitmap)
  39. {
  40. hr = MakeErrorLast();
  41. goto exit;
  42. }
  43. _hdc = CreateCompatibleDC(hdcSource);
  44. if (! _hdc)
  45. {
  46. hr = MakeErrorLast();
  47. goto exit;
  48. }
  49. _hOldBitmap = (HBITMAP) SelectObject(_hdc, _hBitmap);
  50. if (! _hOldBitmap)
  51. {
  52. hr = MakeErrorLast();
  53. goto exit;
  54. }
  55. hr = S_OK;
  56. exit:
  57. if (fDeskDC)
  58. ReleaseDC(NULL, hdcSource);
  59. if (FAILED(hr))
  60. CloseDC();
  61. return hr;
  62. }
  63. //-------------------------------------------------------------------------
  64. void CMemoryDC::CloseDC()
  65. {
  66. if (_hOldBitmap)
  67. {
  68. SelectObject(_hdc, _hOldBitmap);
  69. _hOldBitmap = NULL;
  70. }
  71. if (_hdc)
  72. {
  73. DeleteDC(_hdc);
  74. _hdc = NULL;
  75. }
  76. if (_hBitmap)
  77. {
  78. DeleteObject(_hBitmap);
  79. _hBitmap = NULL;
  80. }
  81. }
  82. //-------------------------------------------------------------------------
  83. //-------------------------------------------------------------------------
  84. //-------------------------------------------------------------------------
  85. CBitmapPixels::CBitmapPixels()
  86. {
  87. _hdrBitmap = NULL;
  88. _buffer = NULL;
  89. _iWidth = 0;
  90. _iHeight = 0;
  91. }
  92. //-------------------------------------------------------------------------
  93. CBitmapPixels::~CBitmapPixels()
  94. {
  95. if (_buffer)
  96. delete [] (BYTE *)_buffer;
  97. }
  98. //-------------------------------------------------------------------------
  99. BYTE* CBitmapPixels::Buffer()
  100. {
  101. return _buffer;
  102. }
  103. //-------------------------------------------------------------------------
  104. HRESULT CBitmapPixels::OpenBitmap(HDC hdc, HBITMAP bitmap, BOOL fForceRGB32,
  105. DWORD OUT **pPixels, OPTIONAL OUT int *piWidth, OPTIONAL OUT int *piHeight,
  106. OPTIONAL OUT int *piBytesPerPixel, OPTIONAL OUT int *piBytesPerRow,
  107. OPTIONAL OUT int *piPreviousBytesPerPixel, OPTIONAL UINT cbBytesBefore)
  108. {
  109. if (! pPixels)
  110. return MakeError32(E_INVALIDARG);
  111. bool fNeedRelease = false;
  112. if (! hdc)
  113. {
  114. hdc = GetWindowDC(NULL);
  115. if (! hdc)
  116. {
  117. return MakeErrorLast();
  118. }
  119. fNeedRelease = true;
  120. }
  121. BITMAP bminfo;
  122. GetObject(bitmap, sizeof(bminfo), &bminfo);
  123. _iWidth = bminfo.bmWidth;
  124. _iHeight = bminfo.bmHeight;
  125. int iBytesPerPixel;
  126. if (piPreviousBytesPerPixel != NULL)
  127. {
  128. *piPreviousBytesPerPixel = bminfo.bmBitsPixel / 8;
  129. }
  130. if ((fForceRGB32) || (bminfo.bmBitsPixel == 32))
  131. iBytesPerPixel = 4;
  132. else
  133. iBytesPerPixel = 3;
  134. int iRawBytes = _iWidth * iBytesPerPixel;
  135. int iBytesPerRow = 4*((iRawBytes+3)/4);
  136. int size = sizeof(BITMAPINFOHEADER) + _iHeight*iBytesPerRow;
  137. _buffer = new BYTE[size + cbBytesBefore + 100]; // avoid random GetDIBits() failures with 100 bytes padding (?)
  138. if (! _buffer)
  139. return MakeError32(E_OUTOFMEMORY);
  140. _hdrBitmap = (BITMAPINFOHEADER *)(_buffer + cbBytesBefore);
  141. memset(_hdrBitmap, 0, sizeof(BITMAPINFOHEADER));
  142. _hdrBitmap->biSize = sizeof(BITMAPINFOHEADER);
  143. _hdrBitmap->biWidth = _iWidth;
  144. _hdrBitmap->biHeight = _iHeight;
  145. _hdrBitmap->biPlanes = 1;
  146. _hdrBitmap->biBitCount = static_cast<WORD>(8*iBytesPerPixel);
  147. _hdrBitmap->biCompression = BI_RGB;
  148. #ifdef DEBUG
  149. int linecnt =
  150. #endif
  151. GetDIBits(hdc, bitmap, 0, _iHeight, DIBDATA(_hdrBitmap), (BITMAPINFO *)_hdrBitmap,
  152. DIB_RGB_COLORS);
  153. ATLASSERT(linecnt == _iHeight);
  154. if (fNeedRelease)
  155. ReleaseDC(NULL, hdc);
  156. *pPixels = (DWORD *)DIBDATA(_hdrBitmap);
  157. if (piWidth)
  158. *piWidth = _iWidth;
  159. if (piHeight)
  160. *piHeight = _iHeight;
  161. if (piBytesPerPixel)
  162. *piBytesPerPixel = iBytesPerPixel;
  163. if (piBytesPerRow)
  164. *piBytesPerRow = iBytesPerRow;
  165. return S_OK;
  166. }
  167. //-------------------------------------------------------------------------
  168. void CBitmapPixels::CloseBitmap(HDC hdc, HBITMAP hBitmap)
  169. {
  170. if (_hdrBitmap && _buffer)
  171. {
  172. if (hBitmap) // rewrite bitmap
  173. {
  174. bool fNeedRelease = false;
  175. if (! hdc)
  176. {
  177. hdc = GetWindowDC(NULL);
  178. fNeedRelease = true;
  179. }
  180. SetDIBits(hdc, hBitmap, 0, _iHeight, DIBDATA(_hdrBitmap), (BITMAPINFO *)_hdrBitmap,
  181. DIB_RGB_COLORS);
  182. if ((fNeedRelease) && (hdc))
  183. ReleaseDC(NULL, hdc);
  184. }
  185. delete [] (BYTE *)_buffer;
  186. _hdrBitmap = NULL;
  187. _buffer = NULL;
  188. }
  189. }
  190. //-------------------------------------------------------------------------
  191. //---------------------------------------------------------------------------
  192. //---------------------------------------------------------------------------
  193. HRESULT LoadThemeLibrary(LPCWSTR pszThemeName, HINSTANCE *phInst)
  194. {
  195. HRESULT hr = S_OK;
  196. HINSTANCE hInst = NULL;
  197. hInst = LoadLibraryEx(pszThemeName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  198. if (! hInst)
  199. {
  200. hr = MakeErrorLast();
  201. goto exit;
  202. }
  203. //---- is this version supported? ----
  204. void *pvVersion;
  205. DWORD dwVersionLength;
  206. hr = GetPtrToResource(hInst, L"PACKTHEM_VERSION", MAKEINTRESOURCE(1), &pvVersion, &dwVersionLength);
  207. if (SUCCEEDED(hr))
  208. {
  209. if (dwVersionLength != sizeof(SHORT))
  210. hr = E_FAIL;
  211. else
  212. {
  213. SHORT sVersionNum = *(SHORT *)pvVersion;
  214. if (sVersionNum != PACKTHEM_VERSION)
  215. hr = E_FAIL;
  216. }
  217. }
  218. if (FAILED(hr))
  219. {
  220. hr = MakeError32(ERROR_BAD_FORMAT);
  221. goto exit;
  222. }
  223. *phInst = hInst;
  224. exit:
  225. if (FAILED(hr))
  226. {
  227. if (hInst)
  228. FreeLibrary(hInst);
  229. }
  230. return hr;
  231. }
  232. //---------------------------------------------------------------------------
  233. LPCWSTR ThemeString(CUxThemeFile *pThemeFile, int iOffset)
  234. {
  235. LPCWSTR p = L"";
  236. if ((pThemeFile) && (pThemeFile->_pbThemeData) && (iOffset > 0))
  237. {
  238. p = (LPCWSTR) (pThemeFile->_pbThemeData + iOffset);
  239. }
  240. return p;
  241. }
  242. //---------------------------------------------------------------------------
  243. int GetLoadIdFromTheme(CUxThemeFile *pThemeFile)
  244. {
  245. int iLoadId = 0;
  246. if (pThemeFile)
  247. {
  248. THEMEHDR *hdr = (THEMEHDR *)pThemeFile->_pbThemeData;
  249. iLoadId = hdr->iLoadId;
  250. }
  251. return iLoadId;
  252. }
  253. //---------------------------------------------------------------------------
  254. HRESULT GetThemeNameId(CUxThemeFile *pThemeFile, LPWSTR pszFileNameBuff, UINT cchFileNameBuff,
  255. LPWSTR pszColorParam, UINT cchColorParam, LPWSTR pszSizeParam, UINT cchSizeParam, int *piSysMetricsOffset, LANGID *pwLangID)
  256. {
  257. HRESULT hr = S_OK;
  258. THEMEHDR *hdr = (THEMEHDR *)pThemeFile->_pbThemeData;
  259. if (piSysMetricsOffset)
  260. *piSysMetricsOffset = hdr->iSysMetricsOffset;
  261. if (pszFileNameBuff)
  262. {
  263. hr = SafeStringCchCopyW(pszFileNameBuff, cchFileNameBuff, ThemeString(pThemeFile, hdr->iDllNameOffset));
  264. }
  265. if (SUCCEEDED(hr) && pszColorParam)
  266. {
  267. hr = SafeStringCchCopyW(pszColorParam, cchColorParam, ThemeString(pThemeFile, hdr->iColorParamOffset));
  268. }
  269. if (SUCCEEDED(hr) && pszSizeParam)
  270. {
  271. hr = SafeStringCchCopyW(pszSizeParam, cchSizeParam, ThemeString(pThemeFile, hdr->iSizeParamOffset) );
  272. }
  273. if (SUCCEEDED(hr) && pwLangID)
  274. *pwLangID = (LANGID) hdr->dwLangID;
  275. return hr;
  276. }
  277. //---------------------------------------------------------------------------
  278. BOOL ThemeMatch (CUxThemeFile *pThemeFile, LPCWSTR pszThemeName, LPCWSTR pszColorName, LPCWSTR pszSizeName, LANGID wLangID)
  279. {
  280. WCHAR szThemeFileName[MAX_PATH];
  281. WCHAR szColorParam[MAX_PATH];
  282. WCHAR szSizeParam[MAX_PATH];
  283. LANGID wThemeLangID = 0;
  284. bool bLangMatch = true;
  285. HRESULT hr = GetThemeNameId(pThemeFile,
  286. szThemeFileName, ARRAYSIZE(szThemeFileName),
  287. szColorParam, ARRAYSIZE(szColorParam),
  288. szSizeParam, ARRAYSIZE(szSizeParam), NULL, &wThemeLangID);
  289. if (wLangID != 0 && ((wThemeLangID != wLangID) || (wLangID != GetUserDefaultUILanguage())))
  290. {
  291. Log(LOG_TMLOAD, L"UxTheme: Reloading theme because of language change.");
  292. Log(LOG_TMLOAD, L"UxTheme: User LangID=0x%x, current theme=0x%x, LastUserLangID=0x%x", GetUserDefaultUILanguage(), wThemeLangID, wLangID);
  293. bLangMatch = false;
  294. }
  295. if( bLangMatch )
  296. {
  297. if( SUCCEEDED(hr) )
  298. {
  299. int iCmpTheme, iCmpColor, iCmpSize;
  300. if( SUCCEEDED(SafeStringCmpIW( pszThemeName, szThemeFileName, ARRAYSIZE(szThemeFileName), &iCmpTheme )) &&
  301. SUCCEEDED(SafeStringCmpIW( pszColorName, szColorParam, ARRAYSIZE(szColorParam), &iCmpColor )) &&
  302. SUCCEEDED(SafeStringCmpIW( pszSizeName, szSizeParam, ARRAYSIZE(szSizeParam), &iCmpSize )) )
  303. {
  304. return 0 == iCmpTheme &&
  305. 0 == iCmpColor &&
  306. 0 == iCmpSize;
  307. }
  308. }
  309. }
  310. return FALSE;
  311. }
  312. //---------------------------------------------------------------------------
  313. HRESULT GetColorSchemeIndex(HINSTANCE hInst, LPCWSTR pszColor, int *piIndex)
  314. {
  315. HRESULT hr;
  316. WCHAR szColor[_MAX_PATH+1];
  317. for (int i=0; i < 1000; i++)
  318. {
  319. hr = GetResString(hInst, L"COLORNAMES", i, szColor, ARRAYSIZE(szColor));
  320. if (FAILED(hr))
  321. break;
  322. int iCmpColor;
  323. if( SUCCEEDED(SafeStringCmpIW( pszColor, szColor, ARRAYSIZE(szColor), &iCmpColor)) &&
  324. 0 == iCmpColor )
  325. {
  326. *piIndex = i;
  327. return S_OK;
  328. }
  329. }
  330. return MakeError32(ERROR_NOT_FOUND); // not found
  331. }
  332. //---------------------------------------------------------------------------
  333. HRESULT GetSizeIndex(HINSTANCE hInst, LPCWSTR pszSize, int *piIndex)
  334. {
  335. HRESULT hr;
  336. WCHAR szSize[_MAX_PATH+1];
  337. for (int i=0; i < 1000; i++)
  338. {
  339. hr = GetResString(hInst, L"SIZENAMES", i, szSize, ARRAYSIZE(szSize));
  340. if (FAILED(hr))
  341. break;
  342. int iCmpSize;
  343. if( SUCCEEDED(SafeStringCmpIW( pszSize, szSize, ARRAYSIZE(szSize), &iCmpSize)) &&
  344. 0 == iCmpSize )
  345. {
  346. *piIndex = i;
  347. return S_OK;
  348. }
  349. }
  350. return MakeError32(ERROR_NOT_FOUND); // not found
  351. }
  352. //---------------------------------------------------------------------------
  353. HRESULT FindComboData(HINSTANCE hDll, COLORSIZECOMBOS **ppCombos)
  354. {
  355. HRSRC hRsc = FindResource(hDll, L"COMBO", L"COMBODATA");
  356. if (! hRsc)
  357. return MakeErrorLast();
  358. HGLOBAL hGlobal = LoadResource(hDll, hRsc);
  359. if (! hGlobal)
  360. return MakeErrorLast();
  361. *ppCombos = (COLORSIZECOMBOS *)LockResource(hGlobal);
  362. if (! *ppCombos)
  363. return MakeErrorLast();
  364. return S_OK;
  365. }
  366. //---------------------------------------------------------------------------
  367. BOOL FormatLocalMsg(HINSTANCE hInst, int iStringNum,
  368. LPWSTR pszMessageBuff, DWORD cchMessageBuff, DWORD *pdwParams, TMERRINFO *pErrInfo)
  369. {
  370. BOOL fGotMsg = FALSE;
  371. WCHAR szBuff[_MAX_PATH+1];
  372. WCHAR *p;
  373. //----- get string from string table ----
  374. if (LoadString(hInst, iStringNum, szBuff, ARRAYSIZE(szBuff)))
  375. {
  376. //---- repl %1 or %2 with %s ----
  377. p = szBuff;
  378. while (*p)
  379. {
  380. if (*p == '%')
  381. {
  382. p++;
  383. if ((*p == '1') || (*p == '2'))
  384. *p = 's';
  385. p++;
  386. }
  387. else
  388. p++;
  389. }
  390. int len = lstrlen(szBuff);
  391. if (len)
  392. {
  393. StringCchPrintfW(pszMessageBuff, cchMessageBuff, szBuff, pErrInfo->szMsgParam1, pErrInfo->szMsgParam2);
  394. fGotMsg = TRUE;
  395. }
  396. }
  397. return fGotMsg;
  398. }
  399. //---------------------------------------------------------------------------
  400. HRESULT _FormatParseMessage(TMERRINFO *pErrInfo,
  401. OUT LPWSTR pszMessageBuff, DWORD cchMessageBuff)
  402. {
  403. LogEntry(L"_FormatParseMessage");
  404. HRESULT hr = S_OK;
  405. DWORD dwParams[] = {PtrToInt(pErrInfo->szMsgParam1), PtrToInt(pErrInfo->szMsgParam2)};
  406. DWORD dwCode = pErrInfo->dwParseErrCode;
  407. BOOL fGotMsg = FALSE;
  408. int iStringNum = SCODE_CODE(dwCode);
  409. //---- get process name (see if we are "packthem.exe" ----
  410. WCHAR szPath[MAX_PATH];
  411. if (! GetModuleFileNameW( NULL, szPath, ARRAYSIZE(szPath) ))
  412. goto exit;
  413. WCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szBase[_MAX_FNAME], szExt[_MAX_EXT];
  414. _wsplitpath(szPath, szDrive, szDir, szBase, szExt);
  415. if (lstrcmpi(szBase, L"packthem")==0) // give packthem priority
  416. {
  417. fGotMsg = FormatLocalMsg(GetModuleHandle(NULL), iStringNum,
  418. pszMessageBuff, cchMessageBuff, dwParams, pErrInfo);
  419. }
  420. if (! fGotMsg) // try normal route: uxtheme.dll
  421. {
  422. HINSTANCE hInst = LoadLibrary(L"uxtheme.dll");
  423. if (! hInst)
  424. {
  425. Log(LOG_ALWAYS, L"_FormatParseMessage: Could not load uxtheme.dll");
  426. hr = E_FAIL;
  427. goto exit;
  428. }
  429. fGotMsg = FormatLocalMsg(hInst, iStringNum,
  430. pszMessageBuff, cchMessageBuff, dwParams, pErrInfo);
  431. FreeLibrary(hInst);
  432. }
  433. if (! fGotMsg)
  434. hr = MakeErrorLast();
  435. exit:
  436. LogExit(L"_FormatParseMessage");
  437. return hr;
  438. }
  439. //---------------------------------------------------------------------------
  440. HRESULT _GetThemeParseErrorInfo(OUT PARSE_ERROR_INFO *pInfo)
  441. {
  442. LogEntry(L"_GetThemeParseErrorInfo");
  443. HRESULT hr = S_OK;
  444. if (pInfo->dwSize != sizeof(PARSE_ERROR_INFO)) // unsupported size
  445. {
  446. hr = MakeError32(E_INVALIDARG);
  447. goto exit;
  448. }
  449. TMERRINFO *pErrInfo = GetParseErrorInfo(TRUE);
  450. if (! pErrInfo)
  451. {
  452. hr = MakeError32(E_OUTOFMEMORY);
  453. goto exit;
  454. }
  455. //---- convert code into msg using param strings ----
  456. hr = _FormatParseMessage(pErrInfo, pInfo->szMsg, ARRAYSIZE(pInfo->szMsg));
  457. if (FAILED(hr))
  458. goto exit;
  459. //---- transfer the other info ----
  460. pInfo->dwParseErrCode = pErrInfo->dwParseErrCode;
  461. pInfo->iLineNum = pErrInfo->iLineNum;
  462. StringCchCopyW(pInfo->szFileName, ARRAYSIZE(pInfo->szFileName), pErrInfo->szFileName);
  463. StringCchCopyW(pInfo->szSourceLine, ARRAYSIZE(pInfo->szSourceLine), pErrInfo->szSourceLine);
  464. exit:
  465. LogExit(L"_GetThemeParseErrorInfo");
  466. return hr;
  467. }
  468. //---------------------------------------------------------------------------
  469. HRESULT _ParseThemeIniFile(LPCWSTR pszFileName,
  470. DWORD dwParseFlags, OPTIONAL THEMEENUMPROC pfnCallBack, OPTIONAL LPARAM lparam)
  471. {
  472. LogEntry(L"ParseThemeIniFile");
  473. HRESULT hr;
  474. CThemeParser *pParser = new CThemeParser;
  475. if (! pParser)
  476. {
  477. hr = MakeError32(E_OUTOFMEMORY);
  478. goto exit;
  479. }
  480. hr = pParser->ParseThemeFile(pszFileName, NULL, NULL, pfnCallBack, lparam,
  481. dwParseFlags);
  482. delete pParser;
  483. exit:
  484. LogExit(L"ParseThemeIniFile");
  485. return hr;
  486. }
  487. //---------------------------------------------------------------------------
  488. BOOL ThemeLibStartUp(BOOL fThreadAttach)
  489. {
  490. BOOL fInit = FALSE;
  491. if (fThreadAttach)
  492. {
  493. //---- nothing to do here ----
  494. }
  495. else // process
  496. {
  497. _tls_ErrorInfoIndex = TlsAlloc();
  498. if (_tls_ErrorInfoIndex == (DWORD)-1)
  499. goto exit;
  500. if (! LogStartUp())
  501. goto exit;
  502. if (! UtilsStartUp())
  503. goto exit;
  504. }
  505. fInit = TRUE;
  506. exit:
  507. return fInit;
  508. }
  509. //---------------------------------------------------------------------------
  510. BOOL ThemeLibShutDown(BOOL fThreadDetach)
  511. {
  512. if (fThreadDetach)
  513. {
  514. //---- destroy the thread-local Error Info ----
  515. TMERRINFO * ei = GetParseErrorInfo(FALSE);
  516. if (ei)
  517. {
  518. TlsSetValue(_tls_ErrorInfoIndex, NULL);
  519. delete ei;
  520. }
  521. }
  522. else // process
  523. {
  524. UtilsShutDown();
  525. LogShutDown();
  526. if (_tls_ErrorInfoIndex != (DWORD)-1)
  527. {
  528. TlsFree(_tls_ErrorInfoIndex);
  529. _tls_ErrorInfoIndex = (DWORD)-1;
  530. }
  531. }
  532. return TRUE;
  533. }
  534. //---------------------------------------------------------------------------
  535. HRESULT GetThemeSizeId(int iSysSizeId, int *piThemeSizeId)
  536. {
  537. HRESULT hr = S_OK;
  538. *piThemeSizeId = 0;
  539. switch (iSysSizeId)
  540. {
  541. case SM_CXSIZEFRAME:
  542. *piThemeSizeId = TMT_SIZINGBORDERWIDTH;
  543. break;
  544. case SM_CYSIZEFRAME:
  545. *piThemeSizeId = TMT_SIZINGBORDERWIDTH;
  546. break;
  547. case SM_CXVSCROLL:
  548. *piThemeSizeId = TMT_SCROLLBARWIDTH;
  549. break;
  550. case SM_CYHSCROLL:
  551. *piThemeSizeId = TMT_SCROLLBARHEIGHT;
  552. break;
  553. case SM_CXSIZE:
  554. *piThemeSizeId = TMT_CAPTIONBARWIDTH;
  555. break;
  556. case SM_CYSIZE:
  557. *piThemeSizeId = TMT_CAPTIONBARHEIGHT;
  558. break;
  559. case SM_CXSMSIZE:
  560. *piThemeSizeId = TMT_SMCAPTIONBARWIDTH;
  561. break;
  562. case SM_CYSMSIZE:
  563. *piThemeSizeId = TMT_SMCAPTIONBARHEIGHT;
  564. break;
  565. case SM_CXMENUSIZE:
  566. *piThemeSizeId = TMT_MENUBARWIDTH;
  567. break;
  568. case SM_CYMENUSIZE:
  569. *piThemeSizeId = TMT_MENUBARHEIGHT;
  570. break;
  571. default:
  572. hr = MakeError32(E_INVALIDARG);
  573. break;
  574. }
  575. return hr;
  576. }
  577. //---------------------------------------------------------------------------
  578. HRESULT _EnumThemeSizes(HINSTANCE hInst, LPCWSTR pszThemeName,
  579. OPTIONAL LPCWSTR pszColorScheme, DWORD dwSizeIndex, OUT THEMENAMEINFO *ptn, BOOL fCheckColorDepth)
  580. {
  581. HRESULT hr;
  582. COLORSIZECOMBOS *combos;
  583. hr = FindComboData(hInst, &combos);
  584. if (FAILED(hr))
  585. goto exit;
  586. int iMinColor, iMaxColor;
  587. iMinColor = 0;
  588. iMaxColor = combos->cColorSchemes-1;
  589. if (pszColorScheme) // translate "pszColorScheme" into a color number
  590. {
  591. int index;
  592. hr = GetColorSchemeIndex(hInst, pszColorScheme, &index);
  593. if (FAILED(hr))
  594. goto exit;
  595. //---- restrict our search to just this color ----
  596. iMinColor = index;
  597. iMaxColor = index;
  598. }
  599. int s, c;
  600. DWORD dwSizeNum;
  601. dwSizeNum = 0;
  602. BOOL gotall;
  603. gotall = FALSE;
  604. DWORD dwCurMinDepth = 0;
  605. if (fCheckColorDepth)
  606. {
  607. dwCurMinDepth = MinimumDisplayColorDepth();
  608. }
  609. for (s=0; s < combos->cSizes; s++)
  610. {
  611. BOOL fFoundOne = FALSE;
  612. for (c=iMinColor; c <= iMaxColor; c++)
  613. {
  614. if (COMBOENTRY(combos, c, s) != -1)
  615. {
  616. fFoundOne = TRUE;
  617. break;
  618. }
  619. }
  620. if (fFoundOne && (!fCheckColorDepth || CheckMinColorDepth(hInst, dwCurMinDepth, COMBOENTRY(combos, c, s))))
  621. {
  622. if (dwSizeNum++ == dwSizeIndex)
  623. {
  624. hr = GetResString(hInst, L"SIZENAMES", s, ptn->szName, ARRAYSIZE(ptn->szName));
  625. if (FAILED(hr))
  626. *ptn->szName = 0;
  627. if (! LoadString(hInst, s+RES_BASENUM_SIZEDISPLAYS, ptn->szDisplayName, ARRAYSIZE(ptn->szDisplayName)))
  628. *ptn->szDisplayName = 0;
  629. if (! LoadString(hInst, s+RES_BASENUM_SIZETOOLTIPS, ptn->szToolTip, ARRAYSIZE(ptn->szToolTip)))
  630. *ptn->szToolTip = 0;
  631. gotall = TRUE;
  632. break;
  633. }
  634. }
  635. }
  636. if ((SUCCEEDED(hr)) && (! gotall))
  637. hr = MakeError32(ERROR_NOT_FOUND);
  638. exit:
  639. return hr;
  640. }
  641. //---------------------------------------------------------------------------
  642. HRESULT _EnumThemeColors(HINSTANCE hInst, LPCWSTR pszThemeName,
  643. OPTIONAL LPCWSTR pszSizeName, DWORD dwColorIndex, OUT THEMENAMEINFO *ptn, BOOL fCheckColorDepth)
  644. {
  645. HRESULT hr;
  646. COLORSIZECOMBOS *combos;
  647. hr = FindComboData(hInst, &combos);
  648. if (FAILED(hr))
  649. goto exit;
  650. int iMinSize, iMaxSize;
  651. iMinSize = 0;
  652. iMaxSize = combos->cSizes-1;
  653. if (pszSizeName) // translate "pszSizeName" into a size number
  654. {
  655. int index;
  656. hr = GetSizeIndex(hInst, pszSizeName, &index);
  657. if (FAILED(hr))
  658. goto exit;
  659. //---- restrict our search to just this size ----
  660. iMinSize = index;
  661. iMaxSize = index;
  662. }
  663. int s, c;
  664. DWORD dwColorNum;
  665. dwColorNum = 0;
  666. BOOL gotall;
  667. gotall = FALSE;
  668. DWORD dwCurMinDepth = 0;
  669. if (fCheckColorDepth)
  670. {
  671. dwCurMinDepth = MinimumDisplayColorDepth();
  672. }
  673. for (c=0; c < combos->cColorSchemes; c++)
  674. {
  675. BOOL fFoundOne = FALSE;
  676. for (s=iMinSize; s <= iMaxSize; s++)
  677. {
  678. if (COMBOENTRY(combos, c, s) != -1)
  679. {
  680. fFoundOne = TRUE;
  681. break;
  682. }
  683. }
  684. if (fFoundOne && (!fCheckColorDepth || CheckMinColorDepth(hInst, dwCurMinDepth, COMBOENTRY(combos, c, s))))
  685. {
  686. if (dwColorNum++ == dwColorIndex)
  687. {
  688. hr = GetResString(hInst, L"COLORNAMES", c, ptn->szName, ARRAYSIZE(ptn->szName));
  689. if (FAILED(hr))
  690. *ptn->szName = 0;
  691. if (! LoadString(hInst, c+RES_BASENUM_COLORDISPLAYS, ptn->szDisplayName, ARRAYSIZE(ptn->szDisplayName)))
  692. *ptn->szDisplayName = 0;
  693. if (! LoadString(hInst, c+RES_BASENUM_COLORTOOLTIPS, ptn->szToolTip, ARRAYSIZE(ptn->szToolTip)))
  694. *ptn->szToolTip = 0;
  695. gotall = true;
  696. break;
  697. }
  698. }
  699. }
  700. if ((SUCCEEDED(hr)) && (! gotall))
  701. hr = MakeError32(ERROR_NOT_FOUND);
  702. exit:
  703. return hr;
  704. }