IDE.HtmlHelpFunc.pas 3.0 KB

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