Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
14 KiB

  1. #include "priv.h"
  2. #include "mbutil.h"
  3. #include "legacy.h"
  4. #include "mediahlpr.h"
  5. #include "mediautil.h"
  6. #include "mediaband.h"
  7. #include "resource.h"
  8. #include <mluisupp.h>
  9. #include "apithk.h"
  10. CMediaMRU::CMediaMRU()
  11. {
  12. _hkey = NULL;
  13. }
  14. CMediaMRU::~CMediaMRU()
  15. {
  16. if (_hkey)
  17. RegCloseKey(_hkey);
  18. }
  19. VOID CMediaMRU::Load(PTSTR pszKey)
  20. {
  21. HKEY hkey = NULL;
  22. if (ERROR_SUCCESS==RegCreateKeyEx(HKEY_CURRENT_USER, pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  23. NULL, &hkey, NULL))
  24. {
  25. _hkey = hkey;
  26. }
  27. }
  28. VOID CMediaMRU::Add(PTSTR pszData)
  29. {
  30. if (!_hkey)
  31. return;
  32. ASSERT((pszData && *pszData));
  33. TCHAR szData[INTERNET_MAX_URL_LENGTH];
  34. TCHAR szTemp[INTERNET_MAX_URL_LENGTH];
  35. for (INT i = MEDIA_MRU_LIMIT-2; i>=0; i--)
  36. {
  37. if (!Get(i, szData))
  38. {
  39. continue;
  40. }
  41. TCHAR szValue[] = TEXT("0");
  42. if (!PathUnExpandEnvStringsForUser(NULL, szData, szTemp, ARRAYSIZE(szTemp)))
  43. {
  44. StrCpyN(szTemp, szData, ARRAYSIZE(szTemp));
  45. }
  46. *szValue = TEXT('0')+(TCHAR)i+1;
  47. SHSetValue(_hkey, NULL, szValue, REG_EXPAND_SZ, szTemp, (lstrlen(szTemp)+1)*sizeof(TCHAR));
  48. }
  49. if (!PathUnExpandEnvStringsForUser(NULL, pszData, szTemp, ARRAYSIZE(szTemp)))
  50. {
  51. StrCpyN(szTemp, pszData, ARRAYSIZE(szTemp));
  52. }
  53. SHSetValue(_hkey, NULL, TEXT("0"), REG_EXPAND_SZ, szTemp, (lstrlen(szTemp)+1)*sizeof(TCHAR));
  54. }
  55. VOID CMediaMRU::Delete(INT iWhich)
  56. {
  57. if (!_hkey)
  58. return;
  59. TCHAR szData[INTERNET_MAX_URL_LENGTH];
  60. TCHAR szTemp[INTERNET_MAX_URL_LENGTH];
  61. for (INT i = iWhich; i<MEDIA_MRU_LIMIT; i++)
  62. {
  63. if (!Get(i+1, szData))
  64. {
  65. continue;
  66. }
  67. TCHAR szValue[] = TEXT("0");
  68. if (!PathUnExpandEnvStringsForUser(NULL, szData, szTemp, ARRAYSIZE(szTemp)))
  69. {
  70. StrCpyN(szTemp, szData, ARRAYSIZE(szTemp));
  71. }
  72. *szValue = TEXT('0')+(TCHAR)i;
  73. SHSetValue(_hkey, NULL, szValue, REG_EXPAND_SZ, szTemp, (lstrlen(szTemp)+1)*sizeof(TCHAR));
  74. }
  75. }
  76. BOOL CMediaMRU::Get(INT iWhich, PTSTR pszOut)
  77. {
  78. BOOL fRet = FALSE;
  79. TCHAR szValue[] = TEXT("0");
  80. DWORD dwType, cb = INTERNET_MAX_URL_LENGTH;
  81. *szValue = TEXT('0')+(TCHAR)iWhich;
  82. if (ERROR_SUCCESS==SHGetValue(_hkey, NULL, szValue, &dwType, pszOut, &cb))
  83. {
  84. fRet = TRUE;
  85. }
  86. return fRet;
  87. }
  88. CMediaWidget::CMediaWidget(HWND hwnd, int cx, int cy)
  89. {
  90. _hwnd = NULL;
  91. _hwndParent = hwnd;
  92. _cx = cx;
  93. _cy = cy;
  94. }
  95. CMediaWidget::~CMediaWidget()
  96. {
  97. DESTROY_OBJ_WITH_HANDLE(_hwnd, DestroyWindow);
  98. }
  99. CMediaWidgetButton*
  100. CMediaWidgetButton_CreateInstance(HWND hwnd, int cx, int cy, int idCommand, int idImageList, int idAlt, int idTooltip, int idTooltipAlt)
  101. {
  102. CMediaWidgetButton* pmwb = new CMediaWidgetButton(hwnd, cx, cy);
  103. if (pmwb)
  104. {
  105. HRESULT hr = pmwb->Initialize(idCommand, idTooltip, idTooltipAlt);
  106. if (SUCCEEDED(hr) && idImageList)
  107. {
  108. hr = pmwb->SetImageList(idImageList);
  109. }
  110. if (SUCCEEDED(hr) && idAlt)
  111. {
  112. hr = pmwb->SetAlternateImageList(idAlt);
  113. }
  114. if (FAILED(hr))
  115. {
  116. delete pmwb;
  117. pmwb = NULL;
  118. }
  119. }
  120. return pmwb;
  121. }
  122. CMediaWidgetButton::CMediaWidgetButton(HWND hwnd, int cx, int cy) : CMediaWidget(hwnd, cx, cy)
  123. {
  124. _himl = _himlAlt = NULL;
  125. _dwMode = MWB_NORMAL;
  126. _fImageSource = TRUE;
  127. _iCommand = _iTooltip = _iTooltipAlt = 0;
  128. }
  129. CMediaWidgetButton::~CMediaWidgetButton()
  130. {
  131. DESTROY_OBJ_WITH_HANDLE(_himl, ImageList_Destroy);
  132. DESTROY_OBJ_WITH_HANDLE(_himlAlt, ImageList_Destroy);
  133. }
  134. HRESULT CMediaWidgetButton::Initialize(int idCommand, int idTooltip, int idTooltipAlt)
  135. {
  136. HRESULT hr = E_FAIL;
  137. _hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  138. WS_TABSTOP |WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  139. TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT |
  140. CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE,
  141. 0, 0, 0, 0, _hwndParent, NULL, HINST_THISDLL, NULL);
  142. if (_hwnd)
  143. {
  144. _iCommand = idCommand;
  145. TBBUTTON tb;
  146. tb.iBitmap = 0;
  147. tb.idCommand = idCommand;
  148. tb.fsState = TBSTATE_ENABLED;
  149. tb.fsStyle = BTNS_AUTOSIZE | BTNS_BUTTON;
  150. tb.dwData = 0; //(DWORD_PTR)this;
  151. tb.iString = 0;
  152. SendMessage(_hwnd, TB_BUTTONSTRUCTSIZE, SIZEOF(TBBUTTON), 0);
  153. SendMessage(_hwnd, TB_SETMAXTEXTROWS, 0, 0L);
  154. if (idTooltip)
  155. {
  156. if (idTooltipAlt)
  157. {
  158. _iTooltip = idTooltip;
  159. _iTooltipAlt = idTooltipAlt;
  160. }
  161. else
  162. {
  163. tb.iString = (int)SendMessage(_hwnd, TB_ADDSTRING, (WPARAM)MLGetHinst(), MAKELPARAM(idTooltip, 0));
  164. }
  165. }
  166. SendMessage(_hwnd, TB_ADDBUTTONS, 1, (LPARAM)&tb);
  167. SendMessage(_hwnd, TB_SETPADDING, 0, MAKELPARAM(0, 1));
  168. ShowWindow(_hwnd, SW_SHOW);
  169. Comctl32_SetDPIScale(_hwnd);
  170. hr = S_OK;
  171. }
  172. return hr;
  173. }
  174. HRESULT CMediaWidgetButton::SetImageList(INT iResource)
  175. {
  176. HRESULT hr = E_FAIL;
  177. ASSERT(_cx && _cy);
  178. DESTROY_OBJ_WITH_HANDLE(_himl, ImageList_Destroy);
  179. _himl = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(iResource), _cx, 0, crMask,
  180. IMAGE_BITMAP, LR_CREATEDIBSECTION);
  181. if (_himl && _hwnd)
  182. {
  183. SendMessage(_hwnd, TB_SETIMAGELIST, 0, (LPARAM)_himl);
  184. SendMessage(_hwnd, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)_himl);
  185. SendMessage(_hwnd, TB_SETHOTIMAGELIST, 0, (LPARAM)_himl);
  186. hr = S_OK;
  187. }
  188. return hr;
  189. }
  190. HRESULT CMediaWidgetButton::SetAlternateImageList(INT iResource)
  191. {
  192. HRESULT hr = E_FAIL;
  193. ASSERT(_himl);
  194. ASSERT(_cx && _cy);
  195. DESTROY_OBJ_WITH_HANDLE(_himlAlt, ImageList_Destroy);
  196. _himlAlt = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(iResource), _cx, 0, crMask,
  197. IMAGE_BITMAP, LR_CREATEDIBSECTION);
  198. if (_himlAlt)
  199. {
  200. hr = S_OK;
  201. }
  202. ASSERT(_iTooltipAlt);
  203. SetImageSource(TRUE);
  204. return hr;
  205. }
  206. HRESULT CMediaWidgetButton::SetImageSource(BOOL fImageSource)
  207. {
  208. ASSERT(_himlAlt);
  209. if (_himlAlt)
  210. {
  211. _fImageSource = fImageSource;
  212. if (_hwnd)
  213. {
  214. InvalidateRect(_hwnd, NULL, FALSE);
  215. UpdateWindow(_hwnd);
  216. INT i = fImageSource ? _iTooltip : _iTooltipAlt;
  217. if (i)
  218. {
  219. // ISSUE Why are we doing this? Because on Win9x, the tooltips code isn't working
  220. // no matter how hard I pound.
  221. TCHAR szText[MAX_PATH];
  222. if (MLLoadStringW(i, szText, ARRAYSIZE(szText)))
  223. {
  224. TBBUTTONINFO tb = {0};
  225. tb.cbSize = sizeof(tb);
  226. tb.dwMask = TBIF_TEXT;
  227. tb.pszText = szText;
  228. SendMessage(_hwnd, TB_SETBUTTONINFO, _iCommand, (LPARAM)&tb);
  229. }
  230. }
  231. }
  232. }
  233. return S_OK;
  234. }
  235. HRESULT CMediaWidgetButton::SetMode(DWORD dwMode)
  236. {
  237. TBBUTTONINFO tbbi;
  238. tbbi.cbSize = SIZEOF(tbbi);
  239. tbbi.dwMask = TBIF_BYINDEX | TBIF_IMAGE;
  240. SendMessage(_hwnd, TB_GETBUTTONINFO, (WPARAM)0, (LPARAM)&tbbi);
  241. tbbi.iImage = (INT)dwMode;
  242. SendMessage(_hwnd, TB_SETBUTTONINFO, (WPARAM)0, (LPARAM)&tbbi);
  243. _dwMode = dwMode;
  244. return S_OK;
  245. }
  246. LRESULT CMediaWidgetButton::Draw(LPNMTBCUSTOMDRAW pnm)
  247. {
  248. LPNMTBCUSTOMDRAW pnmc = (LPNMTBCUSTOMDRAW)pnm;
  249. LRESULT lres;
  250. switch (pnmc->nmcd.dwDrawStage)
  251. {
  252. case CDDS_PREPAINT:
  253. lres = CDRF_NOTIFYITEMDRAW;
  254. break;
  255. case CDDS_PREERASE:
  256. lres = CDRF_NOTIFYITEMDRAW;
  257. break;
  258. case CDDS_ITEMPREPAINT:
  259. {
  260. HIMAGELIST himl = _fImageSource ? _himl : _himlAlt;
  261. INT index = MWB_NORMAL;
  262. if (SendMessage(_hwnd, TB_GETSTATE, (WPARAM)pnmc->nmcd.dwItemSpec, 0) & TBSTATE_ENABLED)
  263. {
  264. index = (pnmc->nmcd.uItemState & CDIS_SELECTED)
  265. ? MWB_PRESSED
  266. : (pnmc->nmcd.uItemState & CDIS_HOT) ? MWB_HOT : _dwMode;
  267. }
  268. else
  269. {
  270. index = MWB_DISABLED;
  271. }
  272. if (himl)
  273. {
  274. UINT uFlags = ILD_TRANSPARENT | (IsOS(OS_WHISTLERORGREATER) ? ILD_DPISCALE : 0);
  275. INT x = pnmc->nmcd.rc.left;
  276. if (g_bRunOnMemphis && IS_WINDOW_RTL_MIRRORED(_hwnd))
  277. {
  278. x++;
  279. }
  280. ImageList_Draw(himl, index, pnmc->nmcd.hdc, x, 1, uFlags);
  281. lres = CDRF_SKIPDEFAULT;
  282. break;
  283. }
  284. }
  285. default:
  286. lres = CDRF_DODEFAULT;
  287. break;
  288. }
  289. return lres;
  290. }
  291. BOOL CMediaWidgetButton::IsEnabled()
  292. {
  293. return ((BOOL)SendMessage(_hwnd, TB_GETSTATE, _iCommand, 0) & TBSTATE_ENABLED);
  294. }
  295. HRESULT CMediaWidgetButton::TranslateAccelerator(LPMSG pMsg)
  296. {
  297. return (_hwnd && SendMessage(_hwnd, TB_TRANSLATEACCELERATOR, 0, (LPARAM)pMsg)) ? S_OK : S_FALSE;
  298. }
  299. CMediaWidgetToggle::CMediaWidgetToggle(HWND hwnd, int cx, int cy) : CMediaWidgetButton(hwnd, cx, cy)
  300. {
  301. _fState = FALSE;
  302. }
  303. LRESULT CMediaWidgetToggle::Draw(LPNMTBCUSTOMDRAW pnm)
  304. {
  305. LPNMTBCUSTOMDRAW pnmc = (LPNMTBCUSTOMDRAW)pnm;
  306. LRESULT lres;
  307. switch (pnmc->nmcd.dwDrawStage)
  308. {
  309. case CDDS_PREPAINT:
  310. lres = CDRF_NOTIFYITEMDRAW;
  311. break;
  312. case CDDS_PREERASE:
  313. lres = CDRF_NOTIFYITEMDRAW;
  314. break;
  315. case CDDS_ITEMPREPAINT:
  316. {
  317. INT index = MWB_NORMAL;
  318. if (_fState)
  319. {
  320. index = MWB_PRESSED;
  321. }
  322. else if (pnmc->nmcd.uItemState & CDIS_HOT)
  323. {
  324. index = MWB_HOT;
  325. }
  326. if (_himl)
  327. {
  328. UINT uFlags = ILD_TRANSPARENT | (IsOS(OS_WHISTLERORGREATER) ? ILD_DPISCALE : 0);
  329. INT x = pnmc->nmcd.rc.left;
  330. if (g_bRunOnMemphis && IS_WINDOW_RTL_MIRRORED(_hwnd))
  331. {
  332. x++;
  333. }
  334. ImageList_Draw(_himl, index, pnmc->nmcd.hdc, x, 1, uFlags);
  335. lres = CDRF_SKIPDEFAULT;
  336. break;
  337. }
  338. }
  339. default:
  340. lres = CDRF_DODEFAULT;
  341. break;
  342. }
  343. return lres;
  344. }
  345. VOID CMediaWidgetToggle::SetState(BOOL fState)
  346. {
  347. _fState = fState;
  348. InvalidateRect(_hwnd, NULL, FALSE);
  349. UpdateWindow(_hwnd);
  350. INT i = fState ? _iTooltip : _iTooltipAlt;
  351. if (i)
  352. {
  353. TCHAR szText[MAX_PATH];
  354. if (MLLoadStringW(i, szText, ARRAYSIZE(szText)))
  355. {
  356. TBBUTTONINFO tb = {0};
  357. tb.cbSize = sizeof(tb);
  358. tb.dwMask = TBIF_TEXT;
  359. tb.pszText = szText;
  360. SendMessage(_hwnd, TB_SETBUTTONINFO, _iCommand, (LPARAM)&tb);
  361. }
  362. }
  363. }
  364. CMediaWidgetOptions::CMediaWidgetOptions(HWND hwnd, int cx, int cy) : CMediaWidgetButton(hwnd, cx, cy)
  365. {
  366. _fDepth = TRUE;
  367. }
  368. HRESULT CMediaWidgetOptions::Initialize(int idCommand, int idTooltip, int idTooltipAlt)
  369. {
  370. HRESULT hr = E_FAIL;
  371. _hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | TBSTYLE_EX_MIXEDBUTTONS | WS_EX_WINDOWEDGE, TOOLBARCLASSNAME, NULL,
  372. WS_TABSTOP| WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  373. TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_CUSTOMERASE | TBSTYLE_LIST | TBSTYLE_TRANSPARENT |
  374. CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE,
  375. 0, 0, 0, 0, _hwndParent, NULL, HINST_THISDLL, NULL);
  376. if (_hwnd)
  377. {
  378. static const TBBUTTON tbInfoBar[] =
  379. {
  380. { I_IMAGECALLBACK, FCIDM_MEDIABAND_PLAYINFO, TBSTATE_ENABLED, BTNS_SHOWTEXT | BTNS_WHOLEDROPDOWN, {0,0}, 0, 0 },
  381. };
  382. // Init the toolbar control
  383. SendMessage(_hwnd, TB_BUTTONSTRUCTSIZE, SIZEOF(TBBUTTON), 0);
  384. SendMessage(_hwnd, TB_SETMAXTEXTROWS, 1, 0L);
  385. RECT rcClient;
  386. GetClientRect(_hwndParent, &rcClient);
  387. SendMessage(_hwnd, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(10,10));
  388. SendMessage(_hwnd, TB_ADDBUTTONS, ARRAYSIZE(tbInfoBar), (LPARAM)tbInfoBar);
  389. SendMessage(_hwnd, TB_SETBITMAPSIZE, 0, MAKELONG(0, 0));
  390. // Need to disable theming on this item
  391. SetWindowTheme(_hwnd, TEXT(""), TEXT(""));
  392. ShowWindow(_hwnd, SW_SHOW);
  393. hr = S_OK;
  394. }
  395. return hr;
  396. }
  397. LRESULT CMediaWidgetOptions::Draw(LPNMTBCUSTOMDRAW pnm)
  398. {
  399. LRESULT lres = CDRF_NOTIFYITEMDRAW;
  400. switch (pnm->nmcd.dwDrawStage)
  401. {
  402. case CDDS_PREPAINT:
  403. case CDDS_PREERASE:
  404. break;
  405. case CDDS_ITEMPREPAINT:
  406. {
  407. pnm->clrText = _fDepth ? RGB(255,255,255) : RGB(0,0,0);
  408. if (_fDepth)
  409. {
  410. lres |= TBCDRF_HILITEHOTTRACK;
  411. pnm->clrHighlightHotTrack = COLOR_BKGND2;
  412. }
  413. break;
  414. }
  415. default:
  416. lres = CDRF_DODEFAULT;
  417. break;
  418. }
  419. return lres;
  420. }
  421. HRESULT CMediaWidgetSeek::Initialize(HWND hwnd)
  422. {
  423. _hwnd = hwnd;
  424. return S_OK;
  425. }
  426. HRESULT CMediaWidgetSeek::TranslateAccelerator(LPMSG pMsg)
  427. {
  428. return S_FALSE;
  429. }
  430. VOID CMediaWidgetSeek::SetState(BOOL fState)
  431. {
  432. _fState = fState;
  433. InvalidateRect(_hwnd, NULL, FALSE);
  434. UpdateWindow(_hwnd);
  435. }
  436. HRESULT CMediaWidgetVolume::Initialize(HWND hwnd)
  437. {
  438. _hwnd = hwnd;
  439. return S_OK;
  440. }
  441. HRESULT CMediaWidgetVolume::TranslateAccelerator(LPMSG pMsg)
  442. {
  443. return S_FALSE;
  444. }