[DUG] Delphi 205+ IDE's advantage in generating help for projects

Paul A Norman paul.a.norman at gmail.com
Wed Dec 12 00:10:20 NZDT 2007


Dear NZ group,

For quite a while I looked for a decent and easy help system to integerate
into Delphi projects, and there was over the years a bit of talk on the
whole thing. From many of the ideas expressed in the past in this group, and
a some help from Google (http://*delphi*.about.com <http://delphi.about.com>,
Jan Verhoeven http://www.jansfreeware.com/articles/delphiresource.html,
Peter D Johnson, Llanarth, Ceredigion, Wales, UK
http://www.delphidabbler.com/articles?article=10)
I ended up with the following approach which so far is proving very robust.
And shared here in case any one is looking for a low key and straight
forward approach.
I would appreciate any feedback or improvements please.

 From at least Delphi 2005 (if not D7?) forward there is an integration in
the IDE that allows you to create a .RC file and include it in the project
so that the resulting RES file compiles into the executible automatically.
Well that will not be news to many, but this gives the opening to easily
build html type help directly into a project with a minumin of effort.
(e.g. {$R 'html.res' 'html.rc'}  )

Needed things..

   1. TApplicationEvents use onHelp - ApplicationEvents1Help
   2. .RC file open for editing in the IDE and included in the project
   stored in this example in the project directory
   3. IDE edited HTML files
   4. clear naming of  Tcontrol property HelpKeyword  for controls which
   you wish F1 to work for
   5. clear naming of each TForm's HelpKeyword to cover for controls that
   have no specific help.
   6. A Tform set up with a Twebbrowser or equivalent for displaying the
   help information.
   7. Clients with IE 5.5 or up installed (although Gecko  - Mozilla is
   said to be able to be used as well)

The Twebbrowser component or Basla's TemmbededWB (free from
http://bsalsa.com/) can also use the res:// protocol (instead of just
http://) for extracting and using resources stored in an EXE or DLL.
D2005 (or D8?) introduced a property on Tcontrol descendants called
HelpKeyword. We can reutilise this for the stem of file names of HTML files
that will be embedded in the EXE.

When working on the development of the project, I write the help system as a
part of the general development. This has proven really good because I know
for a lot of people help gets done last, or in a rush, or not at all! It has
also helped me clarify the overall strategies that I am following in the
development. When you have to write about it much earlier than normal for an
end user, it can help sort out much earlier things that may not occur to you
or team members until much later otherwise.

I put general help and general program running technique information in the
Tform(s) and you can also make Table of contents, if necesary turn Tlabels
into hyper links and so on like this:

   //helper method
procedure TshowHelp.showLink(link: string);
begin
 webHelp.Navigate('res://' + Application.ExeName + '/'+ link );
end;

procedure TshowHelp.lblShowIntroductionClick(Sender: TObject);
begin
  showLink(lblShowIntroduction.helpkeyword);
end;
Specifically - One Approach:

Make a folder called, say, HTML in your project directory and make JS CSS
and IMAGES directories below that if you wish to use them.

Write your HTML using the built in functionality of Delphi IDE (2005+), for
ease of process name your HTML files according to the HelpKeyword for the
control that will F1 'call' them, and keep that name close to or identical
to the control's name for trace back if you need to later (I include the
keyword in the HTML in a very small font for that reason especially on a big
project).

For example if the Tcontrol descendant is called editHouseName then the key
word could be the same, and the HTML file would be editHouseName.html, and
the entry in the .RC resource file would be:

editHouseName 23 "HTML\ editHouseName.html"

The 23 is there to tell the system what kind of resource you are using as
Delphi in earlier versions of BRCC32 does not know about HTML, but I believe
that you can identify gif as GIF and bmp as BMP Jpeg as JPG  etc. You''l
need to check on each resource type you may choose to use. But Dephi does
not like dots . in the resouce names (unlike some MS products). So
editHouseName is ok and editHouseName.web would not be.

When writing the HTML if you want to refer to other files embeded in the
executible as well, you do so by the resource name you have used in the .RC
file, not by the file name with extension. For example to use a style sheet
you could use this format.

 <link href="css/mainstyles.css" type="text/css" rel="stylesheet">
 <link href="mainstyles" type="text/css" rel="stylesheet">

and in my .RC I would have:

mainstyles 23 "html/css/mainstyles.css"

Notice that I do actually use the full name in the first link but I do
that  for style sheets only.
The reason I do this is because when called from a resource, this HTML file
will ignore the first link as the path is unresolvable and (it should  refer
to a RES), and use the second link, and look for a resource embedded in the
executible which you called mainstyles when you wrote the .RC
Putting the actual relative path to the harddisked saved HTML file, in the
first link allows you to see the style sheet in action when the HTML file is
***re*opened** for editing in the Delphi IDE.

So if you have an entry in your .RC file like this:

housePicture GIF "html/images/marysHouse.gif"

Then in the HTML you want to embed you would use the image like this:

<img src="housePicture" alt="Marys House/>

You can leaverage your dHTML skills and general HTML techniques as much as
you like. In fact the applicaton becomes like its own web server.

The printPreview functionality of the browser can be called, and many other
things as well, that is where the TwebBrowser repacement by
http://bsalsa.com/ comes in useful as their free component has a lot of
necessary things and extensions to the standard Twebbrowser built in
already.

I have assumed that you like me will make the procedure failsafe, because
you want the help to always work, so, so far I have put no error checking
into it as during development and trialing I want to notice any errors or
failures and fix them all.

Here is the simple procedure in TApplicationEvents that calls the help:

function TmainWebGalleryDisplay.ApplicationEvents1Help(Command: Word;
  Data: Integer; var CallHelp: Boolean): Boolean;
  var keyWord : string;
begin
   keyWord := (screen.ActiveControl as tcontrol).HelpKeyword ;
    if keyWord = '' then keyword := (screen.ActiveForm as
tform).HelpKeyword;

  showHelp.webHelp.Navigate('res://' + Application.ExeName + '/'+ keyWord );
  showHelp.Show;
  showHelp.BringToFront;
   CallHelp := false; //important to supress any further help sysytem
action.
end;

Hope this is of some use to people who have not looked at this kind of
approach before.

Paul

object showHelp: TshowHelp
  Left = 0
  Top = 0
  HelpType = htKeyword
  HelpKeyword = 'welcomehere'
  BorderStyle = bsToolWindow
  Caption = 'Show Help'
  ClientHeight = 599
  ClientWidth = 738
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ScrollBox1: TScrollBox
    Left = 16
    Top = 494
    Width = 193
    Height = 83
    Color = clWhite
    ParentColor = False
    TabOrder = 3
    object Label1: TLabel
      Left = 8
      Top = 16
      Width = 46
      Height = 13
      Caption = 'Show: '#8212
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clBlack
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = [fsBold]
      ParentFont = False
    end
    object lblShowIntroduction: TLabel
      Left = 32
      Top = 35
      Width = 112
      Height = 13
      Cursor = crHandPoint
      HelpType = htKeyword
      HelpKeyword = 'welcomehere'
      Caption = 'Introduction - Welcome'
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clBlue
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = [fsUnderline]
      ParentFont = False
      OnClick = lblShowIntroductionClick
    end
  end
  object webHelp: TEmbeddedWB
    Left = 0
    Top = -1
    Width = 708
    Height = 482
    TabOrder = 0
    DownloadOptions = [DownloadImages, DownloadVideos, DownloadBGSounds]
    UserInterfaceOptions = []
    About = ' Embedded Web Browser from: http://bsalsa.com/'
    PrintOptions.Margins.Left = 4.233418000000001000
    PrintOptions.Margins.Right = 4.233418000000001000
    PrintOptions.Margins.Top = 4.233418000000001000
    PrintOptions.Margins.Bottom = 4.233418000000001000
    PrintOptions.HTMLHeader.Strings = (
      '<HTML></HTML>')
    PrintOptions.Orientation = poPortrait
    UserAgent = ' Embedded Web Browser from: http://bsalsa.com/'
    ControlData = {
      4C0000002D490000D13100000000000000000000000000000000000000000000
      000000004C000000000000000000000001000000E0D057007335CF11AE690800
      2B2E126208000000000000004C0000000114020000000000C000000000000046
      8000000000000000000000000000000000000000000000000000000000000000
      00000000000000000100000000000000000000000000000000000000}
  end
  object btnHelpPrint: TBitBtn
    Left = 626
    Top = 486
    Width = 81
    Height = 25
    HelpType = htKeyword
    HelpKeyword = 'printHelp'
    Caption = 'Print Help'
    TabOrder = 1
    OnClick = btnHelpPrintClick
    Glyph.Data = {
      F6000000424DF600000000000000760000002800000010000000100000000100
      04000000000080000000C40E0000C40E00001000000000000000000000000000
      80000080000000808000800000008000800080800000C0C0C000808080000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AAAAAAAAAAAA
      AAAAAA00000000000AAAA0777777777070AA000000000000070A0777777FFF77
      000A077777788877070A00000000000007700777777777707070A00000000007
      0700AA0FFFFFFFF07070AAA0F00000F0000AAAA0FFFFFFFF0AAAAAAA0F00000F
      0AAAAAAA0FFFFFFFF0AAAAAAA000000000AAAAAAAAAAAAAAAAAA}
  end
  object btnHelpClose: TBitBtn
    Left = 632
    Top = 560
    Width = 75
    Height = 25
    TabOrder = 2
    Kind = bkClose
  end
end
========
unit showHelpMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, OleCtrls, SHDocVw_EWB, EwbCore, EmbeddedWB;

type
  TshowHelp = class(TForm)
    webHelp: TEmbeddedWB;
    btnHelpPrint: TBitBtn;
    btnHelpClose: TBitBtn;
    ScrollBox1: TScrollBox;
    Label1: TLabel;
    lblShowIntroduction: TLabel;
    procedure lblShowIntroductionClick(Sender: TObject);
    procedure btnHelpPrintClick(Sender: TObject);
    procedure showLink(link:string);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  showHelp: TshowHelp;

implementation

{$R *.dfm}

procedure TshowHelp.btnHelpPrintClick(Sender: TObject);
begin
webHelp.PrintPreview;
end;

procedure TshowHelp.showLink(link: string);
begin
 webHelp.Navigate('res://' + Application.ExeName + '/'+ link );
end;

procedure TshowHelp.lblShowIntroductionClick(Sender: TObject);
begin
  showLink(lblShowIntroduction.helpkeyword);
end;

end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserver.123.net.nz/pipermail/delphi/attachments/20071212/bcb96b27/attachment-0001.html


More information about the Delphi mailing list