262 lines
7.3 KiB
C++
262 lines
7.3 KiB
C++
/******************************************************************************
|
|
|
|
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<IRunningObjectTable> m_rt;
|
|
// CComPtr<IMoniker> 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<IPCHHelpHost>& pVal )
|
|
{
|
|
__HCP_FUNC_ENTRY( "HelpHost::Main::Locate" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IUnknown> 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<ARRAYSIZE(s_lookup); i++)
|
|
{
|
|
if(!_wcsicmp( szComp, s_lookup[i].szName ))
|
|
{
|
|
ChangeStatus( s_lookup[i].comp, fStatus );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HelpHost::Main::ChangeStatus( /*[in]*/ CompId idComp, /*[in]*/ bool fStatus )
|
|
{
|
|
MPC::SmartLock<_ThreadModel> 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);
|
|
}
|