Sergio Bonfiglio
Sergio Bonfiglio

Reputation: 159

Adding a Help file in Firemonkey applications

I'm creating the help file for an application written in Delphi Firemonkey. Unfortunately I have discovered that Firemonkey APPLICATION class doesn't have the HelFile property that the VCL equivalent has, so it seems to not be possible to include a help file with the application. I would like to know if someone has dealt with this problem and which is the better strategy to solve this. I thought to write a launcher in VCL console mode. The launcher is started from the main application with some parameters including the help topic code. This launcher links the HELP file, so the only thing it does is to start the help and then terminate itself. but this solution seems tricky to me. I was wondering if a better solution exists.

Upvotes: 1

Views: 202

Answers (1)

Philip J. Rayment
Philip J. Rayment

Reputation: 1245

I've dived deeply into the source code, and although I don't fully understand it, I found some interesting things. I don't have a custom help file to test with, but hopefully you can make this work.

The first interesting thing that I found is that there is a unit called System.HelpIntfs. That is, this is a System unit, not a vcl unit, so you'd expect it to be usable with FMX.

In order to call the Windows HTMLHelp system from FMX, you need to first call GetHelpSystem(), passing as an out parameter an iHelpSystem, iHelpSystem2, or iHelpSystem3 variable. You can then use the returned result to call for help.

However, when I tried this, it mostly failed, because the returned result is supposed to contain a list of help viewers, but that list was empty. I then found that the list can be populated with one entry for the Windows HTMLHelp by using the unit vcl.HtmlHelpViewer. What is interesting here is that, despite the name, this unit has no vcl dependencies! The only units it uses are System.Classes, System.HelpIntfs, System.SysUtils, and Winapi.Windows.

vcl.HtmlHelpViewer creates the viewer object and registers it in its Initialization section, so all you have to do with this is include it.

I have assumed that you have populated your controls' .HelpContext or HelpKeyword properties.

Your code will need to be something like this:

unit Form1;

interface

uses System.HelpIntfs, Vcl.HtmlHelpViewer,   //Necessary
     winapi.Windows,FMX.Platform.Win,        //Only needed for the line with 'hook' in it.
     System.UITypes,                         //Just for F1 name.
     FMX.Types, FMX.Controls;                //You probably already have these two.
.
.
.
//Form's OnKeyUp event handler.
procedure Form1.FormKeyUP(Sender:TObject; var Key:Word; var KeyChar:Char; Shift:TShiftState);
var  o:    TFMXObject;
     Ctrl: TStyledControl absolute o;
     hs:   iHelpSystem; //Or iHelpSystem2 or iHelpSystem3.  See Delphi help for the differences.
const      HelpFileName = 'MyHelpFile.chm';
begin
  if (key=vkF1) and (Shift=[]) then begin
    o:=Focused.GetObject;        //Get the focussed control, that the user would be expecting help on.
    if o is TStyledControl then begin
      GetHelpSystem(hs);
      case WhatIWant of //pseudo-values now to show options
        IWantTOC:             hs.ShowTableOfContents;  //NB: This doesn't work, as we haven't provided a file name and this method doesn't take parameters.
        IWantTOC_thatWorks:   hs.hook(FormToHWND(self),HelpFileName,HH_DISPLAY_TOC,0)
        IWantContextHelp:     hs.ShowContextHelp(Ctrl.HelpContext,HelpFileName); 
        IWantKeywordHelp:     hs.ShowKeywordHelp(Ctrl.HelpKeyword,HelpFileName); //Untested, but doesn't crash.
        IWantSomethingElse:   ;//See Delphi help for other options.
      end; //case
    end;
  end;
end

Presumably you'll want to move some of that (such as the HelpFileName constant) somewhere else and add some more error checking, but this should give you the idea, and I hope you can get it working.

Upvotes: 3

Related Questions