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

Windows Kernel

Development Platform:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////////
  2. // SSWND.CPP
  3. //
  4. // Implementation of CScreenSaverWindow
  5. //
  6. // History:
  7. //
  8. // Author   Date        Description
  9. // ------   ----        -----------
  10. // jaym     08/26/96    Created
  11. // jaym     01/24/97    Added password verification
  12. // jaym     04/15/97    Toolbar UI updates
  13. // jaym     05/05/97    Removed Toolbar
  14. // jaym     05/19/97    Re-added Toolbar
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "precomp.h"
  17. #include <regstr.h>
  18. #include "regini.h"
  19. #include "resource.h"
  20. #include "sswnd.h"
  21. #define TF_DEBUGQI          0
  22. #define TF_DEBUGQS          0
  23. #define TF_DEBUGREFCOUNT    0
  24. #define TF_NAVIGATION       0
  25. #define TF_NOTIFY           0
  26. #define TF_TIMER            0
  27. #define TF_FUNCENTRY        0
  28. #define TF_CLOSE            TF_ALWAYS
  29. #define WM_LOADSCREENSAVER  (WM_USER+550)
  30. /////////////////////////////////////////////////////////////////////////////
  31. // Global variables
  32. /////////////////////////////////////////////////////////////////////////////
  33. BOOL                g_bPasswordEnabled;
  34. extern BOOL         g_bPlatformNT;
  35. extern TCHAR        g_szRegSubKey[];
  36. extern IMalloc *    g_pMalloc;
  37. extern IMMASSOCPROC g_pfnIMMProc;
  38. /////////////////////////////////////////////////////////////////////////////
  39. // Module variables
  40. /////////////////////////////////////////////////////////////////////////////
  41. static CScreenSaverWindow * s_pThis = NULL;
  42. static HHOOK                s_hKeyboardHook = NULL;
  43. static HHOOK                s_hMouseHook = NULL;
  44. #pragma data_seg(DATASEG_READONLY)
  45. static const TCHAR      s_szScreenSaverKey[] = REGSTR_PATH_SCREENSAVE;
  46. static const TCHAR      s_szPasswordActiveValue[] = REGSTR_VALUE_USESCRPASSWORD;
  47. static const TCHAR      s_szPasswordActiveOnNTValue[] = TEXT("ScreenSaverIsSecure");
  48. static const TCHAR      s_szPasswordValue[] = REGSTR_VALUE_SCRPASSWORD;
  49. static const TCHAR      s_szPasswordDLL[] = TEXT("PASSWORD.CPL");
  50. static const TCHAR      s_szPasswordFnName[] = TEXT("VerifyScreenSavePwd");
  51.     // Password
  52. static const TCHAR      s_szRegLastURL[]        = TEXT("LastURL");
  53. static const TCHAR      s_szRegLastNavURL[]     = TEXT("LastNavURL");
  54. static const TCHAR      s_szSETermEvent[]       = TEXT("ActSaverSEEvent");
  55. static const TCHAR      s_szTrayUIWindow[]      = TEXT("MS_WebcheckMonitor");
  56. static const TCHAR      s_szRES[]               = TEXT("res://");
  57. static const TCHAR      s_szSSEmptyFile[]       = TEXT("/ssempty.htm");
  58. static const OLECHAR    s_szYes[]               = OLESTR("YES");
  59. static const OLECHAR    s_szNo[]                = OLESTR("NO");
  60. static const OLECHAR    s_szDefTransition[]     = OLESTR("revealTrans(Duration=5.0, Transition=15)");
  61.     // Misc.
  62. #pragma data_seg()
  63. /////////////////////////////////////////////////////////////////////////////
  64. // Design constants
  65. /////////////////////////////////////////////////////////////////////////////
  66. #define MOUSEMOVE_THRESHOLD         10  // In pixels
  67.     // Number of pixels that the mouse must move to determine a
  68.     // 'real' mouse move event (for closing the Screen Saver).
  69. #define ID_CHANNELCHANGE_TIMER      0x0100
  70.     // Channel change/update timer ID
  71. #define ID_CONTROLS_TIMER           0x0101
  72.     // Scrollbar/Toolbar show/hide timer ID
  73. #define ID_CLICKCHECK_TIMER         0x0102
  74.     // Hotlink click check timer ID
  75. #define ID_RESTART_TIMER            0x0103
  76.     // Restart timer ID
  77. #define TIME_CONTROLS_TIMEOUT       3000    // ms (3 seconds)
  78.     // Scrollbar/Toolbar show/hide timeout
  79. #define TIME_CLICKCHECK_TIMEOUT     1000    // ms (1 second)
  80.     // Hotlink click check timeout
  81. #define TIME_NAVIGATE_TIMEOUT       10000   // ms (10 seconds)
  82.     // WebBrowser Navigate timeout
  83. #define CX_TOOLBAR                  51
  84. #define CY_TOOLBAR                  29
  85.     // Toolbar dimensions
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CScreenSaverWindow
  88. /////////////////////////////////////////////////////////////////////////////
  89. CScreenSaverWindow::CScreenSaverWindow
  90. (
  91. )
  92. {
  93.     m_cRef = 0;
  94.     m_pToolbar = NULL;
  95.     m_bModelessEnabled = TRUE;
  96.     m_bMouseClicked = FALSE;
  97.     m_bScrollbarVisible = TRUE;
  98.     m_pScreenSaver = NULL;
  99.     m_pSSConfig = NULL;
  100.     m_idChangeTimer = 0;
  101.     m_idControlsTimer = 0;
  102.     m_idClickCheckTimer = 0;
  103.     m_idReloadTimer = 0;
  104.     m_pPIDLList = NULL;
  105.     m_pidlDefault = NULL;
  106.     m_lCurrChannel = CURRENT_CHANNEL_NONE;
  107.     m_pUnkBrowser = NULL;
  108.     m_pWebBrowser = NULL;
  109.     m_pOleObject = NULL;
  110.     m_pHlinkFrame = NULL;
  111.     m_pHTMLDocument = NULL;
  112.     m_dwWebBrowserEvents = 0L;
  113.     m_dwWebBrowserEvents2 = 0L;
  114.     m_dwHTMLDocumentEvents = 0L;
  115.     m_pBindStatusCallback = NULL;
  116.     m_hPasswordDLL = NULL;
  117.     m_pfnVerifyPassword = NULL;
  118.     m_hPrevBrowserIMC = 0;
  119.     m_lVerifingPassword = FALSE;
  120. }
  121. CScreenSaverWindow::~CScreenSaverWindow
  122. (
  123. )
  124. {
  125.     // All clean-up is done in OnDestroy and OnNCDestroy.
  126. }
  127. //
  128. // Helper routine to check appropriate registry value to see if screensaver
  129. // is password protected.
  130. //
  131. BOOL IsScreenSaverPasswordProtected()
  132. {
  133.     BOOL bRetValue = FALSE;
  134.     HKEY hKey;
  135.     if (RegOpenKey( HKEY_CURRENT_USER,
  136.                     s_szScreenSaverKey,
  137.                     &hKey) == ERROR_SUCCESS)
  138.     {
  139.         //
  140.         // Registry key string is different on Win95 & NT !!!
  141.         //
  142.         if (g_bPlatformNT)
  143.         {
  144.             CHAR buf[4];
  145.             DWORD dwSize = sizeof(buf);
  146.             if (RegQueryValueEx(hKey, s_szPasswordActiveOnNTValue,
  147.                                 NULL,
  148.                                 NULL,
  149.                                 (BYTE *)buf,
  150.                                 &dwSize) == ERROR_SUCCESS)
  151.             {
  152.                 //
  153.                 // check if "1" is returned in buf
  154.                 //
  155.                 if (dwSize == 2 && buf[0] == '1')
  156.                 {
  157.                     bRetValue = TRUE;
  158.                 }
  159.             }
  160.         }
  161.         else
  162.         {
  163.             DWORD dwVal;
  164.             DWORD dwSize = sizeof(DWORD);
  165.             if  (
  166.                 (RegQueryValueEx(   hKey,
  167.                                     s_szPasswordActiveValue,
  168.                                     NULL,
  169.                                     NULL,
  170.                                     (BYTE *)&dwVal,
  171.                                     &dwSize) == ERROR_SUCCESS)
  172.                 &&
  173.                 (dwVal != 0)
  174.                 )
  175.             {
  176.                 bRetValue = TRUE;
  177.             }
  178.         }
  179.         RegCloseKey(hKey);
  180.     }
  181.     return bRetValue;
  182. }
  183. /////////////////////////////////////////////////////////////////////////////
  184. // CScreenSaverWindow::Create
  185. /////////////////////////////////////////////////////////////////////////////
  186. BOOL CScreenSaverWindow::Create
  187. (
  188.     const RECT &    rect,
  189.     HWND            hwndParent,
  190.     IScreenSaver *  pScreenSaver
  191. )
  192. {
  193.     HRESULT hrResult;
  194.     ASSERT(pScreenSaver != NULL);
  195.     TraceMsg(TF_ALWAYS, "CScreenSaverWindow::Create(hwndParent=%x)", hwndParent);
  196.     //
  197.     // Set the g_bPasswordEnabled flag
  198.     //
  199.     g_bPasswordEnabled = IsScreenSaverPasswordProtected();
  200.     for (;;)
  201.     {
  202.         // Save this pointer for Hook functions.
  203.         s_pThis = this;
  204.         // Save IScreenSaver interface pointer.
  205.         m_pScreenSaver = pScreenSaver;
  206.         m_pScreenSaver->AddRef();
  207.         // Get the Configuration interface pointer.
  208.         if (FAILED(hrResult = m_pScreenSaver->QueryInterface(IID_IScreenSaverConfig,
  209.                                                              (void **)&m_pSSConfig)))
  210.             break;
  211.         DWORD dwFeatureFlags;
  212.         EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  213.         // Create the actual window.
  214.         if (!CWindow::CreateEx( NULL,
  215.                                 ((dwFeatureFlags & FEATURE_NOT_TOPMOST)
  216.                                     ? 0
  217.                                     : (WS_EX_TOOLWINDOW | WS_EX_TOPMOST)),
  218.                                 WS_POPUP,
  219.                                 rect,
  220.                                 hwndParent,
  221.                                 0))
  222.         {
  223.             hrResult = E_OUTOFMEMORY;
  224.             break;
  225.         }
  226.         TraceMsg(TF_ALWAYS, "CScreenSaverWindow::Create(m_hWnd=%x)", m_hWnd );
  227.         // If we aren't on NT, load the password verification DLL.
  228.         if (!g_bPlatformNT)
  229.             LoadPasswordDLL();
  230.         // Create PIDL for default HTML page
  231.         char szModuleName[MAX_PATH];
  232.         GetModuleFileName(_pModule->GetModuleInstance(), szModuleName, MAX_PATH);
  233.         CString strURLDefault;
  234.         strURLDefault = s_szRES;
  235.         strURLDefault += PathFindFileName(szModuleName);
  236.         strURLDefault += s_szSSEmptyFile;
  237.         EVAL(CreatePIDLFromPath(strURLDefault, &m_pidlDefault));
  238.         // Create the toolbar.
  239.         RECT rectToolbar;
  240.         rectToolbar.left    = rect.right - CX_TOOLBAR;
  241.         rectToolbar.top     = 0;
  242.         rectToolbar.right   = rectToolbar.left + CX_TOOLBAR;
  243.         rectToolbar.bottom  = rectToolbar.top + CY_TOOLBAR;
  244.         m_pToolbar = new CToolbarWindow;
  245.         if (NULL == m_pToolbar)
  246.         {
  247.             hrResult = E_OUTOFMEMORY;
  248.             break;
  249.         }
  250.         if (!m_pToolbar->Create(rectToolbar, this))
  251.         {
  252.             delete m_pToolbar;
  253.             m_pToolbar = NULL;
  254.             hrResult = E_OUTOFMEMORY;
  255.             break;
  256.         }
  257.         // Initialize the channel view list.
  258.         InitChannelList();
  259.         //  TODO: Darrenmi add online/offline registration here.
  260.         // Initialize the web browser.
  261.         if (!CreateWebBrowser(rect))
  262.         {
  263.             CString strCaption;
  264.             CString strText;
  265.             // Display error message.
  266.             strCaption.LoadString(IDS_SCREENSAVER_DESC);
  267.             strText.LoadString(IDS_ERROR_REQUIREMENTSNOTMET);
  268.             MessageBox(hwndParent, strText, strCaption, MB_OK);
  269.             hrResult = E_OUTOFMEMORY;
  270.             break;
  271.         }
  272.         // Setup the Keyboard and Mouse hooks.
  273.         SetHooks();
  274.         // Show the first channel.
  275.         DisplayCurrentChannel();
  276.         // Start the reload timer.
  277.         if (!g_bPlatformNT)
  278.         {
  279.             DWORD dwRestartTime;
  280.             EVAL(SUCCEEDED(m_pSSConfig->get_RestartTime(&dwRestartTime)));
  281.             EVAL((m_idReloadTimer = SetTimer(   ID_RESTART_TIMER,
  282.                                                 dwRestartTime,
  283.                                                 NULL)) != 0);
  284.         }
  285.         hrResult = S_OK;
  286.         break;
  287.     }
  288.     return SUCCEEDED(hrResult);
  289. }
  290. /////////////////////////////////////////////////////////////////////////////
  291. // CScreenSaverWindow::ShowControls
  292. /////////////////////////////////////////////////////////////////////////////
  293. void CScreenSaverWindow::ShowControls
  294. (
  295.     BOOL bShow
  296. )
  297. {
  298.     TraceMsg(   TF_FUNCENTRY,
  299.                 "ShowControls(%d): m_bScrollbarVisible = %d, Toolbar = %d",
  300.                 bShow, m_bScrollbarVisible, m_pToolbar->IsWindowVisible());
  301.     // Kill the current 'controls timer' and restart if needed.
  302.     if (m_idControlsTimer != 0)
  303.     {
  304.         EVAL(KillTimer(m_idControlsTimer));
  305.         m_idControlsTimer = 0;
  306.     }
  307.     // Screen saver does not need the IME.                
  308.     if (g_pfnIMMProc != NULL)
  309.     {
  310.         if (m_hPrevBrowserIMC != 0)
  311.         {
  312.             g_pfnIMMProc(m_hwndContainer, m_hPrevBrowserIMC);
  313.             m_hPrevBrowserIMC = 0;
  314.         }
  315.         ASSERT(m_hwndContainer != NULL)
  316.         m_hPrevBrowserIMC = g_pfnIMMProc(m_hwndContainer, (HIMC)NULL);
  317.     }
  318.     IHTMLBodyElement * pHTMLBodyElement = NULL;
  319.     BOOL               bLongContent = FALSE;
  320.     RECT rectClient;
  321.     GetClientRect(&rectClient);
  322.     // Check to see if the content is long enough to warrant scrollbars.
  323.     if  (
  324.         SUCCEEDED(GetHTMLBodyElement(&pHTMLBodyElement))
  325.         &&
  326.         (pHTMLBodyElement != NULL)
  327.         )
  328.     {
  329.         IHTMLTextContainer * pTxtEdit = NULL;
  330.         if  (
  331.             (SUCCEEDED(pHTMLBodyElement->QueryInterface(IID_IHTMLTextContainer,
  332.                                                         (void **)&pTxtEdit)))
  333.             &&
  334.             (pTxtEdit != NULL)
  335.             )
  336.         {
  337.             long lHeight;
  338.             EVAL(SUCCEEDED(pTxtEdit->get_scrollHeight(&lHeight)));
  339.             bLongContent = (lHeight > (rectClient.bottom - rectClient.top));
  340.             pTxtEdit->Release();
  341.         }
  342.     }
  343.     // Don't show scrollbar if we don't need them.
  344.     if (pHTMLBodyElement != NULL)
  345.     {
  346.         if (m_bScrollbarVisible != bShow)
  347.         {
  348.             BSTR bstrScroll = SysAllocString(((bShow && bLongContent)? s_szYes : s_szNo));
  349.             if (bstrScroll)
  350.             {
  351.                 pHTMLBodyElement->put_scroll(bstrScroll);
  352.                 SysFreeString(bstrScroll);
  353.                 m_bScrollbarVisible = bShow;
  354.             }
  355.         }
  356.         pHTMLBodyElement->Release();
  357.     }
  358.     // Show the toolbar, too.
  359.     if ((m_pToolbar != NULL) && (m_pToolbar->IsWindowVisible() != bShow))
  360.     {
  361.         RECT rectToolbar;
  362.         m_pToolbar->GetWindowRect(&rectToolbar);
  363.         // Position toolbar appropriately, depending
  364.         // on visibility of the scrollbar.
  365.         if (bLongContent)
  366.         {
  367.             if (rectToolbar.right == rectClient.right)
  368.             {
  369.                 OffsetRect(&rectToolbar, -GetSystemMetrics(SM_CXVSCROLL), 0);
  370.                 m_pToolbar->SetWindowPos(   NULL,
  371.                                             &rectToolbar,
  372.                                             SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOSIZE);
  373.             }
  374.         }
  375.         else
  376.         {
  377.             if (rectToolbar.right != rectClient.right)
  378.             {
  379.                 OffsetRect(&rectToolbar, GetSystemMetrics(SM_CXVSCROLL), 0);
  380.                 m_pToolbar->SetWindowPos(   NULL,
  381.                                             &rectToolbar,
  382.                                             SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOSIZE);
  383.             }
  384.         }
  385.         m_pToolbar->ShowToolbar(bShow);
  386.     }
  387.     if  (
  388.         m_bScrollbarVisible
  389.         ||
  390.         ((m_pToolbar != NULL) && m_pToolbar->IsWindowVisible())
  391.         )
  392.     {
  393.         EVAL((m_idControlsTimer = SetTimer( ID_CONTROLS_TIMER,
  394.                                             TIME_CONTROLS_TIMEOUT,
  395.                                             NULL)) != 0);
  396.     }
  397.     // REVIEW: Should use UIActivate? [jaym]
  398.     POINT pt = { 0 };
  399.     m_hwndContainer = WindowFromPoint(pt);
  400.     SetFocus(m_hwndContainer);
  401. }
  402. /////////////////////////////////////////////////////////////////////////////
  403. // CScreenSaverWindow::ShowPropertiesDlg
  404. /////////////////////////////////////////////////////////////////////////////
  405. void CScreenSaverWindow::ShowPropertiesDlg
  406. (
  407.     HWND hwndParent
  408. )
  409. {
  410.     // Save the 'current' channel.
  411.     SaveState();            
  412.     EnableModeless(FALSE);
  413.     m_pSSConfig->ShowDialog(hwndParent);
  414.     EnableModeless(TRUE);
  415.     // Reinitialize the internal channel list.
  416.     InitChannelList();
  417.     // Show the first channel in the new list.
  418.     DisplayCurrentChannel();
  419. }
  420. /////////////////////////////////////////////////////////////////////////////
  421. // CScreenSaverWindow::OnCreate
  422. /////////////////////////////////////////////////////////////////////////////
  423. BOOL CScreenSaverWindow::OnCreate
  424. (
  425.     CREATESTRUCT * pcs
  426. )
  427. {
  428.     return TRUE;
  429. }
  430. /////////////////////////////////////////////////////////////////////////////
  431. // CScreenSaverWindow::OnDestroy
  432. /////////////////////////////////////////////////////////////////////////////
  433. void CScreenSaverWindow::OnDestroy
  434. (
  435. )
  436. {
  437.     TraceMsg(TF_CLOSE, "CScreenSaverWindow::OnDestroy() BEGIN");
  438.     ReleaseHooks();
  439.     if (m_idChangeTimer != 0)
  440.         EVAL(KillTimer(m_idChangeTimer));
  441.     if (m_idControlsTimer != 0)
  442.         EVAL(KillTimer(m_idControlsTimer));
  443.     if (m_idClickCheckTimer != 0)
  444.         EVAL(KillTimer(m_idClickCheckTimer));
  445.     if (m_idReloadTimer != 0)
  446.         EVAL(KillTimer(m_idReloadTimer));
  447.     if (m_pToolbar != NULL)
  448.         delete m_pToolbar;
  449.     if (m_hPrevBrowserIMC != 0)
  450.     {
  451.         ASSERT(m_hwndContainer != NULL);
  452.         g_pfnIMMProc(m_hwndContainer, m_hPrevBrowserIMC);
  453.     }
  454.     //  TODO: Darrenmi add online/offline deregistration here.
  455.     ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  456.                                 DIID_DWebBrowserEvents,
  457.                                 FALSE,
  458.                                 m_pUnkBrowser,
  459.                                 &m_dwWebBrowserEvents,
  460.                                 NULL);
  461.     ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  462.                                 DIID_DWebBrowserEvents2,
  463.                                 FALSE,
  464.                                 m_pUnkBrowser,
  465.                                 &m_dwWebBrowserEvents2,
  466.                                 NULL);
  467.     if (m_pHTMLDocument != NULL)
  468.     {
  469.         // Disconnect current connection to HTMLDocumentEvents
  470.         ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  471.                                     DIID_HTMLDocumentEvents,
  472.                                     FALSE,
  473.                                     m_pHTMLDocument,
  474.                                     &m_dwHTMLDocumentEvents,
  475.                                     NULL);
  476.         m_pHTMLDocument->Release();
  477.     }
  478.     OleSetContainedObject((IUnknown *)m_pOleObject, FALSE);
  479.     if (m_pHlinkFrame != NULL)
  480.         m_pHlinkFrame->Release();
  481.     if (m_pOleObject != NULL)
  482.     {
  483.         m_pOleObject->DoVerb(   OLEIVERB_HIDE,
  484.                                 NULL,
  485.                                 SAFECAST(this, IOleClientSite *),
  486.                                 0,
  487.                                 m_hWnd,
  488.                                 NULL);
  489.         m_pOleObject->SetClientSite(NULL);
  490.         m_pOleObject->Close(OLECLOSE_NOSAVE);
  491.         m_pOleObject->Release();
  492.     }
  493.     if (m_pWebBrowser != NULL)
  494.     {
  495.         m_pWebBrowser->Stop();
  496.         m_pWebBrowser->Release();
  497.     }
  498.     if (m_pBindStatusCallback != NULL)
  499.         EVAL(m_pBindStatusCallback->Release() == 0);
  500.     if (m_hPasswordDLL != NULL)
  501.         UnloadPasswordDLL();
  502.     if (m_pPIDLList != NULL)
  503.         delete m_pPIDLList;
  504.     if (m_pidlDefault != NULL)
  505.         g_pMalloc->Free(m_pidlDefault);
  506.     if (m_pUnkBrowser != NULL)
  507.         m_pUnkBrowser->Release();
  508.     if (m_pSSConfig != NULL)
  509.         m_pSSConfig->Release();
  510.     m_pScreenSaver->put_Running(FALSE);
  511.     if (m_pScreenSaver != NULL)
  512.         m_pScreenSaver->Release();
  513.     CWindow::OnDestroy();
  514.     PostQuitMessage(0);
  515.     TraceMsg(TF_CLOSE, "CScreenSaverWindow::OnDestroy() END");
  516. }
  517. /////////////////////////////////////////////////////////////////////////////
  518. // CScreenSaverWindow::OnEraseBkgnd
  519. /////////////////////////////////////////////////////////////////////////////
  520. BOOL CScreenSaverWindow::OnEraseBkgnd
  521. (
  522.     HDC hDC
  523. )
  524. {
  525.     return TRUE;
  526. }
  527. /////////////////////////////////////////////////////////////////////////////
  528. // CScreenSaverWindow::OnTimer
  529. /////////////////////////////////////////////////////////////////////////////
  530. void CScreenSaverWindow::OnTimer
  531. (
  532.     UINT nIDTimer
  533. )
  534. {
  535.     if  (
  536.         // Ignore if there is a dialog up or we are disabled.
  537.         !m_bModelessEnabled
  538.         ||
  539.         // Ignore if the user is selecting or scrolling.
  540.         (GetAsyncKeyState((GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON)) & 0x8000)
  541.         )
  542.     {
  543.         return;
  544.     }
  545.     switch (nIDTimer)
  546.     {
  547.         case ID_CONTROLS_TIMER:
  548.         {
  549.             TraceMsg(TF_TIMER, "CScreenSaverWindow::OnTimer(ID_CONTROLS_TIMER)");
  550.             ShowControls(FALSE);
  551.             break;
  552.         }
  553.         case ID_CHANNELCHANGE_TIMER:
  554.         {
  555.             TraceMsg(TF_TIMER, "CScreenSaverWindow::OnTimer(ID_CHANNELCHANGE_TIMER)");
  556.             OnChannelChangeTimer();
  557.             break;
  558.         }
  559.         case ID_CLICKCHECK_TIMER:
  560.         {
  561.             TraceMsg(TF_TIMER, "CScreenSaverWindow::OnTimer(ID_CLICKCHECK_TIMER)");
  562.             ASSERT(m_idClickCheckTimer != 0);
  563.             ASSERT(m_bMouseClicked);
  564.             EVAL(KillTimer(m_idClickCheckTimer));
  565.             m_idClickCheckTimer = 0;
  566.             Quit();
  567.             break;
  568.         }
  569.         case ID_RESTART_TIMER:
  570.         {
  571.             HWND hwndTrayUI;
  572.             TraceMsg(TF_TIMER, "CScreenSaverWindow::OnTimer(ID_RELOAD_TIMER)");
  573.             // Send message which will be handled in
  574.             // WebCheck to restart the screen saver.
  575.             if ((hwndTrayUI = FindWindow(s_szTrayUIWindow, s_szTrayUIWindow)) != NULL)
  576.             {
  577.                 ::PostMessage(hwndTrayUI, WM_LOADSCREENSAVER, 0, 0);
  578.                 EVAL(KillTimer(m_idReloadTimer));
  579.                 m_idReloadTimer = 0;
  580.                 Quit(TRUE);
  581.             }
  582.             break;
  583.         }
  584.         default:
  585.             ASSERT(FALSE);
  586.     }
  587. }
  588. /////////////////////////////////////////////////////////////////////////////
  589. // CScreenSaverWindow::OnUserMessage
  590. /////////////////////////////////////////////////////////////////////////////
  591. LRESULT CScreenSaverWindow::OnUserMessage
  592. (
  593.     HWND    hWnd,
  594.     UINT    uMsg,
  595.     WPARAM  wParam,
  596.     LPARAM  lParam
  597. )
  598. {
  599.     switch (uMsg)
  600.     {
  601.         case WM_ABORTNAVIGATE:
  602.             return NavigateToDefault();
  603.         case WM_DEATHTOSAVER:
  604.             DestroyWindow(m_hWnd);
  605.             break;
  606.             
  607.         default:
  608.             break;
  609.     }
  610.     return -1;
  611. }
  612. ////////////////////////////////////////////////////////////////////////////
  613. //
  614. //
  615. #define PARAM_PROCESSED     0
  616. #define PARAM_HEADERS       1
  617. #define PARAM_POST_DATA     2
  618. #define PARAM_FRAME_NAME    3
  619. #define PARAM_FLAGS         4
  620. #define PARAM_URL           5
  621. //
  622. //
  623. //
  624. ////////////////////////////////////////////////////////////////////////////
  625. /////////////////////////////////////////////////////////////////////////////
  626. // CScreenSaverWindow::OnBeforeNavigate
  627. /////////////////////////////////////////////////////////////////////////////
  628. #define NUM_PARAM_NEWWINDOW 6
  629. HRESULT CScreenSaverWindow::OnNewWindow
  630. (
  631.     DISPPARAMS *    pDispParams,
  632.     VARIANT *       pVarResult
  633. )
  634. {
  635.     HRESULT hrResult;
  636.     for (;;)
  637.     {
  638.         if (pDispParams == NULL)
  639.         {
  640.             hrResult = DISP_E_PARAMNOTOPTIONAL;
  641.             break;
  642.         }
  643.         if (pDispParams->cArgs != NUM_PARAM_NEWWINDOW)
  644.         {
  645.             hrResult = DISP_E_BADPARAMCOUNT;
  646.             break;
  647.         }
  648.             // Check for password.
  649.         if (VerifyPassword())
  650.         {
  651.             CString strNavigateURL;
  652.             ASSERT(pDispParams->rgvarg[PARAM_URL].vt == VT_BSTR);
  653.             strNavigateURL = pDispParams->rgvarg[PARAM_URL].bstrVal;
  654.             TraceMsg(TF_NAVIGATION, "Navigate URL = '%s'rn", (LPCTSTR)strNavigateURL);
  655.             if (LaunchBrowser(strNavigateURL))
  656.             {
  657.                 // Save our state and quit the Screen Saver
  658.                 // if we successfully launched the browser.
  659.                 TraceMsg(TF_CLOSE, "Attempting to close screen saver");
  660.                 Quit(TRUE);
  661.             }
  662.             else
  663.                 MessageBeep(MB_ICONEXCLAMATION);
  664.         }
  665.         // Set the cancel flag to TRUE to disallow
  666.         // shdocvw from launching a new window
  667.         ASSERT(pDispParams->rgvarg[PARAM_PROCESSED].vt == (VT_BYREF | VT_BOOL));
  668.         *(pDispParams->rgvarg[PARAM_PROCESSED].pboolVal) = VARIANT_TRUE;
  669.         hrResult = S_OK;
  670.         break;
  671.     }
  672.     return hrResult;
  673. }
  674. /////////////////////////////////////////////////////////////////////////////
  675. // CScreenSaverWindow::OnBeforeNavigate
  676. /////////////////////////////////////////////////////////////////////////////
  677. #define NUM_PARAM_BEFORENAV 6
  678. #define PARAM_PROCESSED     0
  679. #define PARAM_HEADERS       1
  680. #define PARAM_POST_DATA     2
  681. #define PARAM_FRAME_NAME    3
  682. #define PARAM_FLAGS         4
  683. #define PARAM_URL           5
  684. HRESULT CScreenSaverWindow::OnBeforeNavigate
  685. (
  686.     DISPPARAMS *    pDispParams,
  687.     VARIANT *       pVarResult
  688. )
  689. {
  690.     HRESULT hrResult;
  691.     for (;;)
  692.     {
  693.         if (pDispParams == NULL)
  694.         {
  695.             hrResult = DISP_E_PARAMNOTOPTIONAL;
  696.             break;
  697.         }
  698.         if (pDispParams->cArgs != NUM_PARAM_BEFORENAV)
  699.         {
  700.             hrResult = DISP_E_BADPARAMCOUNT;
  701.             break;
  702.         }
  703.         DWORD dwFeatureFlags;
  704.         EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  705.         // We'll skip everything until a mouse click happens
  706.         if (m_bMouseClicked && !(dwFeatureFlags & FEATURE_IGNORE_MOUSE_CLICKS))
  707.         {
  708.             ASSERT(m_idClickCheckTimer != 0);
  709.             EVAL(KillTimer(m_idClickCheckTimer));
  710.             m_idClickCheckTimer = 0;
  711.             // Check for password.
  712.             if (VerifyPassword())
  713.             {
  714.                 CString strNavigateURL;
  715.                 ASSERT(pDispParams->rgvarg[PARAM_URL].vt == VT_BSTR);
  716.                 strNavigateURL = pDispParams->rgvarg[PARAM_URL].bstrVal;
  717.                 TraceMsg(TF_NAVIGATION, "Navigate URL = '%s'rn", (LPCTSTR)strNavigateURL);
  718.                 if (LaunchBrowser(strNavigateURL))
  719.                 {
  720.                     // Save our state and quit the Screen Saver
  721.                     // if we successfully launched the browser.
  722.                     TraceMsg(TF_CLOSE, "Attempting to close screen saver");
  723.                     Quit(TRUE);
  724.                 }
  725.                 else
  726.                     MessageBeep(MB_ICONEXCLAMATION);
  727.             }
  728.             // Set the cancel flag to TRUE to disallow
  729.             // navigation in the Screen Saver itself.
  730.             ASSERT(pDispParams->rgvarg[PARAM_PROCESSED].vt == (VT_BYREF | VT_BOOL));
  731.             *(pDispParams->rgvarg[PARAM_PROCESSED].pboolVal) = VARIANT_TRUE;
  732.         }
  733.         hrResult = S_OK;
  734.         break;
  735.     }
  736.     return hrResult;
  737. }
  738. /////////////////////////////////////////////////////////////////////////////
  739. // CScreenSaverWindow::OnDocumentComplete
  740. /////////////////////////////////////////////////////////////////////////////
  741. HRESULT CScreenSaverWindow::OnDocumentComplete
  742. (
  743.     BSTR bstrURL
  744. )
  745. {
  746.     if (m_pHTMLDocument != NULL)
  747.     {
  748.         // Disconnect current connection to HTMLDocumentEvents
  749.         ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  750.                                     DIID_HTMLDocumentEvents,
  751.                                     FALSE,
  752.                                     m_pHTMLDocument,
  753.                                     &m_dwHTMLDocumentEvents,
  754.                                     NULL);
  755.         m_pHTMLDocument->Release();
  756.         m_pHTMLDocument = NULL;
  757.     }
  758.     // Connect to new document HTMLDocumentEvents connection
  759.     if  (
  760.         SUCCEEDED(m_pWebBrowser->get_Document(&m_pHTMLDocument))
  761.         &&
  762.         (m_pHTMLDocument != NULL)
  763.         )
  764.     {
  765.         ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  766.                                     DIID_HTMLDocumentEvents,
  767.                                     TRUE,
  768.                                     m_pHTMLDocument,
  769.                                     &m_dwHTMLDocumentEvents,
  770.                                     NULL);
  771.     }
  772.     else
  773.         TraceMsg(TF_NAVIGATION, "OnDocumentComplete: Unable to get_Document()!");
  774.     // Set the current URL property.
  775.     SUCCEEDED(m_pScreenSaver->put_CurrentURL(bstrURL));
  776. #ifdef _DEBUG
  777.     CString strURL = bstrURL;
  778.     TraceMsg(TF_NAVIGATION, "OnDocumentComplete: Current URL is "%s"", (LPCTSTR)strURL);
  779. #endif  // _DEBUG
  780.     // Hide the scrollbar and any other controls
  781.     ShowControls(FALSE);
  782.     // Start the channel change timer again.
  783.     ResetChangeTimer();
  784.     return S_OK;
  785. }
  786. /////////////////////////////////////////////////////////////////////////////
  787. // CScreenSaverWindow::OnTitleChange
  788. /////////////////////////////////////////////////////////////////////////////
  789. HRESULT CScreenSaverWindow::OnTitleChange
  790. (
  791.     BSTR bstrTitle
  792. )
  793. {
  794.     TraceMsg(TF_FUNCENTRY, "OnTitleChange()");
  795.     CString strTitle = bstrTitle;
  796.     SetWindowText(strTitle);
  797.     return S_OK;
  798. }
  799. /////////////////////////////////////////////////////////////////////////////
  800. // CScreenSaverWindow::CreateWebBrowser
  801. /////////////////////////////////////////////////////////////////////////////
  802. BOOL CScreenSaverWindow::CreateWebBrowser
  803. (
  804.     const RECT & rect
  805. )
  806. {
  807.     HRESULT hrResult;
  808.     ASSERT(m_hWnd);
  809.     for (;;)
  810.     {
  811.         CLSID clsidBrowser;
  812.         if  (
  813.             FAILED(CLSIDFromProgID(OLESTR("Shell.Explorer"), &clsidBrowser))
  814.             ||
  815.             FAILED(hrResult = CoCreateInstance( clsidBrowser,
  816.                                                 NULL,
  817.                                                 CLSCTX_INPROC_SERVER
  818.                                                     | CLSCTX_LOCAL_SERVER,
  819.                                                 IID_IUnknown,
  820.                                                 (void **)&m_pUnkBrowser))
  821.             )
  822.         {
  823.             TraceMsg(TF_ERROR, "Failed to create Web Browser object.");
  824.             break;
  825.         }
  826.         if (FAILED(hrResult = m_pUnkBrowser->QueryInterface(IID_IWebBrowser2,
  827.                                                             (void **)&m_pWebBrowser)))
  828.         {
  829.             TraceMsg(TF_ERROR, "Web browser doesn't support IWebBrowser2!");
  830.             break;
  831.         }
  832.         if  (
  833.             FAILED(hrResult = m_pUnkBrowser->QueryInterface(IID_IOleObject, (void **)&m_pOleObject))
  834.             ||
  835.             FAILED(hrResult = m_pOleObject->SetClientSite(SAFECAST(this, IOleClientSite *)))
  836.             )
  837.         {
  838.             TraceMsg(TF_ERROR, "Failure attempting to setup IOleObject!");
  839.             break;
  840.         }
  841.         IPersistStreamInit * pPersistStreamInit;
  842.         if (SUCCEEDED(hrResult = m_pOleObject->QueryInterface(IID_IPersistStreamInit, (void **)&pPersistStreamInit)))
  843.         {
  844.             pPersistStreamInit->InitNew();
  845.             pPersistStreamInit->Release();
  846.         }
  847.         OleSetContainedObject((IUnknown *)m_pOleObject, TRUE);
  848.         ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  849.                                     DIID_DWebBrowserEvents,
  850.                                     TRUE,
  851.                                     m_pUnkBrowser,
  852.                                     &m_dwWebBrowserEvents,
  853.                                     NULL);
  854.         ConnectToConnectionPoint(   SAFECAST(this, IDispatch *),
  855.                                     DIID_DWebBrowserEvents2,
  856.                                     TRUE,
  857.                                     m_pUnkBrowser,
  858.                                     &m_dwWebBrowserEvents2,
  859.                                     NULL);
  860.         // Make sure we are known as the browser
  861.         EVAL(SUCCEEDED(m_pWebBrowser->put_RegisterAsBrowser(VARIANT_TRUE)));
  862.         // We don't need to handle drops in the screen saver.
  863.         EVAL(SUCCEEDED(m_pWebBrowser->put_RegisterAsDropTarget(VARIANT_FALSE)));
  864.         // Make sure no dialogs are displayed for error conditions.
  865.         EVAL(SUCCEEDED(m_pWebBrowser->put_Silent(VARIANT_TRUE)));
  866.         // Make sure we get benefits of running theater mode.
  867.         // (in particular the flat scrollbar)
  868.         EVAL(SUCCEEDED(m_pWebBrowser->put_TheaterMode(VARIANT_TRUE)));
  869.         // Get the Target frame and don't allow,
  870.         // resizing, and turn off the 3D border.
  871.         ITargetEmbedding * pTargetEmbedding;
  872.         if (SUCCEEDED(hrResult = m_pUnkBrowser->QueryInterface( IID_ITargetEmbedding,
  873.                                                                 (void **)&pTargetEmbedding)))
  874.         {
  875.             ITargetFrame * pTargetFrame;
  876.             // Save the ITargetFrame interface pointer.
  877.             if (SUCCEEDED(hrResult = pTargetEmbedding->GetTargetFrame(&pTargetFrame)))
  878.             {
  879.                 DWORD dwFrameOpts;
  880.                 if (SUCCEEDED(pTargetFrame->GetFrameOptions(&dwFrameOpts)))
  881.                 {
  882.                     dwFrameOpts |= (FRAMEOPTIONS_NORESIZE
  883.                                         | FRAMEOPTIONS_NO3DBORDER);
  884.                     EVAL(SUCCEEDED(pTargetFrame->SetFrameOptions(dwFrameOpts)));
  885.                 }
  886.                 // Save the HLINK frame for navigation and setup purposes.
  887.                 hrResult = pTargetFrame->QueryInterface(IID_IHlinkFrame,
  888.                                                         (void **)&m_pHlinkFrame);
  889.                 pTargetFrame->Release();
  890.             }
  891.             pTargetEmbedding->Release();
  892.         }
  893.         if (FAILED(hrResult))
  894.         {
  895.             TraceMsg(TF_ERROR, "Error attempting to initialize TargetEmbedding.");
  896.             break;
  897.         }
  898.         // Make sure we are running in the current mode.
  899.         DWORD dwFlags;
  900.         VARIANT_BOOL bOffline = (InternetGetConnectedState(&dwFlags, 0)
  901.                                     ? VARIANT_FALSE
  902.                                     : VARIANT_TRUE);
  903. #ifdef _DEBUG
  904.         TraceMsg(TF_NAVIGATION, "Currently %s", ((bOffline == VARIANT_TRUE)
  905.                                                     ? TEXT("OFFLINE")
  906.                                                     : TEXT("ONLINE")));
  907. #endif  // _DEBUG
  908.         EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(bOffline)));
  909.         m_pBindStatusCallback = new CSSNavigateBSC( SAFECAST(this, CScreenSaverWindow *),
  910.                                                     TIME_NAVIGATE_TIMEOUT);
  911.         if (NULL == m_pBindStatusCallback)
  912.         {
  913.             hrResult = E_OUTOFMEMORY;
  914.             break;
  915.         }
  916.         // Display the Web Browser OC.
  917.         ShowWindow(SW_SHOWNORMAL);
  918.         m_pOleObject->DoVerb(   OLEIVERB_SHOW,
  919.                                 NULL,
  920.                                 SAFECAST(this, IOleClientSite *),
  921.                                 0,
  922.                                 m_hWnd,
  923.                                 &rect);
  924.         break;
  925.     }
  926.     return SUCCEEDED(hrResult);
  927. }
  928. /////////////////////////////////////////////////////////////////////////////
  929. // CScreenSaverWindow::GetHTMLBodyElement
  930. /////////////////////////////////////////////////////////////////////////////
  931. HRESULT CScreenSaverWindow::GetHTMLBodyElement
  932. (
  933.     IHTMLBodyElement ** ppHTMLBodyElement
  934. )
  935. {
  936.     IDispatch *         pDispatch = NULL;
  937.     IHTMLDocument2 *    pHTMLDocument = NULL;
  938.     IHTMLElement *      pHTMLElement = NULL;
  939.     HRESULT             hrResult;
  940.     for (;;)
  941.     {
  942.         *ppHTMLBodyElement = NULL;
  943.         if  (
  944.             FAILED(m_pWebBrowser->get_Document(&pDispatch))
  945.             ||
  946.             (pDispatch == NULL)
  947.             )
  948.         {
  949.             hrResult = E_FAIL;
  950.             break;
  951.         }
  952.         if (FAILED(hrResult = pDispatch->QueryInterface( IID_IHTMLDocument2,
  953.                                                          (void **)&pHTMLDocument)))
  954.         {
  955.             break;
  956.         }
  957.         if  (
  958.             SUCCEEDED(hrResult = pHTMLDocument->get_body(&pHTMLElement))
  959.             &&
  960.             (pHTMLElement != NULL)
  961.             )
  962.         {
  963.             hrResult = pHTMLElement->QueryInterface(IID_IHTMLBodyElement,
  964.                                                     (void **)ppHTMLBodyElement);
  965.         }
  966.         break;
  967.     }
  968.     if (pHTMLElement != NULL)
  969.         pHTMLElement->Release();
  970.     if (pHTMLDocument != NULL)
  971.         pHTMLDocument->Release();
  972.     if (pDispatch != NULL)
  973.         pDispatch->Release();
  974.     return hrResult;
  975. }
  976. /////////////////////////////////////////////////////////////////////////////
  977. // CScreenSaverWindow::DisplayCurrentChannel
  978. /////////////////////////////////////////////////////////////////////////////
  979. HRESULT CScreenSaverWindow::DisplayCurrentChannel
  980. (
  981. )
  982. {
  983.     HRESULT hrResult;
  984.     if (m_lCurrChannel == CURRENT_CHANNEL_NONE)
  985.         hrResult = DisplayNextChannel();
  986.     else
  987.     {
  988.         if (FAILED(hrResult = DisplayChannel(m_lCurrChannel)))
  989.         {
  990.             TraceMsg(TF_NAVIGATION, "Unable to display channel, trying next one.");
  991.             hrResult = DisplayNextChannel();
  992.         }
  993.     }
  994.     // If everything blows up, show the default page.
  995.     if (FAILED(hrResult))
  996.     {
  997.         TraceMsg(TF_NAVIGATION, "No channels are able to display. Using default.");
  998.         hrResult = NavigateToDefault();
  999.     }
  1000.     return hrResult;
  1001. }
  1002. /////////////////////////////////////////////////////////////////////////////
  1003. // CScreenSaverWindow::DisplayNextChannel
  1004. /////////////////////////////////////////////////////////////////////////////
  1005. HRESULT CScreenSaverWindow::DisplayNextChannel
  1006. (
  1007. )
  1008. {
  1009.     long    lStartChannel = m_lCurrChannel;
  1010.     long    lNextChannel = m_lCurrChannel;
  1011.     HRESULT hrResult;
  1012.     for (;;)
  1013.     {
  1014.         lNextChannel = FindNextChannel(lNextChannel);
  1015.         // Bail if we have gone all the way around the list.
  1016.         if (lNextChannel == lStartChannel)
  1017.         {
  1018.             TraceMsg(TF_NAVIGATION, "No new channel available...Continuing current channel.");
  1019.             hrResult = E_FAIL;
  1020.             break;
  1021.         }
  1022.         if (lNextChannel == CURRENT_CHANNEL_NONE)
  1023.             continue;
  1024.         // Continue until we loop around or have navigated successfully.
  1025.         if (SUCCEEDED(hrResult = DisplayChannel(lNextChannel)))
  1026.             break;
  1027.     }
  1028.     return hrResult;
  1029. }
  1030. /////////////////////////////////////////////////////////////////////////////
  1031. // CScreenSaverWindow::DisplayChannel
  1032. /////////////////////////////////////////////////////////////////////////////
  1033. HRESULT CScreenSaverWindow::DisplayChannel
  1034. (
  1035.     long lChannel
  1036. )
  1037. {
  1038.     LPITEMIDLIST pidlChannel = m_pPIDLList->Item(lChannel);
  1039.     ASSERT(pidlChannel != NULL);
  1040.     m_bMouseClicked = FALSE;
  1041.     HRESULT hrResult = NavigateToPIDL(pidlChannel);
  1042.     m_lCurrChannel = lChannel;
  1043.     return hrResult;
  1044. }
  1045. /////////////////////////////////////////////////////////////////////////////
  1046. // CScreenSaverWindow::NavigateToPIDL
  1047. /////////////////////////////////////////////////////////////////////////////
  1048. HRESULT CScreenSaverWindow::NavigateToPIDL
  1049. (
  1050.     LPITEMIDLIST pidl
  1051. )
  1052. {
  1053.     HRESULT hrResult = E_FAIL;
  1054.     for (;;)
  1055.     {
  1056.         CString strURL;
  1057.         TCHAR * pszURL = strURL.GetBuffer(INTERNET_MAX_URL_LENGTH);
  1058.         BOOL bResult = GetPIDLDisplayName(  NULL,
  1059.                                             pidl,
  1060.                                             pszURL,
  1061.                                             INTERNET_MAX_URL_LENGTH,
  1062.                                             SHGDN_FORPARSING);
  1063.         strURL.ReleaseBuffer();
  1064.         if (!bResult)
  1065.             break;
  1066.         BSTR bstrURL;
  1067.         if ((bstrURL = strURL.AllocSysString()) != NULL)
  1068.         {
  1069.             EVAL(SUCCEEDED(hrResult = NavigateToBSTR(bstrURL)));
  1070.             SysFreeString(bstrURL);
  1071.         }
  1072.         break;
  1073.     }
  1074.     return hrResult;
  1075. }
  1076. /////////////////////////////////////////////////////////////////////////////
  1077. // CScreenSaverWindow::NavigateToBSTR
  1078. /////////////////////////////////////////////////////////////////////////////
  1079. HRESULT CScreenSaverWindow::NavigateToBSTR
  1080. (
  1081.     BSTR bstrURL
  1082. )
  1083. {
  1084.     IMoniker *  pURLMoniker = NULL;
  1085.     IBindCtx *  pBindCtx = NULL;
  1086.     IHlink *    pHlink = NULL;
  1087.     HRESULT     hrResult;
  1088.     for (;;)
  1089.     {
  1090.         if (bstrURL == NULL)
  1091.         {
  1092.             hrResult = E_INVALIDARG;
  1093.             break;
  1094.         }
  1095.         DWORD dwFeatureFlags;
  1096.         EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  1097.         if (dwFeatureFlags & FEATURE_USE_CACHED_CONTENT_FIRST)
  1098.         {
  1099.             if (FAILED(hrResult = SetConnectedState(bstrURL)))
  1100.                 break;
  1101.         }
  1102.         else
  1103.         {
  1104.             if (FAILED(hrResult = IsURLAvailable(bstrURL)))
  1105.                 break;
  1106.         }
  1107.         if  (
  1108.             FAILED(hrResult = CreateURLMoniker(NULL, bstrURL, &pURLMoniker))
  1109.             ||
  1110.             FAILED(hrResult = CreateBindCtx(0, &pBindCtx))
  1111.             ||
  1112.             FAILED(hrResult = HlinkCreateFromMoniker(   pURLMoniker,
  1113.                                                         NULL,
  1114.                                                         NULL,
  1115.                                                         NULL,
  1116.                                                         0,
  1117.                                                         NULL,
  1118.                                                         IID_IHlink,
  1119.                                                         (void **)&pHlink))
  1120.             ||
  1121.             FAILED(hrResult = m_pHlinkFrame->Navigate(  HLNF_CREATENOHISTORY,
  1122.                                                         pBindCtx,
  1123.                                                         SAFECAST(m_pBindStatusCallback, IBindStatusCallback *),
  1124.                                                         pHlink))
  1125.             )
  1126.         {
  1127.             break;
  1128.         }
  1129. #ifdef _DEBUG
  1130.         VARIANT_BOOL bOffline;
  1131.         EVAL(SUCCEEDED(m_pWebBrowser->get_Offline(&bOffline)));
  1132.         CString strURL = bstrURL;
  1133.         TraceMsg(TF_NAVIGATION, "%s: Started navigation to '%s'", (bOffline ? TEXT("OFFLINE") : TEXT("ONLINE")), (LPCTSTR)strURL);
  1134. #endif  // _DEBUG
  1135.         break;
  1136.     }
  1137.     // Cleanup
  1138.     if (pHlink != NULL)
  1139.         pHlink->Release();
  1140.     if (pBindCtx != NULL)
  1141.         pBindCtx->Release();
  1142.     if (pURLMoniker != NULL)
  1143.         pURLMoniker->Release();
  1144.     return hrResult;
  1145. }
  1146. /////////////////////////////////////////////////////////////////////////////
  1147. // CScreenSaverWindow::NavigateToDefault
  1148. /////////////////////////////////////////////////////////////////////////////
  1149. HRESULT CScreenSaverWindow::NavigateToDefault
  1150. (
  1151. )
  1152. {
  1153.     HRESULT hrResult = E_FAIL;
  1154.     for (;;)
  1155.     {
  1156.         BSTR bstrCurrentURL;
  1157.         if  (
  1158.             FAILED(m_pScreenSaver->get_CurrentURL(&bstrCurrentURL))
  1159.             ||
  1160.             (bstrCurrentURL == NULL)
  1161.             )
  1162.         {
  1163.             break;
  1164.         }
  1165.         CString strDefaultURL;
  1166.         TCHAR * pszURL = strDefaultURL.GetBuffer(INTERNET_MAX_URL_LENGTH);
  1167.         EVAL(GetPIDLDisplayName(NULL, m_pidlDefault, pszURL, INTERNET_MAX_URL_LENGTH, SHGDN_FORPARSING));
  1168.         strDefaultURL.ReleaseBuffer();
  1169.         CString strCurrentURL = bstrCurrentURL;
  1170.         if (StrCmpI(strCurrentURL, strDefaultURL) == 0)
  1171.         {
  1172.             ResetChangeTimer();
  1173.             hrResult = S_OK;
  1174.         }
  1175.         SysFreeString(bstrCurrentURL);
  1176.         break;
  1177.     }
  1178.     if (FAILED(hrResult))
  1179.         hrResult = NavigateToPIDL(m_pidlDefault);
  1180.     return hrResult;
  1181. }
  1182. /////////////////////////////////////////////////////////////////////////////
  1183. // CScreenSaverWindow::SetConnectedState
  1184. /////////////////////////////////////////////////////////////////////////////
  1185. HRESULT CScreenSaverWindow::SetConnectedState
  1186. (
  1187.     BSTR bstrURL
  1188. )
  1189. {
  1190.     if (bstrURL == NULL)
  1191.         return E_INVALIDARG;
  1192.     CString strURL = bstrURL;
  1193.     if ((LPTSTR)strURL == NULL)
  1194.         return E_OUTOFMEMORY;
  1195.     // Check for 'res://' URL
  1196.     BOOL bResURL = (StrCmpNI(strURL, s_szRES, lstrlen(s_szRES)) == 0);
  1197.     long lMode;
  1198.     EVAL(SUCCEEDED(m_pScreenSaver->get_Mode(&lMode)));
  1199.     HRESULT hrResult;
  1200.     // Check the cache for the URL first. Assume /u URLs want to hit the net.
  1201.     if  (
  1202.         (lMode != SSMODE_SINGLEURL)
  1203.         &&
  1204.         // Ignore cache check for 'res://' URLs
  1205.         !bResURL
  1206.         &&
  1207.         GetUrlCacheEntryInfoEx(strURL, NULL, NULL, NULL, NULL, NULL, 0)
  1208.         )
  1209.     {
  1210.         // Go offline and use cache content.
  1211.         TraceMsg(TF_NAVIGATION, "Going offline");
  1212.         EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_TRUE)));
  1213.         hrResult = S_OK;
  1214.     }
  1215.     else
  1216.     {
  1217.         DWORD dwConnectState;
  1218.         // Try the internet if we have a direct connection. Ignore dialup.
  1219.         if  (
  1220.             InternetGetConnectedState(&dwConnectState, 0)
  1221.             &&
  1222.             (
  1223.                 (dwConnectState & INTERNET_CONNECTION_LAN)
  1224.                 ||
  1225.                 (dwConnectState & INTERNET_CONNECTION_PROXY)
  1226.             )
  1227.             )
  1228.         {
  1229.             if (!bResURL)
  1230.             {
  1231.                 TraceMsg(   TF_NAVIGATION,
  1232.                             "Content for '%s' not in cache! Going online",
  1233.                             (LPCTSTR)strURL);
  1234.                 EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_FALSE)));
  1235.             }
  1236.             else
  1237.             {
  1238.                 TraceMsg(TF_NAVIGATION, "Going offline for res:// URL");
  1239.                 // Go offline for res:// URLs they should be local.
  1240.                 EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_TRUE)));
  1241.             }
  1242.             hrResult = S_OK;
  1243.         }
  1244.         else
  1245.             hrResult = E_FAIL;
  1246.     }
  1247.     return hrResult;
  1248. }
  1249. /////////////////////////////////////////////////////////////////////////////
  1250. // CScreenSaverWindow::IsURLAvailable
  1251. /////////////////////////////////////////////////////////////////////////////
  1252. HRESULT CScreenSaverWindow::IsURLAvailable
  1253. (
  1254.     BSTR bstrURL
  1255. )
  1256. {
  1257.     if (bstrURL == NULL)
  1258.         return E_INVALIDARG;
  1259.     CString strURL = bstrURL;
  1260.     if ((LPTSTR)strURL == NULL)
  1261.         return E_OUTOFMEMORY;
  1262.     HRESULT hrResult = S_OK;
  1263.     for (;;)
  1264.     {
  1265.         // Ignore cache check for 'res://' URLs
  1266.         if (StrCmpNI(strURL, s_szRES, lstrlen(s_szRES)) == 0)
  1267.             break;
  1268.         
  1269.         long lMode;
  1270.         EVAL(SUCCEEDED(m_pScreenSaver->get_Mode(&lMode)));
  1271.         DWORD dwConnectState;
  1272.               
  1273.         if  (
  1274.             // Assume /u URLs want to hit the net.
  1275.             (lMode == SSMODE_SINGLEURL)
  1276.             ||
  1277.             // If we are online it should be available, too.
  1278.             InternetGetConnectedState(&dwConnectState, 0)
  1279.             )
  1280.         {
  1281.             TraceMsg(TF_NAVIGATION, "Going ONLINE for internet content");
  1282.             EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_FALSE)));
  1283.             break;
  1284.         }
  1285.         // Check the cache for the URL if it is there, go offline.
  1286.         if (GetUrlCacheEntryInfoEx(strURL, NULL, NULL, NULL, NULL, NULL, 0))
  1287.         {
  1288.             TraceMsg(TF_NAVIGATION, "Going OFFLINE for cached content");
  1289.             EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_TRUE)));
  1290.             break;
  1291.         }
  1292.         hrResult = E_FAIL;
  1293.         break;
  1294.     }
  1295.     return hrResult;
  1296. }
  1297. /////////////////////////////////////////////////////////////////////////////
  1298. // CScreenSaverWindow::ResetChangeTimer
  1299. /////////////////////////////////////////////////////////////////////////////
  1300. void CScreenSaverWindow::ResetChangeTimer
  1301. (
  1302.     BOOL bExtendedTime
  1303. )
  1304. {
  1305.     if (m_idChangeTimer != 0)
  1306.     {
  1307.         EVAL(KillTimer(m_idChangeTimer));
  1308.         m_idChangeTimer = 0;
  1309.     }
  1310.     int iChannelTime;
  1311.     EVAL(SUCCEEDED(m_pSSConfig->get_ChannelTime(&iChannelTime)));
  1312.     EVAL((m_idChangeTimer = SetTimer(   ID_CHANNELCHANGE_TIMER,
  1313.                                         (iChannelTime * 1000)
  1314.                                             + (bExtendedTime ? TIME_NAVIGATE_TIMEOUT : 0),
  1315.                                         NULL)) != 0);
  1316. }
  1317. /////////////////////////////////////////////////////////////////////////////
  1318. // CScreenSaverWindow::FindNextChannel
  1319. /////////////////////////////////////////////////////////////////////////////
  1320. long CScreenSaverWindow::FindNextChannel
  1321. (
  1322.     long lChannelStart
  1323. )
  1324. {
  1325.     if (m_pPIDLList->Count() > 0)
  1326.     {
  1327.         if (lChannelStart == CURRENT_CHANNEL_NONE)
  1328.             lChannelStart = 0;
  1329.         else
  1330.         {
  1331.             lChannelStart++;
  1332.             if (lChannelStart >= m_pPIDLList->Count())
  1333.                 lChannelStart = CURRENT_CHANNEL_NONE;
  1334.         }
  1335.     }
  1336.     return lChannelStart;
  1337. }
  1338. /////////////////////////////////////////////////////////////////////////////
  1339. // CScreenSaverWindow::LaunchBrowser
  1340. /////////////////////////////////////////////////////////////////////////////
  1341. BOOL CScreenSaverWindow::LaunchBrowser
  1342. (
  1343.     CString & strURL
  1344. )
  1345. {
  1346.     BOOL bResult = FALSE;
  1347.     for (;;)
  1348.     {
  1349.         PARSEDURL pu = { 0 };
  1350.         pu.cbSize = sizeof(PARSEDURL);
  1351.         if (FAILED(ParseURL(strURL, &pu)))
  1352.             break;
  1353.         if  (
  1354.             (pu.nScheme == URL_SCHEME_INVALID)
  1355.             ||
  1356.             (pu.nScheme == URL_SCHEME_UNKNOWN)
  1357.             ||
  1358.             (pu.nScheme == URL_SCHEME_VBSCRIPT)
  1359.             ||
  1360.             (pu.nScheme == URL_SCHEME_JAVASCRIPT)
  1361.             )
  1362.         {
  1363.             // Don't allow navigation to scripts.
  1364.             // They may need page context.
  1365.             TraceMsg(TF_NAVIGATION, "Ignoring %s -- Can't launch", (LPCTSTR)strURL);
  1366.             break;
  1367.         }
  1368.         //
  1369.         // If we are running on NT and password protection is enabled then
  1370.         // we disable launching browsers. This is because there is no way
  1371.         // to detect on the other side that the password verification succeeded
  1372.         //
  1373.         if (g_bPlatformNT && g_bPasswordEnabled)
  1374.         {
  1375.             bResult = TRUE;
  1376.             break;
  1377.         }
  1378.         if (pu.nScheme == URL_SCHEME_FILE)
  1379.         {
  1380.             // Make sure that URL is completely escaped.
  1381.             char * szURL = strURL.GetBuffer(INTERNET_MAX_URL_LENGTH);
  1382.             DWORD cchSize = INTERNET_MAX_URL_LENGTH;
  1383.             UrlEscape(szURL, szURL, &cchSize, 0);
  1384.             strURL.ReleaseBuffer();
  1385.         } 
  1386.         if (g_bPlatformNT)
  1387.         {
  1388.             // Write URL to registry and trigger event.
  1389.             WriteRegValue(  HKEY_CURRENT_USER,
  1390.                             g_szRegSubKey,
  1391.                             s_szRegLastNavURL,
  1392.                             REG_SZ,
  1393.                             (LPBYTE)(char *)strURL,
  1394.                             strURL.GetLength());
  1395.             HANDLE hTermEvent;
  1396.             if ((hTermEvent = OpenEvent(EVENT_MODIFY_STATE,
  1397.                                         FALSE,
  1398.                                         s_szSETermEvent)) != NULL)
  1399.             {
  1400.                 bResult = SetEvent(hTermEvent);
  1401.                 CloseHandle(hTermEvent);
  1402.             }
  1403.         }
  1404.         else
  1405.         {
  1406.             BSTR bstrURL = strURL.AllocSysString();
  1407.             if (bstrURL != NULL)
  1408.             {
  1409.                 bResult = SUCCEEDED(HlinkNavigateString(NULL, bstrURL));
  1410.                 SysFreeString(bstrURL);
  1411.             }
  1412.         }
  1413.         break;
  1414.     }
  1415.     return bResult;
  1416. }
  1417. /////////////////////////////////////////////////////////////////////////////
  1418. // CScreenSaverWindow::UserIsInteractive
  1419. /////////////////////////////////////////////////////////////////////////////
  1420. BOOL CScreenSaverWindow::UserIsInteractive
  1421. (
  1422. )
  1423. {
  1424.     if (g_bPlatformNT)
  1425.         return TRUE;
  1426.     // REVIEW: This is a big hack. We need to
  1427.     // find a better way to do this [jaym]
  1428.     HWND hwndCurr = ::GetWindow(m_hWnd, GW_HWNDFIRST);
  1429.     while (hwndCurr != NULL)
  1430.     {
  1431.         if (::GetWindowTextLength(hwndCurr) > 0)
  1432.         {
  1433.             TCHAR szWindowText[40];
  1434.             ::GetWindowText(hwndCurr, szWindowText, ARRAYSIZE(szWindowText));
  1435.             TraceMsg(TF_ALWAYS, "Window '%s'", szWindowText);
  1436.             if (StrCmpI(szWindowText, TEXT("DDE Server Window")) == 0)
  1437.                 return TRUE;
  1438.         }
  1439.         hwndCurr = ::GetWindow(hwndCurr, GW_HWNDNEXT);
  1440.     }
  1441.     TraceMsg(TF_ALWAYS, "USER IS NOT INTERACTIVE!");
  1442.     return FALSE;
  1443. }
  1444. /////////////////////////////////////////////////////////////////////////////
  1445. // CScreenSaverWindow::OnChannelChangeTimer
  1446. /////////////////////////////////////////////////////////////////////////////
  1447. void CScreenSaverWindow::OnChannelChangeTimer
  1448. (
  1449. )
  1450. {
  1451.     ASSERT(m_idChangeTimer != 0);
  1452.     EVAL(KillTimer(m_idChangeTimer));
  1453.     m_idChangeTimer = 0;
  1454.     if (FAILED(DisplayNextChannel()))
  1455.         ResetChangeTimer();
  1456.     else
  1457.     {
  1458.         // Just in case we don't get OnDocumentComplete()...
  1459.         ResetChangeTimer(TRUE);
  1460.     }
  1461. }
  1462. /////////////////////////////////////////////////////////////////////////////
  1463. // CScreenSaverWindow::VerifyPassword
  1464. /////////////////////////////////////////////////////////////////////////////
  1465. BOOL CScreenSaverWindow::VerifyPassword
  1466. (
  1467. )
  1468. {
  1469.     BOOL fOK = FALSE;
  1470.     //  Check to see if we are already in here.  If m_lVerifyingPassword
  1471.     //  is zero on entry then it will be set to 1 and the return from
  1472.     //  InterlockedExchange will be 0.  When we are done we call
  1473.     //  InterlockedExchange to reset the value to 0.
  1474.     if (InterlockedExchange(&m_lVerifingPassword, TRUE) == FALSE)
  1475.     {
  1476.         EnableModeless(FALSE);
  1477.         if (g_bPlatformNT)
  1478.         {
  1479.             // REVIEW: Verify password for NT users. Or, alternatively
  1480.             // figure out how to lock the workstation before the screensaver
  1481.             // activates.
  1482.             // LogonUser
  1483.             fOK = TRUE;
  1484.         }
  1485.         else
  1486.         {
  1487.             // Also disable the browser window
  1488.             HWND hBrowserWnd = NULL;
  1489.             ASSERT(m_pWebBrowser);
  1490.             if(m_pWebBrowser)
  1491.             {
  1492.                 IOleWindow *pOleWindow = NULL;
  1493.                 if(SUCCEEDED(m_pWebBrowser->QueryInterface(IID_IOleWindow, (void**)&pOleWindow)))
  1494.                 {
  1495.                     ASSERT(pOleWindow);
  1496.                     pOleWindow->GetWindow(&hBrowserWnd);
  1497.                     pOleWindow->Release();
  1498.                 }
  1499.             }
  1500.             if (m_pfnVerifyPassword != NULL)
  1501.                 fOK = m_pfnVerifyPassword(hBrowserWnd ? hBrowserWnd : m_hWnd);
  1502.             else
  1503.             {
  1504.                 // Passwords disabled or unable to load
  1505.                 // handler DLL always allow exit.
  1506.                 fOK = TRUE;
  1507.             }
  1508.         }
  1509.         EnableModeless(TRUE);
  1510.         InterlockedExchange(&m_lVerifingPassword, FALSE);
  1511.     }
  1512.     return fOK;
  1513. }
  1514. /////////////////////////////////////////////////////////////////////////////
  1515. // CScreenSaverWindow::InitChannelList
  1516. /////////////////////////////////////////////////////////////////////////////
  1517. void CScreenSaverWindow::InitChannelList
  1518. (
  1519. )
  1520. {
  1521.     if (m_pPIDLList == NULL)
  1522.         m_pPIDLList = new CPIDLList;
  1523.     if (m_pPIDLList == NULL)
  1524.         return;
  1525.     if (UserIsInteractive())
  1526.     {
  1527.         long lMode;
  1528.         EVAL(SUCCEEDED(m_pScreenSaver->get_Mode(&lMode)));
  1529.         if (lMode == SSMODE_SINGLEURL)
  1530.         {
  1531.             BSTR bstrURL;
  1532.             if  (
  1533.                 SUCCEEDED(m_pScreenSaver->get_CurrentURL(&bstrURL))
  1534.                 &&
  1535.                 (bstrURL != NULL)
  1536.                 &&
  1537.                 (SysStringLen(bstrURL) != 0)
  1538.                 )
  1539.             {
  1540.                 CString strURL = bstrURL;
  1541.                 m_pPIDLList->Add(strURL);
  1542.             }
  1543.             SysFreeString(bstrURL);
  1544.         }
  1545.         else
  1546.         {
  1547.             DWORD dwFeatureFlags;
  1548.             EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  1549.             m_pPIDLList->Build(m_pSSConfig, (dwFeatureFlags & FEATURE_USE_CDF_TOPLEVEL_URL));
  1550.         }
  1551.     }
  1552.     else
  1553.         TraceMsg(TF_WARNING, "USER IS NOT LOGGED ON!");
  1554.     // If there are no current Screen Saver channels, show the
  1555.     // info. HTML message about setting up Screen Saver channels.
  1556.     if (m_pPIDLList->Count() == 0)
  1557.     {
  1558.         TraceMsg(TF_NAVIGATION, "No URLs in list -- adding default HTML");
  1559.         EVAL(m_pPIDLList->Add(CopyPIDL(m_pidlDefault)));
  1560.     }
  1561.     else
  1562.     {
  1563.         ASSERT(m_pPIDLList->Count() > 0);
  1564.         LoadState();
  1565.     }
  1566.     TraceMsg(TF_NAVIGATION, "%d URLs in list", m_pPIDLList->Count());
  1567. }
  1568. /////////////////////////////////////////////////////////////////////////////
  1569. // CScreenSaverWindow::LoadState
  1570. /////////////////////////////////////////////////////////////////////////////
  1571. void CScreenSaverWindow::LoadState
  1572. (
  1573. )
  1574. {
  1575.     CString strLastURL;
  1576.     ASSERT(m_pPIDLList != NULL);
  1577.     if (m_pPIDLList->Count() > 0)
  1578.     {
  1579.         char * pszLastURL = strLastURL.GetBuffer(INTERNET_MAX_URL_LENGTH);
  1580.         ReadRegString(  HKEY_CURRENT_USER,
  1581.                         g_szRegSubKey,
  1582.                         s_szRegLastURL,
  1583.                         TEXT(""),
  1584.                         pszLastURL,
  1585.                         INTERNET_MAX_URL_LENGTH);
  1586.         strLastURL.ReleaseBuffer();
  1587.         if (strLastURL.GetLength() > 0)
  1588.         {
  1589.             LPITEMIDLIST pidl;
  1590.             if (CreatePIDLFromPath(strLastURL, &pidl) && pidl)
  1591.             {
  1592.                 m_lCurrChannel = m_pPIDLList->Find(pidl);
  1593.                 g_pMalloc->Free(pidl);
  1594.             }
  1595.         }
  1596.     }
  1597. }
  1598. /////////////////////////////////////////////////////////////////////////////
  1599. // CScreenSaverWindow::SaveState
  1600. /////////////////////////////////////////////////////////////////////////////
  1601. void CScreenSaverWindow::SaveState
  1602. (
  1603. )
  1604. {
  1605.     CString strLastURL;
  1606.     // Save the current URL being displayed.    
  1607.     if  (
  1608.         (m_pPIDLList != NULL)
  1609.         &&
  1610.         (m_lCurrChannel != CURRENT_CHANNEL_NONE)
  1611.         )
  1612.     {
  1613.         LPITEMIDLIST pidl = m_pPIDLList->Item(m_lCurrChannel);
  1614.         char * pszLastURL = strLastURL.GetBuffer(INTERNET_MAX_URL_LENGTH);
  1615.         EVAL(GetPIDLDisplayName(NULL,
  1616.                                 pidl,
  1617.                                 pszLastURL,
  1618.                                 INTERNET_MAX_URL_LENGTH,
  1619.                                 SHGDN_FORPARSING));
  1620.         strLastURL.ReleaseBuffer();
  1621.     }
  1622.     WriteRegValue(  HKEY_CURRENT_USER,
  1623.                     g_szRegSubKey,
  1624.                     s_szRegLastURL,
  1625.                     REG_SZ,
  1626.                     (LPBYTE)(char *)strLastURL,
  1627.                     strLastURL.GetLength());
  1628. }
  1629. /////////////////////////////////////////////////////////////////////////////
  1630. // CScreenSaverWindow::LoadPasswordDLL
  1631. /////////////////////////////////////////////////////////////////////////////
  1632. void CScreenSaverWindow::LoadPasswordDLL
  1633. (
  1634. )
  1635. {
  1636.     if (m_hPasswordDLL != NULL)
  1637.         UnloadPasswordDLL();
  1638.     // Look to see if password turned on, otherwise
  1639.     // don't bother to load password handler DLL.
  1640.     if (g_bPasswordEnabled)
  1641.     {
  1642.         // Try to load the DLL that contains password proc.
  1643.         if ((m_hPasswordDLL = LoadLibrary(s_szPasswordDLL)) != NULL)
  1644.         {
  1645.             m_pfnVerifyPassword =
  1646.                 (VERIFYPWDPROC)GetProcAddress(  m_hPasswordDLL,
  1647.                                                 s_szPasswordFnName);
  1648.             if (m_pfnVerifyPassword == NULL)
  1649.                 UnloadPasswordDLL();
  1650.         }
  1651.     }
  1652. }
  1653. /////////////////////////////////////////////////////////////////////////////
  1654. // CScreenSaverWindow::UnloadPasswordDLL
  1655. /////////////////////////////////////////////////////////////////////////////
  1656. void CScreenSaverWindow::UnloadPasswordDLL
  1657. (
  1658. )
  1659. {
  1660.     if (m_hPasswordDLL != NULL)
  1661.     {
  1662.         FreeLibrary(m_hPasswordDLL);
  1663.         m_hPasswordDLL = NULL;
  1664.         m_pfnVerifyPassword = NULL;
  1665.     }
  1666. }
  1667. /////////////////////////////////////////////////////////////////////////////
  1668. // CScreenSaverWindow::SetHooks
  1669. /////////////////////////////////////////////////////////////////////////////
  1670. void CScreenSaverWindow::SetHooks
  1671. (
  1672. )
  1673. {
  1674.     ASSERT(s_hKeyboardHook == NULL);
  1675.     ASSERT(s_hMouseHook == NULL);
  1676.     s_hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD,
  1677.                                         KeyboardHookProc,
  1678.                                         _pModule->GetModuleInstance(),
  1679.                                         GetCurrentThreadId());
  1680.     s_hMouseHook = SetWindowsHookEx(    WH_MOUSE,
  1681.                                         MouseHookProc,
  1682.                                         _pModule->GetModuleInstance(),
  1683.                                         GetCurrentThreadId());
  1684.     ASSERT(s_hKeyboardHook != NULL);
  1685.     ASSERT(s_hMouseHook != NULL);
  1686. }
  1687. /////////////////////////////////////////////////////////////////////////////
  1688. // KeyboardHookProc
  1689. /////////////////////////////////////////////////////////////////////////////
  1690. LRESULT CALLBACK KeyboardHookProc
  1691. (
  1692.     int     nCode,
  1693.     WPARAM  wParam,
  1694.     LPARAM  lParam
  1695. )
  1696. {
  1697.     if  (
  1698.         (nCode != HC_NOREMOVE)
  1699.         &&
  1700.         (s_pThis->ModelessEnabled())
  1701.         )
  1702.     {
  1703.         // Make sure the user is keyboarding in the Screen Saver.
  1704.         if  (s_pThis->m_hWnd != GetForegroundWindow())
  1705.         {
  1706.             // Ignore
  1707.             ;
  1708.         }
  1709.         else
  1710.         {
  1711.             switch (wParam)
  1712.             {
  1713.                 // Ignore if the user is pressing ALT
  1714.                 case VK_MENU:
  1715.                 // Ignore IMM messages (just in case!)
  1716.                 case VK_PROCESSKEY:
  1717.                     break;
  1718.                 // Check for scrolling
  1719.                 case VK_PRIOR:
  1720.                 case VK_NEXT:
  1721.                 case VK_END:
  1722.                 case VK_HOME:
  1723.                 case VK_LEFT:
  1724.                 case VK_UP:
  1725.                 case VK_RIGHT:
  1726.                 case VK_DOWN:
  1727.                 {
  1728.                     static BOOL bUp = TRUE;
  1729.                     if (bUp)
  1730.                         s_pThis->ShowControls(TRUE);
  1731.                     bUp = !bUp;
  1732.                     break;
  1733.                 }
  1734.                 // Hotkey to go to next channel.
  1735.                 case VK_ADD:
  1736.                 {
  1737.                     s_pThis->OnChannelChangeTimer();
  1738.                     break;
  1739.                 }
  1740.                 default:
  1741.                 {
  1742.                     // Ignore F-keys for easier debugging.
  1743.                     if ((wParam >= VK_F1) && (wParam <= VK_F12))
  1744.                     {
  1745.                         DWORD dwFeatureFlags;
  1746.                         s_pThis->GetFeatures(&dwFeatureFlags);
  1747.                         if (dwFeatureFlags & FEATURE_IGNORE_FKEYS)
  1748.                             break;
  1749.                     }
  1750.                     s_pThis->Quit();
  1751.                     break;
  1752.                 }
  1753.             }
  1754.         }
  1755.     }
  1756.     return CallNextHookEx(s_hKeyboardHook, nCode, wParam, lParam);
  1757. }
  1758. /////////////////////////////////////////////////////////////////////////////
  1759. // MouseHookProc
  1760. /////////////////////////////////////////////////////////////////////////////
  1761. LRESULT CALLBACK MouseHookProc
  1762. (
  1763.     int     nCode,
  1764.     WPARAM  wParam,
  1765.     LPARAM  lParam
  1766. )
  1767. {
  1768.     if  (
  1769.         (nCode != HC_NOREMOVE)
  1770.         &&
  1771.         (s_pThis->ModelessEnabled())
  1772.         &&
  1773.         // Make sure the user is mousing in the Screen Saver window.
  1774.         (s_pThis->m_hWnd == GetForegroundWindow())
  1775.     )
  1776.     {
  1777.         switch (wParam)
  1778.         {
  1779.             case WM_NCRBUTTONDOWN:
  1780.             case WM_RBUTTONDOWN:
  1781.             case WM_NCMBUTTONDOWN:
  1782.             case WM_MBUTTONDOWN:
  1783.             {
  1784.                 DWORD dwFeatureFlags;
  1785.                 s_pThis->GetFeatures(&dwFeatureFlags);
  1786.                 if (!(dwFeatureFlags & FEATURE_IGNORE_MOUSE_CLICKS))
  1787.                     s_pThis->Quit();
  1788.                 break;
  1789.             }
  1790.             case WM_MOUSEMOVE:
  1791.             {
  1792.                 static  BOOL    bMouseMoved = FALSE;
  1793.                 static  POINT   ptLast;
  1794.                 TraceMsg(TF_ALWAYS, "MouseHookProc(WM_MOUSEMOVE)");
  1795.                 // Check to see if the mouse pointer really moved.
  1796.                 if (!bMouseMoved)
  1797.                 {
  1798.                     GetCursorPos(&ptLast);
  1799.                     bMouseMoved = TRUE;
  1800.                 }
  1801.                 else
  1802.                 {
  1803.                     POINT ptCursor;
  1804.                     POINT ptCheck;
  1805.                     GetCursorPos(&ptCheck);
  1806.                     if (ptCursor.x = ptCheck.x - ptLast.x)
  1807.                     {
  1808.                         if (ptCursor.x < 0)
  1809.                             ptCursor.x *= -1;
  1810.                     }
  1811.                     if (ptCursor.y = ptCheck.y - ptLast.y)
  1812.                     {
  1813.                         if (ptCursor.y < 0)
  1814.                             ptCursor.y *= -1;
  1815.                     }
  1816.                     if ((ptCursor.x + ptCursor.y) > MOUSEMOVE_THRESHOLD)
  1817.                     {
  1818.                         // Make sure the user is pressing ALT
  1819.                         // if we are in ALT+mouse mode.
  1820.                         if  (
  1821.                             s_pThis->ALTMouseMode()
  1822.                             &&
  1823.                             !(GetAsyncKeyState(VK_MENU) & 0x8000)
  1824.                             )
  1825.                         {
  1826.                             s_pThis->Quit();
  1827.                         }
  1828.                         else
  1829.                         {
  1830.                             // Display the scrollbar while the
  1831.                             // user is moving the mouse pointer
  1832.                             s_pThis->ShowControls(TRUE);
  1833.                         }
  1834.                         ptLast = ptCheck;
  1835.                     }
  1836.                 }
  1837.                 break;
  1838.             }
  1839.             default:
  1840.                 break;
  1841.         }
  1842.     }
  1843.     return CallNextHookEx(s_hMouseHook, nCode, wParam, lParam);
  1844. }
  1845. /////////////////////////////////////////////////////////////////////////////
  1846. // CScreenSaverWindow::ReleaseHooks
  1847. /////////////////////////////////////////////////////////////////////////////
  1848. void CScreenSaverWindow::ReleaseHooks
  1849. (
  1850. )
  1851. {
  1852.     if (s_hKeyboardHook != NULL)
  1853.     {
  1854.         EVAL(UnhookWindowsHookEx(s_hKeyboardHook));
  1855.         s_hKeyboardHook = NULL;
  1856.     }
  1857.     if (s_hMouseHook != NULL)
  1858.     {
  1859.         EVAL(UnhookWindowsHookEx(s_hMouseHook));
  1860.         s_hMouseHook = NULL;
  1861.     }
  1862. }
  1863. /////////////////////////////////////////////////////////////////////////////
  1864. // Interfaces
  1865. /////////////////////////////////////////////////////////////////////////////
  1866. /////////////////////////////////////////////////////////////////////////////
  1867. // IUnknown interface
  1868. /////////////////////////////////////////////////////////////////////////////
  1869. /////////////////////////////////////////////////////////////////////////////
  1870. // CScreenSaverWindow::AddRef
  1871. /////////////////////////////////////////////////////////////////////////////
  1872. ULONG CScreenSaverWindow::AddRef
  1873. (
  1874. {
  1875.     m_cRef++;
  1876.     TraceMsg(TF_DEBUGREFCOUNT, "CScreenSaverWindow::AddRef,  m_cRef = %d", m_cRef);
  1877.     return m_cRef;
  1878. }
  1879. /////////////////////////////////////////////////////////////////////////////
  1880. // CScreenSaverWindow::Release
  1881. /////////////////////////////////////////////////////////////////////////////
  1882. ULONG CScreenSaverWindow::Release
  1883. (
  1884. )
  1885. {
  1886.     m_cRef--;
  1887.     TraceMsg(TF_DEBUGREFCOUNT, "CScreenSaverWindow::Release, m_cRef = %d", m_cRef);
  1888.     if (m_cRef < 0)
  1889.     {
  1890.         ASSERT(FALSE);
  1891.         return 0;
  1892.     }
  1893.     return m_cRef;
  1894. }
  1895. /////////////////////////////////////////////////////////////////////////////
  1896. // CScreenSaverWindow::QueryInterface
  1897. /////////////////////////////////////////////////////////////////////////////
  1898. HRESULT CScreenSaverWindow::QueryInterface
  1899. (
  1900.     REFIID      riid,
  1901.     LPVOID *    ppvObj
  1902. )
  1903. {
  1904.     IUnknown * pUnk;
  1905.     *ppvObj = NULL;
  1906.     if (InlineIsEqualGUID(riid, IID_IUnknown))
  1907.         pUnk = SAFECAST(this, IDispatch *);
  1908. #if 0
  1909.     else if (InlineIsEqualGUID(riid, IID_IServiceProvider))
  1910.         pUnk = SAFECAST(this, IServiceProvider *);
  1911. #endif
  1912.     else if (InlineIsEqualGUID(riid, IID_IOleClientSite))
  1913.         pUnk = SAFECAST(this, IOleClientSite *);
  1914.     else if (InlineIsEqualGUID(riid, IID_IOleInPlaceSite))
  1915.         pUnk = SAFECAST(this, IOleInPlaceSite *);
  1916.     else if (InlineIsEqualGUID(riid, IID_IOleInPlaceFrame))
  1917.         pUnk = SAFECAST(this, IOleInPlaceFrame *);
  1918.     else if (InlineIsEqualGUID(riid, IID_IOleContainer))
  1919.         pUnk = SAFECAST(this , IOleContainer *);
  1920.     else if (InlineIsEqualGUID(riid, IID_IOleCommandTarget))
  1921.         pUnk = SAFECAST(this, IOleCommandTarget *);
  1922.     else if (InlineIsEqualGUID(riid, IID_IBindStatusCallback))
  1923.         pUnk = SAFECAST(m_pBindStatusCallback, IBindStatusCallback *);
  1924.     else if (
  1925.             InlineIsEqualGUID(riid, IID_IDispatch)
  1926.             ||
  1927.             InlineIsEqualGUID(riid, DIID_DWebBrowserEvents)
  1928.             ||
  1929.             InlineIsEqualGUID(riid, DIID_HTMLDocumentEvents)
  1930.             )
  1931.     {
  1932.         pUnk = SAFECAST(this, IDispatch *);
  1933.     }
  1934.     else
  1935.     {
  1936. #ifdef _DEBUG
  1937.         TCHAR szName[128];
  1938.         TraceMsg(   TF_DEBUGQI,
  1939.                     "CScreenSaverWindow::QueryInterface(%s) -- FAILED",
  1940.                     DebugIIDName(riid, szName));
  1941. #endif  // _DEBUG
  1942.         return E_NOINTERFACE;
  1943.     }
  1944.     pUnk->AddRef();
  1945.     *ppvObj = (void *)pUnk;
  1946.     return S_OK;
  1947. }
  1948. /////////////////////////////////////////////////////////////////////////////
  1949. // IServiceProvider interface
  1950. /////////////////////////////////////////////////////////////////////////////
  1951. /////////////////////////////////////////////////////////////////////////////
  1952. // CScreenSaverWindow::QueryService
  1953. /////////////////////////////////////////////////////////////////////////////
  1954. HRESULT CScreenSaverWindow::QueryService
  1955. (
  1956.     REFGUID guidService,
  1957.     REFIID  riid,
  1958.     void ** ppvObj
  1959. )
  1960. {
  1961.     IUnknown *  pUnk;
  1962.     HRESULT     hrResult = S_OK;
  1963.     *ppvObj = NULL;
  1964.     if (InlineIsEqualGUID(guidService, SID_STopLevelBrowser))
  1965.     {
  1966.         if (InlineIsEqualGUID(riid, IID_IServiceProvider))
  1967.             pUnk = SAFECAST(this, IServiceProvider *);
  1968.         else if (InlineIsEqualGUID(riid, IID_IOleCommandTarget))
  1969.             pUnk = SAFECAST(this, IOleCommandTarget *);
  1970.         else
  1971.             hrResult = E_NOINTERFACE;
  1972.     }
  1973.     else if (InlineIsEqualGUID(guidService, IID_IHlinkFrame))
  1974.     {
  1975.         if (InlineIsEqualGUID(riid, IID_IBindStatusCallback))
  1976.             pUnk = SAFECAST(m_pBindStatusCallback, IBindStatusCallback *);
  1977.     }
  1978.     else
  1979.         hrResult = E_NOINTERFACE;
  1980.     if (SUCCEEDED(hrResult))
  1981.     {
  1982.         pUnk->AddRef();
  1983.         *ppvObj = (void *)pUnk;
  1984.     }
  1985. #ifdef _DEBUG
  1986.     else
  1987.     {
  1988.         TCHAR szServiceName[128];
  1989.         DebugCLSIDName(guidService, szServiceName);
  1990.         TCHAR szRIIDName[128];
  1991.         DebugCLSIDName(riid, szRIIDName);
  1992.         TraceMsg(   TF_DEBUGQS,
  1993.                     "CScreenSaverWindow::QueryService(%s, %s) - FAILED",
  1994.                     szServiceName,
  1995.                     szRIIDName);
  1996.     }
  1997. #endif  // _DEBUG
  1998.     return hrResult;
  1999. }
  2000. /////////////////////////////////////////////////////////////////////////////
  2001. // IOleClientSite interface
  2002. /////////////////////////////////////////////////////////////////////////////
  2003. /////////////////////////////////////////////////////////////////////////////
  2004. // CScreenSaverWindow::SaveObject
  2005. /////////////////////////////////////////////////////////////////////////////
  2006. STDMETHODIMP CScreenSaverWindow::SaveObject
  2007. (
  2008. )
  2009. {
  2010.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::SaveObject()");
  2011.     return S_OK;
  2012. }
  2013. /////////////////////////////////////////////////////////////////////////////
  2014. // CScreenSaverWindow::GetMoniker
  2015. /////////////////////////////////////////////////////////////////////////////
  2016. STDMETHODIMP CScreenSaverWindow::GetMoniker
  2017. (
  2018.     DWORD       dwAssign,
  2019.     DWORD       dwWhichMoniker,
  2020.     IMoniker ** ppmk
  2021. )
  2022. {
  2023.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::GetMoniker()");
  2024.     return E_INVALIDARG;
  2025. }
  2026. /////////////////////////////////////////////////////////////////////////////
  2027. // CScreenSaverWindow::GetContainer
  2028. /////////////////////////////////////////////////////////////////////////////
  2029. STDMETHODIMP CScreenSaverWindow::GetContainer
  2030. (
  2031.     IOleContainer ** ppContainer
  2032. )
  2033. {
  2034.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::GetContainer()");
  2035.     *ppContainer = SAFECAST(this, IOleContainer *);
  2036.     (*ppContainer)->AddRef();
  2037.     return S_OK;
  2038. }
  2039. /////////////////////////////////////////////////////////////////////////////
  2040. // CScreenSaverWindow::ShowObject
  2041. /////////////////////////////////////////////////////////////////////////////
  2042. STDMETHODIMP CScreenSaverWindow::ShowObject
  2043. (
  2044. )
  2045. {
  2046.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::ShowObject()");
  2047.     return E_NOTIMPL;
  2048. }
  2049. /////////////////////////////////////////////////////////////////////////////
  2050. // CScreenSaverWindow::OnShowWindow
  2051. /////////////////////////////////////////////////////////////////////////////
  2052. STDMETHODIMP CScreenSaverWindow::OnShowWindow
  2053. (
  2054.     BOOL fShow
  2055. )
  2056. {
  2057.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnShowWindow()");
  2058.     return E_NOTIMPL;
  2059. }
  2060. /////////////////////////////////////////////////////////////////////////////
  2061. // CScreenSaverWindow::RequestNewObjectLayout
  2062. /////////////////////////////////////////////////////////////////////////////
  2063. STDMETHODIMP CScreenSaverWindow::RequestNewObjectLayout
  2064. (
  2065. )
  2066. {
  2067.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::RequestNewObjectLayout()");
  2068.     return E_NOTIMPL;
  2069. }
  2070. /////////////////////////////////////////////////////////////////////////////
  2071. // IOleWindow interface
  2072. /////////////////////////////////////////////////////////////////////////////
  2073. /////////////////////////////////////////////////////////////////////////////
  2074. // CScreenSaverWindow::GetWindow
  2075. /////////////////////////////////////////////////////////////////////////////
  2076. HRESULT CScreenSaverWindow::GetWindow
  2077. (
  2078.     HWND * phWnd
  2079. )
  2080. {
  2081.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::GetWindow()");
  2082.     ASSERT(m_hWnd != NULL);
  2083.     *phWnd = m_hWnd;
  2084.     return S_OK;
  2085. }
  2086. /////////////////////////////////////////////////////////////////////////////
  2087. // CScreenSaverWindow::ContextSensitiveHelp
  2088. /////////////////////////////////////////////////////////////////////////////
  2089. HRESULT CScreenSaverWindow::ContextSensitiveHelp
  2090. (
  2091.     BOOL fEnterMode
  2092. )
  2093. {
  2094.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::ContextSensitiveHelp()");
  2095.     return E_NOTIMPL;
  2096. }
  2097. /////////////////////////////////////////////////////////////////////////////
  2098. // IOleInPlaceSite
  2099. /////////////////////////////////////////////////////////////////////////////
  2100. /////////////////////////////////////////////////////////////////////////////
  2101. // CScreenSaverWindow::CanInPlaceActivate
  2102. /////////////////////////////////////////////////////////////////////////////
  2103. HRESULT CScreenSaverWindow::CanInPlaceActivate
  2104. (
  2105. )
  2106. {
  2107.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::CanInPlaceActivate()");
  2108.     return S_OK;
  2109. }
  2110. /////////////////////////////////////////////////////////////////////////////
  2111. // CScreenSaverWindow::OnInPlaceActivate
  2112. /////////////////////////////////////////////////////////////////////////////
  2113. HRESULT CScreenSaverWindow::OnInPlaceActivate
  2114. (
  2115. )
  2116. {
  2117.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnInPlaceActivate()");
  2118.     return S_OK;
  2119. }
  2120. /////////////////////////////////////////////////////////////////////////////
  2121. // CScreenSaverWindow::OnUIActivate
  2122. /////////////////////////////////////////////////////////////////////////////
  2123. HRESULT CScreenSaverWindow::OnUIActivate
  2124. (
  2125. )
  2126. {
  2127.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnUIActivate()");
  2128.     return S_OK;
  2129. }
  2130. /////////////////////////////////////////////////////////////////////////////
  2131. // CScreenSaverWindow::GetWindowContext
  2132. /////////////////////////////////////////////////////////////////////////////
  2133. HRESULT CScreenSaverWindow::GetWindowContext
  2134. (
  2135.     IOleInPlaceFrame **     ppFrame,
  2136.     IOleInPlaceUIWindow **  ppDoc,
  2137.     LPRECT                  lprcPosRect,
  2138.     LPRECT                  lprcClipRect,
  2139.     LPOLEINPLACEFRAMEINFO   lpFrameInfo
  2140. )
  2141. {
  2142.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::GetWindowContext()");
  2143.     *ppFrame = (IOleInPlaceFrame *)this;
  2144.     (*ppFrame)->AddRef();
  2145.     // NULL means same ptr as ppFrame.
  2146.     *ppDoc = NULL;
  2147.     GetClientRect(lprcClipRect);
  2148.     *lprcPosRect = *lprcClipRect;
  2149.     lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
  2150.     lpFrameInfo->fMDIApp = FALSE;
  2151.     lpFrameInfo->hwndFrame = m_hWnd;
  2152.     lpFrameInfo->haccel = 0;
  2153.     lpFrameInfo->cAccelEntries = 0;
  2154.     return S_OK;
  2155. }
  2156. /////////////////////////////////////////////////////////////////////////////
  2157. // CScreenSaverWindow::Scroll
  2158. /////////////////////////////////////////////////////////////////////////////
  2159. HRESULT CScreenSaverWindow::Scroll
  2160. (
  2161.     SIZE scrollExtent
  2162. )
  2163. {
  2164.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::Scroll()");
  2165.     return E_NOTIMPL;
  2166. }
  2167. /////////////////////////////////////////////////////////////////////////////
  2168. // CScreenSaverWindow::OnUIDeactivate
  2169. /////////////////////////////////////////////////////////////////////////////
  2170. HRESULT CScreenSaverWindow::OnUIDeactivate
  2171. (
  2172.     BOOL fUndoable
  2173. )
  2174. {
  2175.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnUIDeactivate()");
  2176.     return S_OK;
  2177. }
  2178. /////////////////////////////////////////////////////////////////////////////
  2179. // CScreenSaverWindow::OnInPlaceDeactivate
  2180. /////////////////////////////////////////////////////////////////////////////
  2181. HRESULT CScreenSaverWindow::OnInPlaceDeactivate
  2182. (
  2183. )
  2184. {
  2185.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnInPlaceDeactivate()");
  2186.     return S_OK;
  2187. }
  2188. /////////////////////////////////////////////////////////////////////////////
  2189. // CScreenSaverWindow::DiscardUndoState
  2190. /////////////////////////////////////////////////////////////////////////////
  2191. HRESULT CScreenSaverWindow::DiscardUndoState
  2192. (
  2193. )
  2194. {
  2195.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::DiscardUndoState()");
  2196.     return S_OK;
  2197. }
  2198. /////////////////////////////////////////////////////////////////////////////
  2199. // CScreenSaverWindow::DeactivateAndUndo
  2200. /////////////////////////////////////////////////////////////////////////////
  2201. HRESULT CScreenSaverWindow::DeactivateAndUndo
  2202. (
  2203. )
  2204. {
  2205.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::DeactivateAndUndo()");
  2206.     return S_OK;
  2207. }
  2208. /////////////////////////////////////////////////////////////////////////////
  2209. // CScreenSaverWindow::OnPosRectChange
  2210. /////////////////////////////////////////////////////////////////////////////
  2211. HRESULT CScreenSaverWindow::OnPosRectChange
  2212. (
  2213.     LPCRECT lprcPosRect
  2214. )
  2215. {
  2216.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::OnPosRectChange()");
  2217.     return E_NOTIMPL;
  2218. }
  2219. /////////////////////////////////////////////////////////////////////////////
  2220. // IOleInPlaceUIWindow interface
  2221. /////////////////////////////////////////////////////////////////////////////
  2222. /////////////////////////////////////////////////////////////////////////////
  2223. // CScreenSaverWindow::GetBorder
  2224. /////////////////////////////////////////////////////////////////////////////
  2225. HRESULT CScreenSaverWindow::GetBorder
  2226. (
  2227.     LPRECT lprectBorder
  2228. )
  2229. {
  2230.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::GetBorder()");
  2231.     GetClientRect(lprectBorder);
  2232.     return S_OK;
  2233. }
  2234. /////////////////////////////////////////////////////////////////////////////
  2235. // CScreenSaverWindow::RequestBorderSpace
  2236. /////////////////////////////////////////////////////////////////////////////
  2237. HRESULT CScreenSaverWindow::RequestBorderSpace
  2238. (
  2239.     LPCBORDERWIDTHS pbw
  2240. )
  2241. {
  2242.     RECT    rcClient;
  2243.     HRESULT hres = S_OK;
  2244.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::RequestBorderSpace()");
  2245.     GetClientRect(&rcClient);
  2246.     if (pbw->left + pbw->right > rcClient.right/2)
  2247.         hres = INPLACE_E_NOTOOLSPACE;
  2248.     else if (pbw->top + pbw->bottom > rcClient.bottom/2)
  2249.         hres = INPLACE_E_NOTOOLSPACE;
  2250.     return hres;
  2251. }
  2252. /////////////////////////////////////////////////////////////////////////////
  2253. // CScreenSaverWindow::SetBorderSpace
  2254. /////////////////////////////////////////////////////////////////////////////
  2255. HRESULT CScreenSaverWindow::SetBorderSpace
  2256. (
  2257.     LPCBORDERWIDTHS pbw
  2258. )
  2259. {
  2260.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::SetBorderSpace()");
  2261.     return S_OK;
  2262. }
  2263. /////////////////////////////////////////////////////////////////////////////
  2264. // CScreenSaverWindow::SetActiveObject
  2265. /////////////////////////////////////////////////////////////////////////////
  2266. HRESULT CScreenSaverWindow::SetActiveObject
  2267. (
  2268.     IOleInPlaceActiveObject *   pActiveObject,
  2269.     LPCOLESTR                   pszObjName
  2270. )
  2271. {
  2272.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::SetActiveObject()");
  2273.     return S_OK;
  2274. }
  2275. /////////////////////////////////////////////////////////////////////////////
  2276. // IOleInPlaceFrame interface
  2277. /////////////////////////////////////////////////////////////////////////////
  2278. /////////////////////////////////////////////////////////////////////////////
  2279. // CScreenSaverWindow::InsertMenus
  2280. /////////////////////////////////////////////////////////////////////////////
  2281. HRESULT CScreenSaverWindow::InsertMenus
  2282. (
  2283.     HMENU                   hmenuShared,
  2284.     LPOLEMENUGROUPWIDTHS    lpMenuWidths
  2285. )
  2286. {
  2287.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::InsertMenus()");
  2288.     return S_OK;
  2289. }
  2290. /////////////////////////////////////////////////////////////////////////////
  2291. // CScreenSaverWindow::SetMenu
  2292. /////////////////////////////////////////////////////////////////////////////
  2293. HRESULT CScreenSaverWindow::SetMenu
  2294. (
  2295.     HMENU       hmenuShared,
  2296.     HOLEMENU    holemenu,
  2297.     HWND        hwndActiveObject
  2298. )
  2299. {
  2300.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::SetMenu()");
  2301.     return S_OK;
  2302. }
  2303. /////////////////////////////////////////////////////////////////////////////
  2304. // CScreenSaverWindow::RemoveMenus
  2305. /////////////////////////////////////////////////////////////////////////////
  2306. HRESULT CScreenSaverWindow::RemoveMenus
  2307. (
  2308.     HMENU hmenuShared
  2309. )
  2310. {
  2311.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::RemoveMenus()");
  2312.     return S_OK;
  2313. }
  2314. /////////////////////////////////////////////////////////////////////////////
  2315. // CScreenSaverWindow::SetStatusText
  2316. /////////////////////////////////////////////////////////////////////////////
  2317. HRESULT CScreenSaverWindow::SetStatusText
  2318. (
  2319.     LPCOLESTR pszStatusText
  2320. )
  2321. {
  2322.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::SetStatusText()");
  2323.     return S_OK;
  2324. }
  2325. /////////////////////////////////////////////////////////////////////////////
  2326. // CScreenSaverWindow::EnableModeless
  2327. /////////////////////////////////////////////////////////////////////////////
  2328. HRESULT CScreenSaverWindow::EnableModeless
  2329. (
  2330.     BOOL fEnable
  2331. )
  2332. {
  2333. #ifdef _DEBUG
  2334.     TraceMsg(   TF_FUNCENTRY,
  2335.                 "CScreenSaverWindow::EnableModeless(%s)rn",
  2336.                 (fEnable ? TEXT("TRUE") : TEXT("FALSE")));
  2337. #endif  // _DEBUG
  2338.     m_bModelessEnabled = fEnable;
  2339.     EnableWindow(m_bModelessEnabled);
  2340.     if  (
  2341.         (m_pToolbar != NULL)
  2342.         &&
  2343.         IsWindow(m_pToolbar->m_hWnd)
  2344.         )
  2345.     {
  2346.         m_pToolbar->EnableWindow(m_bModelessEnabled);
  2347.     }
  2348.     return S_OK;
  2349. }
  2350. /////////////////////////////////////////////////////////////////////////////
  2351. // CScreenSaverWindow::TranslateAccelerator
  2352. /////////////////////////////////////////////////////////////////////////////
  2353. HRESULT CScreenSaverWindow::TranslateAccelerator
  2354. (
  2355.     LPMSG   lpmsg,
  2356.     WORD    wID
  2357. )
  2358. {
  2359.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::TranslateAccelerator()");
  2360.     return S_OK;
  2361. }
  2362. /////////////////////////////////////////////////////////////////////////////
  2363. // IOleContainer interface
  2364. /////////////////////////////////////////////////////////////////////////////
  2365. /////////////////////////////////////////////////////////////////////////////
  2366. // CScreenSaverWindow::ParseDisplayName
  2367. /////////////////////////////////////////////////////////////////////////////
  2368. HRESULT CScreenSaverWindow::ParseDisplayName
  2369. (
  2370.     IBindCtx *  pbc,
  2371.     LPOLESTR    pszDisplayName,
  2372.     ULONG *     pchEaten,
  2373.     IMoniker ** ppmkOut
  2374. )
  2375. {
  2376.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::ParseDisplayName()");
  2377.     return E_NOTIMPL;
  2378. }
  2379. /////////////////////////////////////////////////////////////////////////////
  2380. // CScreenSaverWindow::EnumObjects
  2381. /////////////////////////////////////////////////////////////////////////////
  2382. HRESULT CScreenSaverWindow::EnumObjects
  2383. (
  2384.     DWORD           grfFlags,
  2385.     IEnumUnknown ** ppenum
  2386. )
  2387. {
  2388.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::EnumObjects()");
  2389.     return E_NOTIMPL;
  2390. }
  2391. /////////////////////////////////////////////////////////////////////////////
  2392. // CScreenSaverWindow::LockContainer
  2393. /////////////////////////////////////////////////////////////////////////////
  2394. HRESULT CScreenSaverWindow::LockContainer
  2395. (
  2396.     BOOL fLock
  2397. )
  2398. {
  2399.     TraceMsg(TF_FUNCENTRY, "CScreenSaverWindow::LockContianer(%d)", fLock);
  2400.     return S_OK;
  2401. }
  2402. /////////////////////////////////////////////////////////////////////////////
  2403. // IOleCommandTarget interface
  2404. /////////////////////////////////////////////////////////////////////////////
  2405. /////////////////////////////////////////////////////////////////////////////
  2406. // CScreenSaverWindow::QueryStatus
  2407. /////////////////////////////////////////////////////////////////////////////
  2408. HRESULT CScreenSaverWindow::QueryStatus
  2409. (
  2410.     const GUID *    pguidCmdGroup,
  2411.     ULONG           cCmds,
  2412.     OLECMD          prgCmds[],
  2413.     OLECMDTEXT *    pCmdText
  2414. )
  2415. {
  2416.     if (prgCmds == NULL)
  2417.         return E_POINTER;
  2418.     return S_OK;
  2419. }
  2420. /////////////////////////////////////////////////////////////////////////////
  2421. // CScreenSaverWindow::Exec
  2422. /////////////////////////////////////////////////////////////////////////////
  2423. HRESULT CScreenSaverWindow::Exec
  2424. (
  2425.     const GUID *    pguidCmdGroup,
  2426.     DWORD           nCmdID,
  2427.     DWORD           nCmdExecOpt,
  2428.     VARIANTARG *    pvaIn,
  2429.     VARIANTARG *    pvaOut
  2430. )
  2431. {
  2432.     if (pguidCmdGroup == NULL)
  2433.         return OLECMDERR_E_NOTSUPPORTED;
  2434.     if (!InlineIsEqualGUID(*pguidCmdGroup, CGID_ShellDocView))
  2435.         return OLECMDERR_E_UNKNOWNGROUP;
  2436.     HRESULT hrResult;
  2437.     switch (nCmdID)
  2438.     {
  2439.         case SHDVID_GETTRANSITION:
  2440.         {
  2441.             // Make sure the feature is enabled
  2442.             DWORD dwFeatureFlags;
  2443.             EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  2444.             if (!(dwFeatureFlags & FEATURE_DEFAULT_TRANSITIONS))
  2445.             {
  2446.                 hrResult = OLECMDERR_E_NOTSUPPORTED;
  2447.                 break;
  2448.             }
  2449.             switch (nCmdExecOpt)
  2450.             {
  2451.                 case OLECMDEXECOPT_DODEFAULT:
  2452.                 {
  2453.                     // Validate In/Out args.
  2454.                     if ((pvaIn == NULL) || (pvaOut == NULL))
  2455.                         return E_UNEXPECTED;
  2456.                     V_VT(&pvaOut[0]) = VT_I4;
  2457.                     V_I4(&pvaOut[0]) = 0;
  2458.                     V_VT(&pvaOut[1]) = VT_BSTR;
  2459.                     V_BSTR(&pvaOut[1]) = SysAllocString(s_szDefTransition);
  2460.                     if (NULL == V_BSTR(&pvaOut[1]))
  2461.                         hrResult = E_OUTOFMEMORY;
  2462.                     else
  2463.                         hrResult = S_OK;
  2464.                     break;
  2465.                 }
  2466.                 case OLECMDEXECOPT_SHOWHELP:
  2467.                 {
  2468.                     hrResult = OLECMDERR_E_NOHELP;
  2469.                     break;
  2470.                 }
  2471.                 default:
  2472.                 {
  2473.                     hrResult = OLECMDERR_E_NOTSUPPORTED;
  2474.                     break;
  2475.                 }
  2476.             }
  2477.             break;
  2478.         }
  2479.         default:
  2480.         {
  2481.             hrResult = OLECMDERR_E_NOTSUPPORTED;
  2482.             break;
  2483.         }
  2484.     }
  2485.     return hrResult;
  2486. }
  2487. /////////////////////////////////////////////////////////////////////////////
  2488. // IDispatch interface
  2489. /////////////////////////////////////////////////////////////////////////////
  2490. /////////////////////////////////////////////////////////////////////////////
  2491. // CScreenSaverWindow::GetTypeInfoCount
  2492. /////////////////////////////////////////////////////////////////////////////
  2493. STDMETHODIMP CScreenSaverWindow::GetTypeInfoCount
  2494. (
  2495.     UINT * pctInfo
  2496. )
  2497. {
  2498.     *pctInfo = NULL;
  2499.     return E_NOTIMPL;
  2500. }
  2501. /////////////////////////////////////////////////////////////////////////////
  2502. // CScreenSaverWindow::GetTypeInfo
  2503. /////////////////////////////////////////////////////////////////////////////
  2504. STDMETHODIMP CScreenSaverWindow::GetTypeInfo
  2505. (
  2506.     UINT            itinfo,
  2507.     LCID            lcid,
  2508.     ITypeInfo **    pptInfo
  2509. )
  2510. {
  2511.     *pptInfo = NULL;
  2512.     return E_NOTIMPL;
  2513. }
  2514. /////////////////////////////////////////////////////////////////////////////
  2515. // CScreenSaverWindow::GetIDsOfNames
  2516. /////////////////////////////////////////////////////////////////////////////
  2517. STDMETHODIMP CScreenSaverWindow::GetIDsOfNames
  2518. (
  2519.     REFIID      riid,
  2520.     OLECHAR **  rgszNames,
  2521.     UINT        cNames,
  2522.     LCID        lcid,
  2523.     DISPID *    rgDispID
  2524. )
  2525. {
  2526.     *rgszNames = NULL;
  2527.     *rgDispID = NULL;
  2528.     return E_NOTIMPL;
  2529. }
  2530. /////////////////////////////////////////////////////////////////////////////
  2531. // CScreenSaverWindow::Invoke
  2532. /////////////////////////////////////////////////////////////////////////////
  2533. STDMETHODIMP CScreenSaverWindow::Invoke
  2534. (
  2535.     DISPID          dispIDMember,
  2536.     REFIID          riid,
  2537.     LCID            lcid,
  2538.     unsigned short  wFlags,
  2539.     DISPPARAMS *    pDispParams,
  2540.     VARIANT *       pVarResult,
  2541.     EXCEPINFO *     pExcepInfo,
  2542.     UINT *          puArgErr)
  2543. {
  2544.     VARIANT varResult;
  2545.     HRESULT hrResult = S_OK;
  2546.     for (;;)
  2547.     {
  2548.         if (!InlineIsEqualGUID(riid, IID_NULL))
  2549.         {
  2550.             hrResult = E_INVALIDARG;
  2551.             break;
  2552.         }
  2553.         // We don't handle the return value of any events if
  2554.         // events have them.  We should, however, initialize an
  2555.         // empty return value just so it's not garbage.
  2556.         if (pVarResult == NULL)
  2557.             pVarResult = &varResult;
  2558.         VariantInit(pVarResult);
  2559.         V_VT(pVarResult) = VT_EMPTY;
  2560.         // Only method and get calls are valid.
  2561.         if (wFlags & ~(DISPATCH_METHOD | DISPATCH_PROPERTYGET))
  2562.         {
  2563.             hrResult = DISP_E_MEMBERNOTFOUND;
  2564.             break;
  2565.         }
  2566.         // Process the event by looking for dispIDMember in the
  2567.         // list maintained in the tenant that maps event IDs to
  2568.         // actions.  If we find the ID, then we execute the action,
  2569.         // otherwise we do nothing.
  2570.         switch (dispIDMember)
  2571.         {
  2572.             case DISPID_AMBIENT_DLCONTROL:
  2573.             {
  2574.                 TraceMsg(TF_NAVIGATION, "NAV: Returning DLCTL ambient");
  2575.                 
  2576.                 VARIANT_BOOL bPlaySounds;
  2577.                 EVAL(SUCCEEDED(m_pSSConfig->get_PlaySounds(&bPlaySounds)));
  2578.                 VARIANT_BOOL bOffline;
  2579.                 EVAL(SUCCEEDED(m_pWebBrowser->get_Offline(&bOffline)));
  2580.                 V_VT(pVarResult) = VT_I4;
  2581.                 V_I4(pVarResult) = DLCTL_SILENT
  2582.                                     | ((bOffline == VARIANT_TRUE) ? DLCTL_OFFLINE : 0)
  2583.                                     | DLCTL_DLIMAGES
  2584.                                     | DLCTL_VIDEOS
  2585.                                     | ((bPlaySounds == VARIANT_TRUE) ? DLCTL_BGSOUNDS : 0);
  2586.                 break;                                        
  2587.             }
  2588.                 
  2589.             case DISPID_BEFORENAVIGATE:
  2590.             case DISPID_FRAMEBEFORENAVIGATE:
  2591.             {
  2592.                 TraceMsg(TF_NAVIGATION, "NAV: OnBeforeNavigate(Frame = %d)", (dispIDMember == DISPID_FRAMEBEFORENAVIGATE));
  2593.                 m_bScrollbarVisible = TRUE;
  2594.                 hrResult = OnBeforeNavigate(pDispParams, pVarResult);
  2595.                 break;
  2596.             }
  2597.             case DISPID_NEWWINDOW:
  2598.             case DISPID_FRAMENEWWINDOW:
  2599.             {
  2600.                 TraceMsg(TF_NAVIGATION, "NAV: OnNewWindow(Frame = %d)", (dispIDMember == DISPID_FRAMEBEFORENAVIGATE));
  2601.                 m_bScrollbarVisible = TRUE;
  2602.                 hrResult = OnNewWindow(pDispParams, pVarResult);  
  2603.                 break;
  2604.             }
  2605.             case DISPID_DOCUMENTCOMPLETE:
  2606.             {
  2607.                 TraceMsg(TF_NAVIGATION, "NAV: DocumentComplete()");
  2608.                 if (pDispParams == NULL)
  2609.                 {
  2610.                     hrResult = DISP_E_PARAMNOTOPTIONAL;
  2611.                     break;
  2612.                 }
  2613.                 ASSERT(V_VT(&pDispParams->rgvarg[0]) == (VT_VARIANT | VT_BYREF));
  2614.                 ASSERT(V_VT(V_VARIANTREF(&pDispParams->rgvarg[0])) == VT_BSTR);
  2615.                 OnDocumentComplete(V_BSTR(V_VARIANTREF(&pDispParams->rgvarg[0])));
  2616.                 break;
  2617.             }
  2618.             case DISPID_TITLECHANGE:
  2619.             {
  2620.                 if (pDispParams == NULL)
  2621.                 {
  2622.                     hrResult = DISP_E_PARAMNOTOPTIONAL;
  2623.                     break;
  2624.                 }
  2625.                 if (pDispParams->cArgs != 1)
  2626.                 {
  2627.                     hrResult = DISP_E_BADPARAMCOUNT;
  2628.                     break;
  2629.                 }
  2630.                 ASSERT(V_VT(&pDispParams->rgvarg[0]) == VT_BSTR);
  2631.     
  2632.                 hrResult = OnTitleChange(V_BSTR(&pDispParams->rgvarg[0]));
  2633.                 break;
  2634.             }
  2635.             case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
  2636.             {
  2637.                 DWORD dwFeatureFlags;
  2638.                 EVAL(SUCCEEDED(m_pSSConfig->get_Features(&dwFeatureFlags)));
  2639.                 if (!(dwFeatureFlags & FEATURE_IGNORE_MOUSE_CLICKS))
  2640.                 {
  2641.                     m_bMouseClicked = TRUE;
  2642.                     // Kill the current click check timer and restart if needed.
  2643.                     if (m_idClickCheckTimer != 0)
  2644.                     {
  2645.                         EVAL(KillTimer(m_idClickCheckTimer));
  2646.                         m_idClickCheckTimer = 0;
  2647.                     }
  2648.                     EVAL((m_idClickCheckTimer = SetTimer(   ID_CLICKCHECK_TIMER,
  2649.                                                             TIME_CLICKCHECK_TIMEOUT,
  2650.                                                             NULL)) != 0);
  2651.                 }
  2652.                 break;
  2653.             }
  2654.             default:
  2655.                 hrResult = DISP_E_MEMBERNOTFOUND;
  2656.                 break;
  2657.         }
  2658.         break;
  2659.     }
  2660.     return hrResult;
  2661. }
  2662. #if 0
  2663. // Darrenmi will wire this into the IOleCommandTarget interface 
  2664. /////////////////////////////////////////////////////////////////////////////
  2665. // INotificationSink interface
  2666. /////////////////////////////////////////////////////////////////////////////
  2667. /////////////////////////////////////////////////////////////////////////////
  2668. // CScreenSaverWindow::OnNotification
  2669. /////////////////////////////////////////////////////////////////////////////
  2670. STDMETHODIMP THIS_CLASS::OnNotification
  2671. (
  2672.     LPNOTIFICATION          pNotification,
  2673.     LPNOTIFICATIONREPORT    pNotfctnReport,
  2674.     DWORD                   dwReserved
  2675. )
  2676. {
  2677.     ASSERT(pNotification != NULL);
  2678.     TraceMsg(TF_NOTIFY, "OnNotification()");
  2679.     NOTIFICATIONTYPE nt;
  2680.     if (SUCCEEDED(pNotification->GetNotificationInfo(   &nt,
  2681.                                                         NULL,
  2682.                                                         NULL,
  2683.                                                         NULL,
  2684.                                                         0)))
  2685.     {
  2686.         if (InlineIsEqualGUID(nt, NOTIFICATIONTYPE_INET_OFFLINE))
  2687.         {
  2688.             TraceMsg(TF_NOTIFY, "Going OFFLINE");
  2689.             EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_TRUE)));
  2690.         }
  2691.         else if (InlineIsEqualGUID(nt, NOTIFICATIONTYPE_INET_ONLINE))
  2692.         {
  2693.             TraceMsg(TF_NOTIFY, "Going ONLINE");
  2694.             EVAL(SUCCEEDED(m_pWebBrowser->put_Offline(VARIANT_FALSE)));
  2695.         }
  2696.         else
  2697.             ASSERT(FALSE);
  2698.     }
  2699.     else
  2700.         ASSERT(FALSE);
  2701.     return S_OK;
  2702. }
  2703. #endif