<div>Dear NZ group,</div>
<div> </div>
<div>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 (
<a href="http://delphi.about.com">http://<span class="a"><font size="2"><font color="#008000"><b>delphi</b>.about.com</font></font></span></a>, Jan Verhoeven <a href="http://www.jansfreeware.com/articles/delphiresource.html">
http://www.jansfreeware.com/articles/delphiresource.html</a>, Peter D Johnson, Llanarth, Ceredigion, Wales, UK <a href="http://www.delphidabbler.com/articles?article=10">http://www.delphidabbler.com/articles?article=10</a>
) </div>
<div>I ended up with the following approach which so far is proving very robust. </div>
<div>And shared here in case any one is looking for a low key and straight forward approach. </div>
<div>I would appreciate any feedback or improvements please.</div>
<div> </div>
<div>
<div>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.
</div>
<div>(e.g. {$R 'html.res' 'html.rc'} )</div></div>
<div> </div>
<div>Needed things..</div>
<ol>
<li>TApplicationEvents use onHelp - ApplicationEvents1Help</li>
<li>.RC file open for editing in the IDE and included in the project stored in this example in the project directory</li>
<li>IDE edited HTML files</li>
<li>clear naming of Tcontrol property HelpKeyword for controls which you wish F1 to work for</li>
<li>clear naming of each TForm's HelpKeyword to cover for controls that have no specific help.</li>
<li>A Tform set up with a Twebbrowser or equivalent for displaying the help information.</li>
<li>Clients with IE 5.5 or up installed (although Gecko - Mozilla is said to be able to be used as well)</li></ol>
<div>The Twebbrowser component or Basla's TemmbededWB (free from <a href="http://bsalsa.com/">http://bsalsa.com/</a>) can also use the res:// protocol (instead of just http://) for extracting and using resources stored in an EXE or DLL.
</div>
<div>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.</div>
<div> </div>
<div>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.
</div>
<div> </div>
<div>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:</div>
<div> </div>
<div> //helper method</div>
<div>procedure TshowHelp.showLink(link: string);<br>begin<br> webHelp.Navigate('res://' + Application.ExeName + '/'+ link );<br>end;</div>
<div>
<p>procedure TshowHelp.lblShowIntroductionClick(Sender: TObject);<br>begin<br> showLink(lblShowIntroduction.helpkeyword);<br>end;</p></div>
<div>Specifically - One Approach:</div>
<div> </div>
<div>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.</div>
<div> </div>
<div>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).
</div>
<div> </div>
<div>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:</div>
<div> </div>
<div>editHouseName 23 "HTML\ editHouseName.html"</div>
<div> </div>
<div>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.</div>
<div> </div>
<div>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.
</div>
<div> </div>
<div> <link href="css/mainstyles.css" type="text/css" rel="stylesheet"><br> <link href="mainstyles" type="text/css" rel="stylesheet"></div>
<div> </div>
<div>and in my .RC I would have:</div>
<div> </div>
<div>mainstyles 23 "html/css/mainstyles.css"</div>
<div> </div>
<div>Notice that I do actually use the full name in the first link but I do that for style sheets only. </div>
<div>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
</div>
<div>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 **<u>re</u>opened** for editing in the Delphi IDE.</div>
<div> </div>
<div>So if you have an entry in your .RC file like this:</div>
<div> </div>
<div>housePicture GIF "html/images/marysHouse.gif"</div>
<div> </div>
<div>Then in the HTML you want to embed you would use the image like this:</div>
<div> </div>
<div><img src="housePicture" alt="Marys House/></div>
<div> </div>
<div>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.</div>
<div> </div>
<div>The printPreview functionality of the browser can be called, and many other things as well, that is where the TwebBrowser repacement by <a href="http://bsalsa.com/">http://bsalsa.com/</a> comes in useful as their free component has a lot of necessary things and extensions to the standard Twebbrowser built in already.
</div>
<div> </div>
<div>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.
</div>
<div> </div>
<div>Here is the simple procedure in TApplicationEvents that calls the help:</div>
<div>
<p>function TmainWebGalleryDisplay.ApplicationEvents1Help(Command: Word;<br> Data: Integer; var CallHelp: Boolean): Boolean;<br> var keyWord : string;<br>begin<br> keyWord := (screen.ActiveControl as tcontrol).HelpKeyword ;
<br> if keyWord = '' then keyword := (screen.ActiveForm as tform).HelpKeyword;</p>
<p> showHelp.webHelp.Navigate('res://' + Application.ExeName + '/'+ keyWord );<br> showHelp.Show;<br> showHelp.BringToFront;<br> CallHelp := false; //important to supress any further help sysytem action.
<br>end;</p>
<p>Hope this is of some use to people who have not looked at this kind of approach before.</p>
<p>Paul</p>
<p>object showHelp: TshowHelp<br> Left = 0<br> Top = 0<br> HelpType = htKeyword<br> HelpKeyword = 'welcomehere'<br> BorderStyle = bsToolWindow<br> Caption = 'Show Help'<br> ClientHeight = 599<br> ClientWidth = 738
<br> Color = clBtnFace<br> Font.Charset = DEFAULT_CHARSET<br> Font.Color = clWindowText<br> Font.Height = -11<br> Font.Name = 'Tahoma'<br> Font.Style = []<br> OldCreateOrder = False<br> PixelsPerInch = 96<br>
TextHeight = 13<br> object ScrollBox1: TScrollBox<br> Left = 16<br> Top = 494<br> Width = 193<br> Height = 83<br> Color = clWhite<br> ParentColor = False<br> TabOrder = 3<br> object Label1: TLabel
<br> Left = 8<br> Top = 16<br> Width = 46<br> Height = 13<br> Caption = 'Show: '#8212<br> Font.Charset = DEFAULT_CHARSET<br> Font.Color = clBlack<br> Font.Height = -11<br>
Font.Name = 'Tahoma'<br> Font.Style = [fsBold]<br> ParentFont = False<br> end<br> object lblShowIntroduction: TLabel<br> Left = 32<br> Top = 35<br> Width = 112<br> Height = 13<br>
Cursor = crHandPoint<br> HelpType = htKeyword<br> HelpKeyword = 'welcomehere'<br> Caption = 'Introduction - Welcome'<br> Font.Charset = DEFAULT_CHARSET<br> Font.Color = clBlue
<br> Font.Height = -11<br> Font.Name = 'Tahoma'<br> Font.Style = [fsUnderline]<br> ParentFont = False<br> OnClick = lblShowIntroductionClick<br> end<br> end<br> object webHelp: TEmbeddedWB
<br> Left = 0<br> Top = -1<br> Width = 708<br> Height = 482<br> TabOrder = 0<br> DownloadOptions = [DownloadImages, DownloadVideos, DownloadBGSounds]<br> UserInterfaceOptions = []<br> About = ' Embedded Web Browser from:
<a href="http://bsalsa.com/'">http://bsalsa.com/'</a><br> PrintOptions.Margins.Left = 4.233418000000001000<br> PrintOptions.Margins.Right = 4.233418000000001000<br> PrintOptions.Margins.Top = 4.233418000000001000
<br> PrintOptions.Margins.Bottom = 4.233418000000001000<br> PrintOptions.HTMLHeader.Strings = (<br> '<HTML></HTML>')<br> PrintOptions.Orientation = poPortrait<br> UserAgent = ' Embedded Web Browser from:
<a href="http://bsalsa.com/'">http://bsalsa.com/'</a><br> ControlData = {<br> 4C0000002D490000D13100000000000000000000000000000000000000000000<br> 000000004C000000000000000000000001000000E0D057007335CF11AE690800
<br> 2B2E126208000000000000004C0000000114020000000000C000000000000046<br> 8000000000000000000000000000000000000000000000000000000000000000<br> 00000000000000000100000000000000000000000000000000000000}<br> end
<br> object btnHelpPrint: TBitBtn<br> Left = 626<br> Top = 486<br> Width = 81<br> Height = 25<br> HelpType = htKeyword<br> HelpKeyword = 'printHelp'<br> Caption = 'Print Help'<br> TabOrder = 1
<br> OnClick = btnHelpPrintClick<br> Glyph.Data = {<br> F6000000424DF600000000000000760000002800000010000000100000000100<br> 04000000000080000000C40E0000C40E00001000000000000000000000000000<br> 80000080000000808000800000008000800080800000C0C0C000808080000000
<br> FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AAAAAAAAAAAA<br> AAAAAA00000000000AAAA0777777777070AA000000000000070A0777777FFF77<br> 000A077777788877070A00000000000007700777777777707070A00000000007
<br> 0700AA0FFFFFFFF07070AAA0F00000F0000AAAA0FFFFFFFF0AAAAAAA0F00000F<br> 0AAAAAAA0FFFFFFFF0AAAAAAA000000000AAAAAAAAAAAAAAAAAA}<br> end<br> object btnHelpClose: TBitBtn<br> Left = 632<br> Top = 560<br> Width = 75
<br> Height = 25<br> TabOrder = 2<br> Kind = bkClose<br> end<br>end<br>========<br>unit showHelpMain;</p>
<p>interface</p>
<p>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls, Buttons, OleCtrls, SHDocVw_EWB, EwbCore, EmbeddedWB;</p>
<p>type<br> TshowHelp = class(TForm)<br> webHelp: TEmbeddedWB;<br> btnHelpPrint: TBitBtn;<br> btnHelpClose: TBitBtn;<br> ScrollBox1: TScrollBox;<br> Label1: TLabel;<br> lblShowIntroduction: TLabel;<br>
procedure lblShowIntroductionClick(Sender: TObject);<br> procedure btnHelpPrintClick(Sender: TObject);<br> procedure showLink(link:string);<br> private<br> { Private declarations }<br> public<br> { Public declarations }
<br> end;</p>
<p>var<br> showHelp: TshowHelp;</p>
<p>implementation</p>
<p>{$R *.dfm}</p>
<p>procedure TshowHelp.btnHelpPrintClick(Sender: TObject);<br>begin<br>webHelp.PrintPreview;<br>end;</p>
<p>procedure TshowHelp.showLink(link: string);<br>begin<br> webHelp.Navigate('res://' + Application.ExeName + '/'+ link );<br>end;</p>
<p>procedure TshowHelp.lblShowIntroductionClick(Sender: TObject);<br>begin<br> showLink(lblShowIntroduction.helpkeyword);<br>end;</p>
<p>end.</p></div>
<div> </div>