Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
5.5 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Behav_A.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHBehavior_A class,
  7. that dictates how hyperlinks work in the help center.
  8. Revision History:
  9. Davide Massarenti (dmassare) 06/06/2000
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. #include <ShellApi.h>
  14. ////////////////////////////////////////////////////////////////////////////////
  15. static const WCHAR s_APPprefix [] = L"APP:";
  16. static const WCHAR s_HCPprefix [] = L"HCP:";
  17. static const WCHAR s_HTTPprefix[] = L"HTTP:";
  18. ////////////////////////////////////////////////////////////////////////////////
  19. HRESULT Local_ShellRun( LPCWSTR szCommandOrig ,
  20. LPCWSTR szArgs )
  21. {
  22. __HCP_FUNC_ENTRY( "Local_ShellRun" );
  23. HRESULT hr;
  24. MPC::wstring szCommand( szCommandOrig );
  25. SHELLEXECUTEINFOW oExecInfo;
  26. ::ZeroMemory( &oExecInfo, sizeof(oExecInfo) ); oExecInfo.cbSize = sizeof(oExecInfo);
  27. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SubstituteEnvVariables( szCommand ));
  28. oExecInfo.fMask = SEE_MASK_FLAG_NO_UI;
  29. oExecInfo.hwnd = NULL;
  30. oExecInfo.lpVerb = L"Open";
  31. oExecInfo.lpFile = szCommand.c_str();
  32. oExecInfo.lpParameters = (szArgs && szArgs[0]) ? szArgs : NULL;
  33. oExecInfo.lpDirectory = NULL;
  34. oExecInfo.nShow = SW_SHOWNORMAL;
  35. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::ShellExecuteExW( &oExecInfo ));
  36. hr = S_OK;
  37. __HCP_FUNC_CLEANUP;
  38. if(oExecInfo.hProcess) ::CloseHandle( oExecInfo.hProcess );
  39. __HCP_FUNC_EXIT(hr);
  40. }
  41. ////////////////////////////////////////////////////////////////////////////////
  42. CPCHBehavior_A::CPCHBehavior_A()
  43. {
  44. __HCP_FUNC_ENTRY( "CPCHBehavior_A::CPCHBehavior_A" );
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. STDMETHODIMP CPCHBehavior_A::Init( /*[in]*/ IElementBehaviorSite* pBehaviorSite )
  48. {
  49. __HCP_FUNC_ENTRY( "CPCHBehavior_A::Init" );
  50. HRESULT hr;
  51. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHBehavior::Init( pBehaviorSite ));
  52. __MPC_EXIT_IF_METHOD_FAILS(hr, AttachToEvent( L"onclick", (CLASS_METHOD)onClick ));
  53. ////////////////////
  54. {
  55. CComQIPtr<IHTMLAnchorElement> elemHyperLink;
  56. if((elemHyperLink = m_elem))
  57. {
  58. CComBSTR bstrHref;
  59. MPC_SCRIPTHELPER_GET__DIRECT(bstrHref, elemHyperLink, href);
  60. if(STRINGISPRESENT(bstrHref)) (void)HyperLinks::Lookup::s_GLOBAL->Queue( bstrHref );
  61. }
  62. }
  63. hr = S_OK;
  64. __HCP_FUNC_CLEANUP;
  65. __HCP_FUNC_EXIT(hr);
  66. }
  67. ////////////////////////////////////////////////////////////////////////////////
  68. HRESULT CPCHBehavior_A::onClick( DISPID, DISPPARAMS*, VARIANT* )
  69. {
  70. __HCP_FUNC_ENTRY( "CPCHBehavior_A::onClick" );
  71. HRESULT hr;
  72. if(!m_parent) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
  73. //
  74. // If we are navigating, abort the click.
  75. //
  76. {
  77. VARIANT_BOOL fCancel;
  78. CPCHHelpSession* hs = m_parent->HelpSession();
  79. if(hs)
  80. {
  81. __MPC_EXIT_IF_METHOD_FAILS(hr, hs->IsNavigating( &fCancel ));
  82. if(fCancel)
  83. {
  84. __MPC_EXIT_IF_METHOD_FAILS(hr, CancelEvent());
  85. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  86. }
  87. hs->CancelThreshold();
  88. }
  89. }
  90. //
  91. // If the URL is an APP: one, process the redirect.
  92. //
  93. if(m_fTrusted)
  94. {
  95. CComPtr<IHTMLElement> elemSrc;
  96. CComPtr<IHTMLElement> elemParent;
  97. CComQIPtr<IHTMLAnchorElement> elemHyperLink;
  98. __MPC_EXIT_IF_METHOD_FAILS(hr, GetEvent_SrcElement( elemSrc ));
  99. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::FindFirstParentWithThisTag( elemParent, elemSrc, L"A" ));
  100. if((elemHyperLink = elemParent))
  101. {
  102. CComBSTR bstrHref;
  103. CComBSTR bstrTarget;
  104. MPC_SCRIPTHELPER_GET__DIRECT(bstrHref , elemHyperLink, href );
  105. MPC_SCRIPTHELPER_GET__DIRECT(bstrTarget, elemHyperLink, target);
  106. if(bstrHref && !_wcsnicmp( bstrHref, s_APPprefix, MAXSTRLEN( s_APPprefix ) ))
  107. {
  108. LPCWSTR szRealHRef = bstrHref + MAXSTRLEN( s_APPprefix );
  109. //
  110. // The URL starts with "app:", so let's cancel the event.
  111. //
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, CancelEvent());
  113. //
  114. // Is it for hcp:// ?
  115. //
  116. if(!_wcsnicmp( szRealHRef, s_HCPprefix, MAXSTRLEN( s_HCPprefix ) ))
  117. {
  118. //
  119. // Then navigate from the top level window.
  120. //
  121. CComPtr<IHTMLWindow2> win;
  122. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::LocateFrame( win, elemSrc, L"_top" ));
  123. __MPC_EXIT_IF_METHOD_FAILS(hr, win->navigate( CComBSTR( szRealHRef ) ));
  124. }
  125. else
  126. //
  127. // Launch an external program.
  128. //
  129. {
  130. MPC::wstring szFile;
  131. MPC::wstring szArgs;
  132. MPC::WStringLookup mapQuery;
  133. //
  134. // Parse the query string.
  135. //
  136. MPC::HTML::ParseHREF( szRealHRef, szFile, mapQuery );
  137. //
  138. // Is it for http:// ? Then assume the url is properly escape and pass it directly to the shell.
  139. //
  140. if(!_wcsnicmp( szFile.c_str(), s_HTTPprefix, MAXSTRLEN( s_HTTPprefix ) ))
  141. {
  142. szFile = szRealHRef;
  143. }
  144. else
  145. {
  146. szArgs = mapQuery[ L"arg" ];
  147. }
  148. (void)Local_ShellRun( szFile.c_str(), szArgs.c_str() );
  149. //
  150. // If we have a "topic" argument from the query string, navigate the original target to it.
  151. //
  152. szFile = mapQuery[ L"topic" ];
  153. if(szFile.size())
  154. {
  155. //
  156. // Then navigate from the top level window.
  157. //
  158. CComPtr<IHTMLWindow2> win;
  159. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::HTML::LocateFrame( win, elemSrc, bstrTarget ));
  160. __MPC_EXIT_IF_METHOD_FAILS(hr, win->navigate( CComBSTR( szFile.c_str() ) ));
  161. }
  162. }
  163. }
  164. }
  165. }
  166. hr = S_OK;
  167. __HCP_FUNC_CLEANUP;
  168. __HCP_FUNC_EXIT(hr);
  169. }