HtmlHelpFunc.pas 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. unit HtmlHelpFunc;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2006 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Functions for HTML Help
  8. $jrsoftware: issrc/Projects/HtmlHelpFunc.pas,v 1.6 2009/03/23 23:16:44 mlaan Exp $
  9. }
  10. interface
  11. {$I VERSION.INC}
  12. uses
  13. Windows;
  14. const
  15. HH_DISPLAY_TOPIC = $0000;
  16. HH_KEYWORD_LOOKUP = $000D;
  17. type
  18. THtmlHelp = function(hwndCaller: HWND; pszFile: PChar; uCommand: UINT; dwData: DWORD): HWND; stdcall;
  19. PHH_AKLink = ^THH_AKLink;
  20. THH_AKLINK = record
  21. cbStruct: Integer;
  22. fReserved: Bool;
  23. pszKeywords: PChar;
  24. pszUrl: PChar;
  25. pszMsgText: PChar;
  26. pszMsgTitle: PChar;
  27. pszWindow: PChar;
  28. fIndexOnFail: Bool;
  29. end;
  30. var
  31. HtmlHelp: THtmlHelp;
  32. procedure InitHtmlHelpLibrary;
  33. procedure FreeHtmlHelpLibrary;
  34. implementation
  35. uses
  36. Messages, SysUtils, CmnFunc2, PathFunc;
  37. var
  38. HHCtrl: THandle;
  39. procedure InitHtmlHelpLibrary;
  40. begin
  41. if HHCtrl = 0 then begin
  42. HHCtrl := LoadLibrary(PChar(AddBackslash(GetSystemDir) + 'hhctrl.ocx'));
  43. if HHCtrl <> 0 then
  44. HtmlHelp := GetProcAddress(HHCtrl, {$IFDEF UNICODE}'HtmlHelpW'{$ELSE}'HtmlHelpA'{$ENDIF})
  45. else
  46. HtmlHelp := nil;
  47. end;
  48. end;
  49. procedure FreeHtmlHelpLibrary;
  50. begin
  51. if HHCtrl <> 0 then begin
  52. HtmlHelp := nil;
  53. FreeLibrary(HHCtrl);
  54. HHCtrl := 0;
  55. end;
  56. end;
  57. function CloseHtmlHelpWindowsEnumProc(Wnd: HWND; lParam: LPARAM): BOOL; stdcall;
  58. var
  59. PID: DWORD;
  60. ClassName: array[0..31] of Char;
  61. MsgResult: DWORD_PTR;
  62. begin
  63. if (GetWindowThreadProcessId(Wnd, @PID) <> 0) and
  64. (PID = GetCurrentProcessId) then begin
  65. if (GetClassName(Wnd, ClassName, SizeOf(ClassName) div SizeOf(ClassName[0])) > 0) and
  66. (StrIComp(ClassName, 'HH Parent') = 0) then begin
  67. { Consider only enabled windows. If an HTML Help window is disabled
  68. because it's waiting on a modal dialog (e.g. Properties) then it's
  69. probably not safe to close it. }
  70. if IsWindowEnabled(Wnd) then
  71. SendMessageTimeout(Wnd, WM_CLOSE, 0, 0, SMTO_BLOCK, 7500, @MsgResult);
  72. end;
  73. end;
  74. Result := True;
  75. end;
  76. procedure CloseHtmlHelpWindows;
  77. begin
  78. { Note: We don't call HtmlHelp(HH_CLOSE_ALL) here because its operation is
  79. asynchronous. (See: http://helpware.net/FAR/far_faq.htm#HH_CLOSE_ALL)
  80. If HHCTRL.OCX is unloaded too quickly after HH_CLOSE_ALL, a crash can
  81. occur. Even if HHCTRL.OCX isn't explicitly unloaded, it still *might* be
  82. possible for the main thread to exit while the HH thread is still in the
  83. process of closing the window and cleaning up the temporary file.
  84. Therefore, we use a different approach: we find the window(s) and send a
  85. WM_CLOSE message synchronously. }
  86. if Assigned(HtmlHelp) then
  87. EnumWindows(@CloseHtmlHelpWindowsEnumProc, 0);
  88. end;
  89. initialization
  90. finalization
  91. { Must explicitly close any open HTML Help window before terminating,
  92. otherwise it leaves behind a temporary file. (Most apps don't bother
  93. doing this, including IE and Outlook Express.) }
  94. CloseHtmlHelpWindows;
  95. end.