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.

1004 lines
29 KiB

  1. #include "priv.h"
  2. #include "theater.h"
  3. #include "itbar.h"
  4. #include "sccls.h"
  5. #include "resource.h"
  6. #include "brand.h"
  7. #include "legacy.h"
  8. #include "mluisupp.h"
  9. #if defined(MAINWIN)
  10. #include <mainwin.h>
  11. #endif
  12. #ifndef DISABLE_FULLSCREEN
  13. #define IDT_INITIAL 1
  14. #define IDT_UNHIDE 2
  15. #define IDT_TOOLBAR 3
  16. #define IDT_BROWBAR 4
  17. #define IDT_TASKBAR 5
  18. #define IDT_DELAY 6
  19. #define IDT_HIDETOOLBAR 7
  20. #define IDT_HIDEBROWBAR 8
  21. #define IDT_HIDEFLOATER 9
  22. #define IDT_HIDEFLOATER1SEC 10
  23. #define IDT_INITIALBROWSERBAR 11
  24. #define TF_THEATER 0
  25. #define E_TOP 0
  26. #define E_LEFT 1
  27. #define E_RIGHT 2
  28. #define E_BOTTOM 3
  29. // association list. sort of like dpa, but by association key rather than by index
  30. // we need this because windows hooks are global and have no data associated with them.
  31. // on the callback, we use our thread id as the key
  32. CAssociationList CTheater::_al; // associate threadid with CTheater objects
  33. // _GetWindowRectRel: gets window's coordinates relative to _hwndBrowser
  34. BOOL CTheater::_GetWindowRectRel(HWND hWnd, LPRECT lpRect)
  35. {
  36. BOOL bResult = GetWindowRect(hWnd, lpRect);
  37. if (bResult)
  38. MapWindowPoints(HWND_DESKTOP, _hwndBrowser, (LPPOINT)lpRect, 2);
  39. return bResult;
  40. }
  41. CTheater::CTheater(HWND hwnd, HWND hwndToolbar, IUnknown* punkOwner) :
  42. _hwndBrowser(hwnd), _hwndToolbar(hwndToolbar), _cRef(1)
  43. {
  44. ASSERT(punkOwner);
  45. _punkOwner = punkOwner;
  46. _punkOwner->AddRef();
  47. _al.Add(GetCurrentThreadId(), this);
  48. _wp.length = SIZEOF(_wp);
  49. GetWindowPlacement(_hwndBrowser, &_wp);
  50. GetWindowRect(_hwndBrowser, &_rcOld);
  51. #ifndef FULL_DEBUG
  52. SetWindowZorder(_hwndBrowser, HWND_TOPMOST);
  53. #endif
  54. ShowWindow(_hwndBrowser, SW_MAXIMIZE);
  55. _Initialize();
  56. _fAutoHideBrowserBar = TRUE;
  57. }
  58. CTheater::~CTheater()
  59. {
  60. SetWindowZorder(_hwndBrowser, HWND_NOTOPMOST);
  61. SetBrowserBar(NULL, 0, 0);
  62. if (_hhook)
  63. {
  64. UnhookWindowsHookEx(_hhook);
  65. _hhook = NULL;
  66. }
  67. _al.Delete(GetCurrentThreadId());
  68. KillTimer(_hwndFloater, IDT_UNHIDE);
  69. KillTimer(_hwndFloater, IDT_DELAY);
  70. KillTimer(_hwndFloater, IDT_HIDETOOLBAR);
  71. KillTimer(_hwndFloater, IDT_HIDEBROWBAR);
  72. if (_pdbBrand) {
  73. IUnknown_SetSite(_pdbBrand, NULL);
  74. _pdbBrand->CloseDW(0);
  75. _pdbBrand->Release();
  76. }
  77. if (_hwndClose) {
  78. HIMAGELIST himl = (HIMAGELIST)SendMessage(_hwndClose, TB_SETIMAGELIST, 0, 0);
  79. ImageList_Destroy(himl);
  80. }
  81. if (_hwndFloater) {
  82. DestroyWindow(_hwndFloater);
  83. }
  84. _punkOwner->Release();
  85. }
  86. BOOL CTheater::_IsBrowserActive()
  87. {
  88. HRESULT hr = IUnknown_Exec(_punkOwner, &CGID_Explorer, SBCMDID_ISBROWSERACTIVE, 0, NULL, NULL);
  89. return (hr == S_OK);
  90. }
  91. void CTheater::_ShowTaskbar()
  92. {
  93. if (SHForceWindowZorder(_hwndTaskbar, HWND_TOPMOST))
  94. _fTaskbarShown = TRUE;
  95. }
  96. void CTheater::_HideTaskbar()
  97. {
  98. if (_IsBrowserActive())
  99. {
  100. HWND hwnd = GetForegroundWindow();
  101. if (!GetCapture() && (SHIsChildOrSelf(_hwndTaskbar, hwnd) != S_OK))
  102. {
  103. if (SetWindowZorder(_hwndTaskbar, _hwndBrowser))
  104. _fTaskbarShown = FALSE;
  105. }
  106. }
  107. }
  108. void CTheater::_ShowToolbar()
  109. {
  110. if (!_fShown)
  111. {
  112. KillTimer(_hwndFloater, IDT_HIDETOOLBAR);
  113. if (_hwndToolbar)
  114. {
  115. RECT rcParent;
  116. RECT rc;
  117. GetWindowRect(_hwndToolbar, &rc);
  118. GetClientRect(_hwndBrowser, &rcParent);
  119. IUnknown_Exec(_punkOwner, &CGID_PrivCITCommands, CITIDM_THEATER, THF_UNHIDE, NULL, NULL);
  120. SetWindowPos(_hwndToolbar, _hwndFloater, 0, 0, RECTWIDTH(rcParent), RECTHEIGHT(rc), SWP_NOACTIVATE | SWP_SHOWWINDOW);
  121. _ShowFloater();
  122. }
  123. _fShown = TRUE;
  124. }
  125. }
  126. void CTheater::_HideToolbar()
  127. {
  128. // don't start hiding if floater is still active
  129. if (!_cActiveRef)
  130. {
  131. if (_fAutoHideToolbar && (GetCapture() == NULL) && !IsChild(_hwndToolbar, GetFocus()))
  132. {
  133. _HideFloater();
  134. SetTimer(_hwndFloater, IDT_HIDETOOLBAR, 50, NULL);
  135. _cyLast = -1;
  136. _fShown = FALSE;
  137. }
  138. }
  139. }
  140. void CTheater::_ContinueHideToolbar()
  141. {
  142. while (1) {
  143. RECT rc;
  144. int cy;
  145. _GetWindowRectRel(_hwndToolbar, &rc);
  146. #ifdef MAINWIN
  147. if (MwIsMwwmAllwm(_hwndBrowser))
  148. {
  149. // Simulating
  150. rc.right = rc.right - rc.left;
  151. rc.bottom = rc.bottom - rc.top;
  152. rc.top = 0;
  153. rc.bottom = 0;
  154. }
  155. #endif
  156. cy = rc.bottom;
  157. OffsetRect(&rc, 0, -4);
  158. if (cy > 0 && cy != _cyLast) {
  159. RECT rcT;
  160. _GetWindowRectRel(_hwndToolbar, &rcT);
  161. SetWindowPos(_hwndToolbar, NULL, rcT.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  162. UpdateWindow(_hwndToolbar);
  163. Sleep(10);
  164. _cyLast = cy;
  165. } else {
  166. IUnknown_Exec(_punkOwner, &CGID_PrivCITCommands, CITIDM_THEATER, THF_HIDE, NULL, NULL);
  167. ShowWindow(_hwndToolbar, SW_HIDE);
  168. // Hide floater and restore parenthood so msgs are picked up again
  169. ShowWindow(_hwndFloater, SW_HIDE);
  170. SetParent(_hwndFloater, _hwndBrowser);
  171. break;
  172. }
  173. }
  174. }
  175. void CTheater::_ShowBrowBar()
  176. {
  177. if (!_fBrowBarShown)
  178. {
  179. RECT rc;
  180. KillTimer(_hwndFloater, IDT_HIDEBROWBAR);
  181. _GetWindowRectRel(_hwndBrowBar, &rc);
  182. rc.left = 0;
  183. rc.right = _cxBrowBarShown;
  184. SetWindowPos(_hwndBrowBar, _hwndToolbar, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOACTIVATE);
  185. _SanityCheckZorder();
  186. _fBrowBarShown = TRUE;
  187. }
  188. }
  189. void CTheater::_HideBrowBar()
  190. {
  191. // don't start hiding if something has capture
  192. if (_fBrowBarShown && _CanHideWindow(_hwndBrowBar))
  193. {
  194. SetTimer(_hwndFloater, IDT_HIDEBROWBAR, 50, NULL);
  195. _fBrowBarShown = FALSE;
  196. if (_fInitialBrowserBar)
  197. KillTimer(_hwndFloater, IDT_INITIALBROWSERBAR);
  198. }
  199. }
  200. // REARCHITECT: We should signal browser bar to suppress resizing during autohide. Current scheme
  201. // works only because browser bar doesn't resize itself upon SetWindowPos to zero width.
  202. void CTheater::_ContinueHideBrowBar()
  203. {
  204. RECT rc;
  205. POINT pt;
  206. INT cxOffset, cxEdge;
  207. if (!_GetWindowRectRel(_hwndBrowBar, &rc))
  208. return; // bail
  209. cxEdge = rc.left;
  210. if (_fInitialBrowserBar)
  211. cxOffset = -2; // slow hide
  212. else
  213. cxOffset = -6; // fast hide
  214. _fInitialBrowserBar = FALSE;
  215. while (rc.right > cxEdge)
  216. {
  217. // If mouse has moved over the bar, kill the hide
  218. GetCursorPos(&pt);
  219. MapWindowPoints(HWND_DESKTOP, _hwndBrowser, &pt, 1);
  220. if (PtInRect(&rc, pt))
  221. {
  222. _ShowBrowBar();
  223. return;
  224. }
  225. OffsetRect(&rc, cxOffset, 0);
  226. SetWindowPos(_hwndBrowBar, NULL, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOZORDER | SWP_NOACTIVATE);
  227. RedrawWindow(_hwndBrowBar, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
  228. Sleep(5);
  229. }
  230. }
  231. BOOL CTheater::_CanHideWindow(HWND hwnd)
  232. {
  233. return (!GetCapture() && !IsChild(hwnd, GetFocus()));
  234. }
  235. void CTheater::_ShowFloater()
  236. {
  237. if (!_fFloaterShown)
  238. {
  239. _fFloaterShown = TRUE;
  240. SetParent(_hwndFloater, _hwndBrowser);
  241. KillTimer(_hwndFloater, IDT_HIDEFLOATER);
  242. _SizeFloater();
  243. SetWindowPos(_hwndFloater, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
  244. InvalidateRect(_hwndFloater, NULL, TRUE);
  245. UpdateWindow(_hwndFloater);
  246. ShowWindow(_hwndFloater, SW_SHOW);
  247. if (!_fShown && _fAutoHideToolbar)
  248. _DelayHideFloater();
  249. }
  250. }
  251. void CTheater::_DelayHideFloater()
  252. {
  253. if (!_cActiveRef)
  254. {
  255. SetTimer(_hwndFloater, IDT_HIDEFLOATER1SEC, 1000, NULL);
  256. }
  257. }
  258. void CTheater::_HideFloater()
  259. {
  260. if (_fAutoHideToolbar && _fFloaterShown)
  261. {
  262. if (!_fShown)
  263. {
  264. // don't start hiding if something has capture
  265. if (_CanHideWindow(_hwndFloater))
  266. {
  267. SetTimer(_hwndFloater, IDT_HIDEFLOATER, 50, NULL);
  268. _fFloaterShown = FALSE;
  269. ASSERT(!_cActiveRef);
  270. _cActiveRef++;
  271. return;
  272. }
  273. else
  274. {
  275. _DelayHideFloater();
  276. }
  277. }
  278. else
  279. {
  280. SetParent(_hwndFloater, _hwndToolbar);
  281. _fFloaterShown = FALSE;
  282. }
  283. }
  284. }
  285. void CTheater::_ContinueHideFloater()
  286. {
  287. while (1)
  288. {
  289. RECT rc;
  290. _GetWindowRectRel(_hwndFloater, &rc);
  291. rc.left += 6;
  292. if (rc.left < rc.right)
  293. {
  294. SetWindowPos(_hwndFloater, NULL, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOZORDER | SWP_NOACTIVATE);
  295. UpdateWindow(_hwndFloater);
  296. Sleep(5);
  297. }
  298. else
  299. {
  300. ShowWindow(_hwndFloater, SW_HIDE);
  301. _cActiveRef--;
  302. break;
  303. }
  304. }
  305. }
  306. void CTheater::_Unhide(int iWhich, UINT uDelay)
  307. {
  308. _iUnhidee = iWhich;
  309. SetTimer(_hwndFloater, IDT_UNHIDE, uDelay, NULL);
  310. }
  311. BOOL CTheater::_PtNearWindow(POINT pt, HWND hwnd)
  312. {
  313. RECT rc;
  314. _GetWindowRectRel(hwnd, &rc);
  315. InflateRect(&rc, 60, 60);
  316. return (PtInRect(&rc, pt));
  317. }
  318. int GetWindowHeight(HWND hwnd)
  319. {
  320. ASSERT(hwnd);
  321. RECT rc;
  322. GetWindowRect(hwnd, &rc);
  323. return RECTHEIGHT(rc);
  324. }
  325. BOOL CTheater::_PtOnEdge(POINT pt, int iEdge)
  326. {
  327. RECT rc;
  328. _GetWindowRectRel(_hwndBrowser, &rc);
  329. switch (iEdge)
  330. {
  331. case E_LEFT:
  332. rc.right = rc.left + CX_HIT;
  333. goto leftright;
  334. case E_RIGHT:
  335. rc.left = rc.right - CX_HIT;
  336. leftright:
  337. rc.top += GetWindowHeight(_hwndToolbar);
  338. rc.bottom -= GetSystemMetrics(SM_CXVSCROLL);
  339. break;
  340. case E_TOP:
  341. rc.bottom = rc.top + CX_HIT;
  342. goto topbottom;
  343. case E_BOTTOM:
  344. rc.top = rc.bottom - CX_HIT;
  345. topbottom:
  346. InflateRect(&rc, - GetSystemMetrics(SM_CXVSCROLL), 0);
  347. break;
  348. }
  349. return (PtInRect(&rc, pt));
  350. }
  351. LRESULT CTheater::_OnMsgHook(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT *pmhs, BOOL fFake)
  352. {
  353. if (nCode >= 0)
  354. {
  355. POINT pt;
  356. GetCursorPos(&pt);
  357. MapWindowPoints(HWND_DESKTOP, _hwndBrowser, &pt, 1);
  358. BOOL bTryUnhideTaskbar = !_fTaskbarShown;
  359. // The timer business is so that we don't unhide
  360. // on a user trying to get to the scrollbar
  361. if (_iUnhidee)
  362. {
  363. KillTimer(_hwndFloater, IDT_UNHIDE);
  364. _iUnhidee = 0;
  365. }
  366. if (_PtOnEdge(pt, E_LEFT))
  367. {
  368. if (!_fBrowBarShown && _hwndBrowBar)
  369. _Unhide(IDT_BROWBAR, SHORT_DELAY);
  370. }
  371. else if (_PtOnEdge(pt, E_TOP))
  372. {
  373. if (!_fShown)
  374. _Unhide(IDT_TOOLBAR, SHORT_DELAY);
  375. }
  376. else if (!_PtOnEdge(pt, E_RIGHT) && !_PtOnEdge(pt, E_BOTTOM))
  377. {
  378. bTryUnhideTaskbar = FALSE;
  379. }
  380. #ifndef UNIX
  381. if (bTryUnhideTaskbar && !_fDelay && !_iUnhidee)
  382. {
  383. RECT rc;
  384. _GetWindowRectRel(_hwndTaskbar, &rc);
  385. if (PtInRect(&rc, pt))
  386. _Unhide(IDT_TASKBAR, GetCapture() ? LONG_DELAY : SHORT_DELAY);
  387. }
  388. #endif
  389. if (_fAutoHideBrowserBar && _fBrowBarShown && !_PtNearWindow(pt, _hwndBrowBar))
  390. _HideBrowBar();
  391. if (_fAutoHideToolbar && _fShown && !_PtNearWindow(pt, _hwndToolbar))
  392. _HideToolbar();
  393. #ifndef UNIX
  394. if (_fTaskbarShown && !_PtNearWindow(pt, _hwndTaskbar))
  395. _HideTaskbar();
  396. #endif
  397. }
  398. if (fFake)
  399. return 0;
  400. else
  401. return CallNextHookEx(_hhook, nCode, wParam, (LPARAM)pmhs);
  402. }
  403. LRESULT CTheater::_MsgHook(int nCode, WPARAM wParam, LPARAM lParam)
  404. {
  405. CTheater* pTheater;
  406. if (SUCCEEDED(_al.Find(GetCurrentThreadId(), (LPVOID*)&pTheater)))
  407. {
  408. return pTheater->_OnMsgHook(nCode, wParam, (MOUSEHOOKSTRUCT*)lParam, FALSE);
  409. }
  410. return 0;
  411. }
  412. void CTheater::Begin()
  413. {
  414. _ShowToolbar();
  415. SetTimer(_hwndFloater, IDT_INITIAL, 1500, NULL);
  416. }
  417. void CTheater::_SizeBrowser()
  418. {
  419. // position & size the browser window
  420. RECT rc;
  421. HMONITOR hMon = MonitorFromWindow(_hwndBrowser, MONITOR_DEFAULTTONEAREST);
  422. GetMonitorRect(hMon, &rc);
  423. InflateRect(&rc, CX_BROWOVERLAP, CX_BROWOVERLAP);
  424. SetWindowPos(_hwndBrowser, HWND_TOP, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), 0);
  425. }
  426. void CTheater::_SizeFloater()
  427. {
  428. // position & size the floater
  429. RECT rc;
  430. GetWindowRect(_hwndBrowser, &rc);
  431. int x = RECTWIDTH(rc) - (CX_FLOATERSHOWN + CX_BROWOVERLAP);
  432. int y = 0;
  433. int cy = GetWindowHeight(_hwndToolbar);
  434. SetWindowPos(_hwndFloater, HWND_TOP, x, y, CX_FLOATERSHOWN, cy, SWP_NOACTIVATE);
  435. }
  436. void CTheater::_CreateCloseMinimize()
  437. {
  438. _hwndClose = CreateWindowEx( WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  439. WS_VISIBLE | WS_CHILD |
  440. TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT |
  441. WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  442. CCS_NODIVIDER | CCS_NOPARENTALIGN |
  443. CCS_NORESIZE,
  444. 0, 0,
  445. CLOSEMIN_WIDTH, CLOSEMIN_HEIGHT,
  446. _hwndFloater, 0, HINST_THISDLL, NULL);
  447. if (_hwndClose) {
  448. static const TBBUTTON tb[] =
  449. {
  450. { 0, SC_MINIMIZE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, 0 },
  451. { 1, SC_RESTORE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, 0 },
  452. { 2, SC_CLOSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, 0 }
  453. };
  454. HIMAGELIST himl = ImageList_LoadImage(HINST_THISDLL,
  455. MAKEINTRESOURCE(IDB_THEATERCLOSE),
  456. 10, 0, RGB(255,0,255),
  457. IMAGE_BITMAP, LR_CREATEDIBSECTION);
  458. ImageList_SetBkColor(himl, RGB(0,0,0));
  459. SendMessage(_hwndClose, TB_SETIMAGELIST, 0, (LPARAM)himl);
  460. SendMessage(_hwndClose, TB_BUTTONSTRUCTSIZE, SIZEOF(TBBUTTON), 0);
  461. SendMessage(_hwndClose, TB_ADDBUTTONS, ARRAYSIZE(tb), (LPARAM)tb);
  462. SendMessage(_hwndClose, TB_SETMAXTEXTROWS, 0, 0L);
  463. TBBUTTONINFO tbbi;
  464. TCHAR szBuf[256];
  465. tbbi.cbSize = SIZEOF(TBBUTTONINFO);
  466. tbbi.dwMask = TBIF_TEXT;
  467. tbbi.pszText = szBuf;
  468. MLLoadString(IDS_CLOSE, szBuf, ARRAYSIZE(szBuf));
  469. SendMessage(_hwndClose, TB_SETBUTTONINFO, SC_CLOSE, (LPARAM)&tbbi);
  470. MLLoadString(IDS_RESTORE, szBuf, ARRAYSIZE(szBuf));
  471. SendMessage(_hwndClose, TB_SETBUTTONINFO, SC_RESTORE, (LPARAM)&tbbi);
  472. MLLoadString(IDS_MINIMIZE, szBuf, ARRAYSIZE(szBuf));
  473. SendMessage(_hwndClose, TB_SETBUTTONINFO, SC_MINIMIZE, (LPARAM)&tbbi);
  474. }
  475. }
  476. void CTheater::_Initialize()
  477. {
  478. _SizeBrowser();
  479. #ifndef UNIX
  480. _hwndTaskbar = FindWindow(TEXT("Shell_TrayWnd"), NULL);
  481. #ifdef DEBUG
  482. if (!_hwndTaskbar)
  483. {
  484. TraceMsg(TF_WARNING, "CTheater::_Initialize -- couldn't find taskbar window");
  485. }
  486. #endif // DEBUG
  487. #else
  488. _hwndTaskbar = NULL;
  489. #endif
  490. _fTaskbarShown = FALSE;
  491. _hwndFloater = SHCreateWorkerWindow(_FloaterWndProc, _hwndBrowser,
  492. #if defined(MAINWIN)
  493. // Removing window manager decors
  494. WS_EX_MW_UNMANAGED_WINDOW |
  495. #endif
  496. WS_EX_TOOLWINDOW,
  497. WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL, this);
  498. if (_hwndFloater) {
  499. int cx = 0;
  500. // create animating E logo
  501. IUnknown* punk;
  502. CBrandBand_CreateInstance(NULL, (IUnknown **)&punk, NULL);
  503. if (punk) {
  504. punk->QueryInterface(IID_IDeskBand, (LPVOID*)&_pdbBrand);
  505. if (_pdbBrand) {
  506. HWND hwndBrand;
  507. IUnknown_SetSite(_pdbBrand, SAFECAST(this, IOleWindow*));
  508. IUnknown_GetWindow(_pdbBrand, &hwndBrand);
  509. ASSERT(hwndBrand);
  510. #ifdef DEBUG
  511. // Make sure brand isn't too tall
  512. DESKBANDINFO dbi = {0};
  513. _pdbBrand->GetBandInfo(0, 0, &dbi);
  514. ASSERT(!(dbi.ptMinSize.y > BRAND_HEIGHT));
  515. #endif
  516. if (hwndBrand)
  517. {
  518. SetWindowPos(hwndBrand, NULL,
  519. cx, BRAND_YOFFSET, BRAND_WIDTH, BRAND_HEIGHT,
  520. SWP_NOZORDER | SWP_SHOWWINDOW);
  521. cx += BRAND_WIDTH + CLOSEMIN_XOFFSET;
  522. }
  523. // get floater background color
  524. VARIANTARG var = {VT_I4};
  525. IUnknown_Exec(_pdbBrand, &CGID_PrivCITCommands, CITIDM_GETDEFAULTBRANDCOLOR, 0, NULL, &var);
  526. _clrBrandBk = (COLORREF) var.lVal;
  527. }
  528. punk->Release();
  529. }
  530. // now create the progress bar
  531. _hwndProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL,
  532. WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | PBS_SMOOTH,
  533. cx - 1, PROGRESS_YPOS,
  534. PROGRESS_WIDTH, PROGRESS_HEIGHT,
  535. _hwndFloater, (HMENU)TMC_PROGRESSBAR,
  536. HINST_THISDLL, NULL);
  537. if (_hwndProgress)
  538. {
  539. SendMessage(_hwndProgress, PBM_SETBKCOLOR, 0, _clrBrandBk);
  540. SendMessage(_hwndProgress, PBM_SETBARCOLOR, 0, GetSysColor(COLOR_BTNSHADOW));
  541. // hack of the 3d client edge that WM_BORDER implies in dialogs
  542. // add the 1 pixel static edge that we really want
  543. SHSetWindowBits(_hwndProgress, GWL_EXSTYLE, WS_EX_STATICEDGE, 0);
  544. SetWindowPos(_hwndProgress, NULL, 0,0,0,0,
  545. SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  546. }
  547. // make the close/minimize buttons & position them
  548. _CreateCloseMinimize();
  549. if (_hwndClose)
  550. {
  551. SetWindowPos(_hwndClose, HWND_TOP, cx, CLOSEMIN_YOFFSET, 0, 0,
  552. SWP_NOSIZE | SWP_NOACTIVATE);
  553. }
  554. _SizeFloater();
  555. }
  556. }
  557. void CTheater::_SwapParents(HWND hwndOldParent, HWND hwndNewParent)
  558. {
  559. HWND hwnd = ::GetWindow(hwndOldParent, GW_CHILD);
  560. while (hwnd) {
  561. //
  562. // Note that we must get the next sibling BEFORE we set the new
  563. // parent.
  564. //
  565. HWND hwndNext = ::GetWindow(hwnd, GW_HWNDNEXT);
  566. if (hwnd != _hwndToolbar) {
  567. ::SetParent(hwnd, hwndNewParent);
  568. }
  569. hwnd = hwndNext;
  570. }
  571. }
  572. ////// begin floating palette (floater) window implementation
  573. ///
  574. /// floater keeps a ref count of activation (via command target)
  575. /// when the last activity goes away, it sets a timer and hides after a second.
  576. /// this is a regional window that will host the animation icon, progress bar, and
  577. /// close / minimize buttons
  578. ULONG CTheater::AddRef()
  579. {
  580. _cRef++;
  581. return _cRef;
  582. }
  583. ULONG CTheater::Release()
  584. {
  585. ASSERT(_cRef > 0);
  586. _cRef--;
  587. if (_cRef > 0)
  588. return _cRef;
  589. delete this;
  590. return 0;
  591. }
  592. HRESULT CTheater::QueryInterface(REFIID riid, LPVOID * ppvObj)
  593. {
  594. static const QITAB qit[] = {
  595. QITABENT(CTheater, IOleWindow),
  596. QITABENT(CTheater, IOleCommandTarget),
  597. QITABENT(CTheater, IServiceProvider),
  598. { 0 },
  599. };
  600. return QISearch(this, qit, riid, ppvObj);
  601. }
  602. HRESULT CTheater::GetWindow(HWND * lphwnd)
  603. {
  604. *lphwnd = _hwndFloater;
  605. if (_hwndFloater)
  606. return S_OK;
  607. return E_FAIL;
  608. }
  609. void CTheater::_SanityCheckZorder()
  610. {
  611. //
  612. // The view may have jumped to HWND_TOP, so we need to
  613. // fix up the floater, toolbar, and browbar positions
  614. // within the z-order.
  615. //
  616. SetWindowZorder(_hwndFloater, HWND_TOP);
  617. SetWindowZorder(_hwndToolbar, _hwndFloater);
  618. SetWindowZorder(_hwndBrowBar, _hwndToolbar);
  619. }
  620. HRESULT CTheater::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
  621. OLECMD rgCmds[], OLECMDTEXT *pcmdtext)
  622. {
  623. return OLECMDERR_E_UNKNOWNGROUP;
  624. }
  625. HRESULT CTheater::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt,
  626. VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
  627. {
  628. HRESULT hres = OLECMDERR_E_NOTSUPPORTED;
  629. if (pguidCmdGroup == NULL)
  630. {
  631. // nothing
  632. }
  633. else if (IsEqualGUID(CGID_Theater, *pguidCmdGroup))
  634. {
  635. switch (nCmdID)
  636. {
  637. case THID_ACTIVATE:
  638. _cActiveRef++;
  639. if (_cActiveRef == 1)
  640. _ShowFloater();
  641. break;
  642. case THID_DEACTIVATE:
  643. // we can get a deactivate before the first activate if
  644. // we come up during a navigate
  645. if (_cActiveRef > 0)
  646. {
  647. _cActiveRef--;
  648. _DelayHideFloater();
  649. }
  650. break;
  651. case THID_SETBROWSERBARAUTOHIDE:
  652. if (pvarargIn && pvarargIn->vt == VT_I4)
  653. {
  654. _fAutoHideBrowserBar = pvarargIn->lVal;
  655. if (!_fAutoHideBrowserBar)
  656. {
  657. // clear initial hide anymore. they are well aware of it if
  658. // they hit this switch
  659. _fInitialBrowserBar = FALSE;
  660. _ShowBrowBar();
  661. }
  662. }
  663. break;
  664. case THID_SETBROWSERBARWIDTH:
  665. if (pvarargIn && pvarargIn->vt == VT_I4)
  666. _cxBrowBarShown = pvarargIn->lVal;
  667. break;
  668. case THID_SETTOOLBARAUTOHIDE:
  669. if (pvarargIn && pvarargIn->vt == VT_I4)
  670. {
  671. _fAutoHideToolbar = pvarargIn->lVal;
  672. if (pvarargIn->lVal)
  673. _HideToolbar();
  674. else
  675. _ShowToolbar();
  676. }
  677. break;
  678. case THID_ONINTERNET:
  679. IUnknown_Exec(_pdbBrand, &CGID_PrivCITCommands, CITIDM_ONINTERNET, nCmdexecopt, pvarargIn, pvarargOut);
  680. break;
  681. case THID_RECALCSIZING:
  682. RecalcSizing();
  683. break;
  684. }
  685. }
  686. else if (IsEqualGUID(CGID_Explorer, *pguidCmdGroup))
  687. {
  688. switch (nCmdID)
  689. {
  690. case SBCMDID_ONVIEWMOVETOTOP:
  691. _SanityCheckZorder();
  692. hres = S_OK;
  693. break;
  694. }
  695. }
  696. return hres;
  697. }
  698. void CTheater::_OnCommand(UINT idCmd)
  699. {
  700. PostMessage(_hwndBrowser, WM_SYSCOMMAND, idCmd, 0);
  701. }
  702. LRESULT CTheater::_FloaterWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  703. {
  704. CTheater *t = (CTheater*)GetWindowPtr0(hwnd);
  705. if (!t)
  706. return 0;
  707. switch (uMsg)
  708. {
  709. case WM_COMMAND:
  710. t->_OnCommand(GET_WM_COMMAND_ID(wParam, lParam));
  711. break;
  712. case WM_CLOSE:
  713. case WM_NOTIFY:
  714. return SendMessage(t->_hwndBrowser, uMsg, wParam, lParam);
  715. case WM_TIMER:
  716. {
  717. switch (wParam) {
  718. case IDT_HIDEFLOATER1SEC:
  719. t->_HideFloater();
  720. break;
  721. case IDT_INITIALBROWSERBAR:
  722. // _fAutoHideBrowserBar may have changed after the timer was set
  723. if (t->_fAutoHideBrowserBar)
  724. t->_HideBrowBar();
  725. return 1;
  726. case IDT_INITIAL:
  727. {
  728. t->_HideToolbar();
  729. t->_hhook = SetWindowsHookEx(WH_MOUSE, _MsgHook, MLGetHinst(), GetCurrentThreadId());
  730. HWND hwndInsertAfter;
  731. if (t->_IsBrowserActive())
  732. {
  733. // We're active, just move to non-topmost
  734. hwndInsertAfter = HWND_NOTOPMOST;
  735. }
  736. else
  737. {
  738. // Another window became active while we were
  739. // moving to fullscreen mode; move ourselves below
  740. // that window. We need to walk up the parent chain
  741. // so that if the window has a modal dialog open we
  742. // won't insert ourselves between the dialog and the
  743. // app.
  744. hwndInsertAfter = GetForegroundWindow();
  745. HWND hwnd;
  746. while (hwnd = GetParent(hwndInsertAfter))
  747. {
  748. hwndInsertAfter = hwnd;
  749. }
  750. }
  751. SetWindowZorder(t->_hwndBrowser, hwndInsertAfter);
  752. // Call the hook handler manually to insure that even if there's no mouse
  753. // movement the handler will get called once. That way, bar unhiding will
  754. // still work if the user has already given up and stopped moving the mouse.
  755. t->_OnMsgHook(0, 0, NULL, TRUE);
  756. }
  757. break;
  758. case IDT_UNHIDE:
  759. switch (t->_iUnhidee)
  760. {
  761. case IDT_TOOLBAR:
  762. t->_ShowToolbar();
  763. break;
  764. case IDT_BROWBAR:
  765. t->_ShowBrowBar();
  766. break;
  767. case IDT_TASKBAR:
  768. t->_ShowTaskbar();
  769. break;
  770. }
  771. SetTimer(t->_hwndFloater, IDT_DELAY, LONG_DELAY, NULL);
  772. t->_fDelay = TRUE;
  773. t->_iUnhidee = 0;
  774. break;
  775. case IDT_DELAY:
  776. t->_fDelay = FALSE;
  777. break;
  778. case IDT_HIDETOOLBAR:
  779. t->_ContinueHideToolbar();
  780. break;
  781. case IDT_HIDEBROWBAR:
  782. t->_ContinueHideBrowBar();
  783. break;
  784. case IDT_HIDEFLOATER:
  785. t->_ContinueHideFloater();
  786. break;
  787. }
  788. KillTimer(hwnd, wParam);
  789. break;
  790. }
  791. case WM_SETTINGCHANGE:
  792. if (wParam == SPI_SETNONCLIENTMETRICS)
  793. {
  794. t->RecalcSizing();
  795. }
  796. break;
  797. case WM_ERASEBKGND:
  798. {
  799. HDC hdc = (HDC)wParam;
  800. RECT rc;
  801. GetClientRect(hwnd, &rc);
  802. SHFillRectClr(hdc, &rc, t->_clrBrandBk);
  803. return 1;
  804. }
  805. default:
  806. return ::DefWindowProcWrap(hwnd, uMsg, wParam, lParam);
  807. }
  808. return 0;
  809. }
  810. void CTheater::RecalcSizing()
  811. {
  812. _SizeBrowser();
  813. _SizeFloater();
  814. }
  815. HRESULT CTheater::QueryService(REFGUID guidService, REFIID riid, void **ppvObj)
  816. {
  817. return IUnknown_QueryService(_punkOwner, guidService, riid, ppvObj);
  818. }
  819. HRESULT CTheater::SetBrowserBar(IUnknown* punk, int cxHidden, int cxExpanded)
  820. {
  821. if (punk != _punkBrowBar) {
  822. IUnknown_Exec(_punkBrowBar, &CGID_Theater, THID_DEACTIVATE, 0, NULL, NULL);
  823. ATOMICRELEASE(_punkBrowBar);
  824. IUnknown_GetWindow(punk, &_hwndBrowBar);
  825. _punkBrowBar = punk;
  826. if (punk)
  827. punk->AddRef();
  828. if (_hwndBrowBar)
  829. {
  830. _cxBrowBarShown = cxExpanded;
  831. // tell the browser bar to only ever request the hidden window size
  832. VARIANT var = { VT_I4 };
  833. var.lVal = _fAutoHideBrowserBar;
  834. IUnknown_Exec(_punkBrowBar, &CGID_Theater, THID_ACTIVATE, 0, &var, &var);
  835. _fAutoHideBrowserBar = var.lVal;
  836. }
  837. }
  838. if (punk) {
  839. if (_hwndBrowBar)
  840. _ShowBrowBar();
  841. // if we're in autohide mode, the first hide should be slow
  842. if (_fAutoHideBrowserBar) {
  843. _fInitialBrowserBar = TRUE;
  844. SetTimer(_hwndFloater, IDT_INITIALBROWSERBAR, 1000, NULL);
  845. }
  846. }
  847. return S_OK;
  848. }
  849. #endif /* !DISABLE_FULLSCREEN */