theater.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 29k
Category:

Windows Kernel

Development Platform:

Visual C++

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