/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: HelpHost.cpp Abstract: This file contains the implementation of the CPCHHelpHost class, UI-side version of IHelpHost. Revision History: Davide Massarenti (Dmassare) 11/03/2000 created ******************************************************************************/ #include "stdafx.h" //////////////////////////////////////////////////////////////////////////////// #define GRANT_ACCESS_AND_CALL(ext,func,fail) \ HRESULT hr; \ \ if(ext) \ { \ CPCHHelpCenterExternal::TLS* tlsOld = ext->GetTLS(); \ CPCHHelpCenterExternal::TLS tlsNew; ext->SetTLS( &tlsNew ); \ \ tlsNew.m_fSystem = true; \ tlsNew.m_fTrusted = true; \ \ hr = ext->func; \ \ ext->SetTLS( tlsOld ); \ } \ else \ { \ hr = fail; \ } \ \ return hr //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// HelpHost::Main::Main() { // CComPtr m_rt; // CComPtr m_moniker; m_dwRegister = 0; // DWORD m_dwRegister; // m_External = NULL; // CPCHHelpCenterExternal* m_External; // m_hEvent = NULL; // HANDLE m_hEvent; // bool m_comps[COMPID_MAX]; ::ZeroMemory( m_comps, sizeof(m_comps) ); // Initialize to false... } HelpHost::Main::~Main() { Passivate(); if(m_hEvent) ::CloseHandle( m_hEvent ); } HRESULT HelpHost::Main::Initialize( /*[in]*/ CPCHHelpCenterExternal* external ) { __HCP_FUNC_ENTRY( "HelpHost::Main::Initialize" ); HRESULT hr; m_External = external; // // Get a pointer to the ROT and create a class moniker. // __MPC_EXIT_IF_METHOD_FAILS(hr, ::GetRunningObjectTable( 0, &m_rt )); __MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (m_hEvent = ::CreateEvent( NULL, FALSE, TRUE, NULL ))); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } void HelpHost::Main::Passivate() { if(m_rt) { if(m_dwRegister) { (void)m_rt->Revoke( m_dwRegister ); m_dwRegister = NULL; } } m_rt .Release(); m_moniker.Release(); m_External = NULL; } HRESULT HelpHost::Main::Locate( /*[in]*/ CLSID& clsid, /*[out]*/ CComPtr& pVal ) { __HCP_FUNC_ENTRY( "HelpHost::Main::Locate" ); HRESULT hr; CComPtr obj; m_moniker.Release(); __MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateClassMoniker( clsid, &m_moniker )); if(SUCCEEDED(m_rt->GetObject( m_moniker, &obj )) && obj) { __MPC_EXIT_IF_METHOD_FAILS(hr, obj.QueryInterface( &pVal )); } else { __MPC_SET_ERROR_AND_EXIT(hr, E_NOINTERFACE); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT HelpHost::Main::Register( /*[in]*/ CLSID& clsid ) { __HCP_FUNC_ENTRY( "HelpHost::Main::Register" ); HRESULT hr; m_moniker.Release(); __MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateClassMoniker( clsid, &m_moniker )); __MPC_EXIT_IF_METHOD_FAILS(hr, m_rt->Register( ROTFLAGS_REGISTRATIONKEEPSALIVE, this, m_moniker, &m_dwRegister )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////// void HelpHost::Main::ChangeStatus( /*[in]*/ LPCWSTR szComp, /*[in]*/ bool fStatus ) { static struct { LPCWSTR szName; CompId comp; } s_lookup[] = { { L"NAVBAR" , COMPID_NAVBAR }, { L"MININAVBAR", COMPID_MININAVBAR }, { L"CONTEXT" , COMPID_CONTEXT }, { L"CONTENTS" , COMPID_CONTENTS }, { L"HHWINDOW" , COMPID_HHWINDOW }, { L"FIRSTPAGE" , COMPID_FIRSTPAGE }, { L"HOMEPAGE" , COMPID_HOMEPAGE }, { L"SUBSITE" , COMPID_SUBSITE }, { L"SEARCH" , COMPID_SEARCH }, { L"INDEX" , COMPID_INDEX }, { L"FAVORITES" , COMPID_FAVORITES }, { L"HISTORY" , COMPID_HISTORY }, { L"CHANNELS" , COMPID_CHANNELS }, { L"OPTIONS" , COMPID_OPTIONS } }; if(szComp == NULL) return; for(int i=0; i lock( this ); if(idComp < COMPID_MAX) { m_comps[idComp] = fStatus; if(m_hEvent) { ::SetEvent( m_hEvent ); } } } bool HelpHost::Main::GetStatus( /*[in]*/ CompId idComp ) { MPC::SmartLock<_ThreadModel> lock( this ); if(idComp >= COMPID_MAX) return false; return m_comps[idComp]; } bool HelpHost::Main::WaitUntilLoaded( /*[in]*/ CompId idComp, /*[in]*/ DWORD dwTimeout ) { MPC::SmartLock<_ThreadModel> lock( this ); if(idComp >= COMPID_MAX) return false; // // On machine without enough RAM, increase the timeout. // { MEMORYSTATUSEX ms; ::ZeroMemory( &ms, sizeof(ms) ); ms.dwLength = sizeof(ms); if(::GlobalMemoryStatusEx( &ms )) { if(ms.ullAvailPhys < 32 * 1024 * 1024) dwTimeout *= 10; } } while(m_comps[idComp] == false) { // // Wait without holding a lock on the object. // lock = NULL; if(MPC::WaitForSingleObject( m_hEvent, dwTimeout ) != WAIT_OBJECT_0) return false; lock = this; } return true; } //////////////////// STDMETHODIMP HelpHost::Main::DisplayTopicFromURL( /*[in]*/ BSTR url, /*[in]*/ VARIANT options ) { GRANT_ACCESS_AND_CALL(m_External, ChangeContext( HSCCONTEXT_CONTENT, NULL, url, /*fAlsoContent*/true ), S_FALSE); }