Recent

Author Topic: Context Help in .chm file  (Read 1727 times)

Timbo

  • Newbie
  • Posts: 2
Context Help in .chm file
« on: September 28, 2021, 04:39:09 pm »
I'm converting an application developed in Delphi, potentially one of many. It uses context help in a .chm file, with context numbers set in the file and the current context number set within the code. This works correctly with Delphi.

I have a CHMHelpDatabase and LHelpConnector on the main form, and have initialised them according to the examples, and everything seems to be working - except that when, for example, the help context is 200, I get a message, presumably from LHelp, saying "Help context 200 not found".

As as aside, is there a way I can bypass LHelp and simply invoke the default CHM file viewer?

Thanks.

wp

  • Hero Member
  • *****
  • Posts: 9025
Re: Context Help in .chm file
« Reply #1 on: September 28, 2021, 05:23:18 pm »
is there a way I can bypass LHelp and simply invoke the default CHM file viewer?
I don't have a simple example for this, but you could look at the application LazStats (https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/applications/lazstats/ - download the snapshot if you don't have svn. No external components are required) which I modified to use chm help massively. Look at the MainUnit (in folder "forms"):

- Add the unit htmlhelp to "uses"; it comes with FPC (packages/winunits-base)

- Add a private method "function HelpHandler(Command: Word; Data: PtrInt; var CallHelp: Boolean): Boolean;" to the main form which does this:
Code: Pascal  [Select][+][-]
  1. // Call HTML help (.chm file)
  2. function TOS3MainFrm.HelpHandler(Command: Word; Data: PtrInt;
  3. var
  4.   s: String;
  5.   ws: UnicodeString;
  6.   res: Integer;
  7. begin
  8.   if Command = HELP_CONTEXT then
  9.   begin
  10.     // see: http://www.helpware.net/download/delphi/hh_doc.txt
  11.     ws := UnicodeString(Application.HelpFile);
  12.     res := htmlhelp.HtmlHelpW(0, PWideChar(ws), HH_HELP_CONTEXT, Data);  // Data is HelpContext here
  13.   end else
  14.   if Command = HELP_COMMAND then
  15.   begin
  16.     s := {%H-}PChar(Data);
  17.     // Data is pointer to HelpKeyword here, but the Windows help viewer does
  18.     // not want the KeywordPrefix required for LHelp.
  19.     if pos(HELP_KEYWORD_PREFIX + '/', s) = 1 then
  20.       Delete(s, 1, Length(HELP_KEYWORD_PREFIX) + 1);
  21.     ws := UnicodeString(Application.HelpFile + '::/' + s);
  22.     res := htmlhelp.HtmlHelpW(0, PWideChar(ws), HH_DISPLAY_TOPIC, 0);
  23.   end;
  24.  
  25.   // Don't call regular help
  26.   CallHelp := False;
  27.  
  28.   Result := res <> 0;
  29. end;

- In the main form's OnCreate handler, assign it to the Application.OnHelp event, and set the Application.Helpfile to the name of your chm file:
Code: Pascal  [Select][+][-]
  1. var
  2.   helpfn: String;
  3. begin
  4.   ...
  5.   helpfn := Application.Location + 'LazStats.chm';
  6.   if FileExists(helpfn) then
  7.   begin
  8.     Application.HelpFile := helpfn;
  9.     Application.OnHelp := @HelpHandler;
  10.   end
  11.   else
  12.     MessageDlg('LazStats help file not found.', mtError, [mbOK], 0);
  13. end;

This is for Windows only. Study the real code in the application which is extended to use the Lazarus-internal help-database instead which - of course - is cross-platform.


Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Timbo

  • Newbie
  • Posts: 2
Re: Context Help in .chm file
« Reply #2 on: September 29, 2021, 12:47:54 pm »
Thanks very much.

I had trouble with line 9 in the second snippet of code, getting an error for the @.

I fixed it by setting the OnHelp handler for the form using the Object Inspector instead, and now everything is working perfectly. Thanks again!


marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9700
  • FPC developer.
Re: Context Help in .chm file
« Reply #3 on: September 29, 2021, 12:58:52 pm »
Thanks very much.

I had trouble with line 9 in the second snippet of code, getting an error for the @.

That's a difference between $mode delphi and $mode objfpc probably. In mode delphi just leave it out.

 

TinyPortal © 2005-2018