unit mdhHelp;

{
[mdhHelp] [1.0]
Delphi 2005
November 2006

LICENSE

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
"http://www.mozilla.org/MPL/"

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is "[mdhHelp.pas]".

The Initial Developer of the Original Code is Martin Holmes (Victoria,
BC, Canada, "http://www.mholmes.com/"). Copyright (C) 2006 Martin Holmes
and the University of Victoria Computing and Media Centre. The code was 
co-developed for university and personal projects, and rights are shared
by Martin Holmes and the University of Victoria. All Rights Reserved.
}

{
  The purpose of this library is to find the best option for launching
  local Web pages in a browser, by searching for installed versions of
  Firefox, then Opera, before sadly falling back to the default browser
  if neither of these is installed. The idea is that anything is better
  than IE when it comes to displaying complex Web pages; IE has poor
  standards support, and also it blocks JavaScript by default on local
  files.

  How to use this file:

  1. In your main form's Create routine, set the application help file value:

    AppHelpFile := WideExtractFilePath(Application.ExeName) +
                                    'help\help.htm';

  2. Add a TApplicationEvents control to your main form (if you don't have one
     already), and give it an OnHelp event:

    function TufrmMain.aeMainHelp(Command: Word; Data: Integer;
    var CallHelp: Boolean): Boolean;
    begin
    //Don't pass on help processing to the OS
      CallHelp := False;
    //Call our help system, passing the Data (the Help keyword)
      mdhCallHelp(StrPas(PAnsiChar(Data)));
    //Return True to show it's handled.
      Result := True;
    end;

  3. In any explicit Help commands (such as TActions calling Help), call mdhCallHelp
     manually:

    mdhCallHelp('');

  if necessary passing a keyword.

  4. Make sure all your key components have keywords.

  5. Make sure DocLauncher.exe is in the same folder as your program executable.

  Dependencies:

  ShBrowseU (Alan G. Lloyd)
  TntUnicodeControls (Troy Wolbrink)

}

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TntStdCtrls, ComCtrls, TntForms, ShellAPI, FileFunctions,
  TntSysUtils, Registry;

var AppHelpFile: WideString;
function BrowseURL(const URL: string): Boolean;
function mdhCallHelp(HelpKeyword: WideString): Boolean;

implementation

function BrowseURL(const URL: string) : Boolean;
var
Browser: string;
HTMFileId: string;

begin
  Result := True;
  Browser := '';
  with TRegistry.Create do
    try
      RootKey := HKEY_CLASSES_ROOT;
      Access := KEY_QUERY_VALUE;

//First, we'll try to find Firefox -- that's our best bet
      if OpenKey('\FirefoxHTML\shell\open\command', False) then
        begin
          Browser := ReadString('');
          CloseKey;
        end;

//Failing that, try Opera
      if Browser = '' then
        begin
          if OpenKey('\Opera.HTML\shell\open\command', False) then
            begin
              Browser := ReadString('');
              CloseKey;
            end;
        end;

//Failing both of these, read the default browser. Sadly this is likely to
//result in IE, but what can we do?
      if Browser = '' then
        begin
          if OpenKey('\.htm', False) then
            begin
              HTMFileId := ReadString('');
              CloseKey;
              if OpenKey('\' + HTMFileId + '\shell\open\command', False) then
                begin
                  Browser := ReadString('');
                  CloseKey;
                end;
            end;
        end;
    finally
      Free;
    end;
  if Browser = '' then
    begin
//Just try a launch anyway
      LaunchFile(URL);
      Result := False;
      Exit;
    end;
//Try to turn the browser string into a working executable path
  Browser := StringReplace(Browser, '"', '', [rfReplaceAll]);
  Browser := StringReplace(Browser, '%1', '', [rfReplaceAll]);
  while (Length(Browser) > 0) and not(FileExists(Browser)) do
    Browser := Copy(Browser, 1, Length(Browser)-1);
  if FileExists(Browser) then
    ShellExecute(0, 'open', PChar(Browser), PChar('"' + URL + '"'), nil, SW_SHOW)
  else
    LaunchFile(URL);
end;

function mdhCallHelp(HelpKeyword: WideString): Boolean;
var
PossibleHelpFile: WideString;

begin
  Result := False; //default; false = fail.
//Check whether the Help file exists
  if not WideFileExists(AppHelpFile) then
    begin
      PossibleHelpFile := WideExtractFilePath(Application.ExeName) + 'help\help';
      if FileExists(PossibleHelpFile + '.htm') then
        begin
          AppHelpFile := PossibleHelpFile + '.htm';
        end
      else
        begin
          if FileExists(PossibleHelpFile + '.html') then
            begin
              AppHelpFile := PossibleHelpFile + '.html';
            end
          else
            begin
              PossibleHelpFile := WideExtractFilePath(Application.ExeName) + 'help\' +
                WideExtractFileName(Application.ExeName);
              PossibleHelpFile := WideChangeFileExt(PossibleHelpFile, '');
              if FileExists(PossibleHelpFile + '.htm') then
                begin
                  AppHelpFile := PossibleHelpFile + '.htm';
                end
              else
                begin
                  if FileExists(PossibleHelpFile + '.html') then
                    begin
                      AppHelpFile := PossibleHelpFile + '.html';
                    end
                  else
                    begin
                      if FileExists(PossibleHelpFile + '_help.htm') then
                        begin
                          AppHelpFile := PossibleHelpFile + '_help.htm';
                        end
                      else
                        begin
                          if FileExists(PossibleHelpFile + '_help.html') then
                            begin
                              AppHelpFile := PossibleHelpFile + '_help.html';
                            end;
                        end;
                    end;
                end;
            end;
        end;
    end;
  if WideFileExists(AppHelpFile) then
    begin
      AppHelpFile := StringReplace(AppHelpFile, '\', '/', [rfReplaceAll]);
      if Length(HelpKeyword) > 0 then
        BrowseURL('file:///' + AppHelpFile + '#' + HelpKeyword)
      else
        BrowseURL('file:///' + AppHelpFile);
      Result := True;
    end;
end;

end.
