Windows Help

Windows Help

WinHelp macros
Using Help
HelpFiles
Searching your application's help file


WinHelp macros

Question


Is it possible to call the WinHelp macro 'Search()' from  Delphi?

Answer


A:

Yes, you can do this by a direct call to the Windows API WinHelp function, or

(more easily) by calling the Application.HelpCommand method.

Or (more easily still) you could avoid having to fiddle with pointers to null

terminated strings every time, by going a stage further and encapsulating the

call into a simple procedure like this:



unit Help;



{$X+      {Allow Application.HelpCommand's result to be discarded}



interface



 procedure HelpSearch (const Key: string);





implementation

 uses

   Forms,         {for Application}

   SysUtils,      {for StrPCopy}

   WinTypes;      {for HELP_PARTIALKEY}



 procedure HelpSearch (const Key: string);

{----------------------------------------------------------------}

{ Calls Windows Help engine for a Search on the supplied Key.    }

{ If more than one match or no match, brings up Search dialog.   }

{----------------------------------------------------------------}

 var

   AStr255: array[0..255] of char;

   PStr255: pointer;

 begin

   PStr255 := StrPCopy(@AStr255, Key);

   Application.HelpCommand(HELP_PARTIALKEY, longint(PStr255));

 end;





end.


Using Help

Question


I'm using Application.helpJump to implement context-sensitive help.

Sometimes, however, the topic string I construct isn't in the help file, in

which case winHelp displays "Topic not found" and keeps the user in Help

with a blank screen.  Does anyone know of a way to interrogate a WinHelp

file to see if a context string exists, or alternatively a way to extract

all context strings from a help file (then I can write a little loop to see

if the string is there).

Answer


A:

You can support LDLLHandler() in your help system. With that I think you can

check DW_ENDJUMP, lparam1 of it will hold the position of the help topic.

When it fails you can call the callback function RcCloseHfs to close Help.

I suppose there would be a blink that the user may notice, but it may be

tolerable.



The work to do is to create a DLL to support LDLLHandler() and a DLL macro in

the help system to send information to the DLL.



A:

The following code demonstrates how to bring up the WinHelp "Search"

dialog for your application's help file.  You can use TApplication's

HelpCommand method to send the Help_PartialKey command to the WinHelp

system. The parameter for this command should be a PChar (cast to a

longint to circumvent typechecking) that contains the string on

which you'd like to search.  The example below uses an empty string,



which invokes "Search" dialog and leaves the edit control in the

dialog empty.



procedure TForm1.SearchHelp;

var

  P: PChar;

begin

  Application.HelpFile := 'c:\delphi\bin\delphi.hlp';

  P := StrNew('');

  Application.HelpCommand(Help_PartialKey, longint(P));

  StrDispose(P);

end;



DISCLAIMER: You have the right to use this technical information

subject to the terms of the No-Nonsense License Statement that

you received with the Borland product to which this information

pertains.



A:

  Here's my Help unit.  You may find some of the routines down

  at the bottom useful -  e.g. look for WinHelpTopic.  Let me

  know if you need any of the routines which it calls:





{----------------------------------------------------------------}

{                                                                }

{    The Pascal Factory - Delphi Tools Library - Help unit       }

{                                                                }

{    Routines for easy implementation of Windows Help & Hints.   }

{----------------------------------------------------------------}

                  {c 1990-1996 Mike O'Hanlon, The Pascal Factory.}

unit Help;



{$R HELPCURS.RES}



interface

 uses

   Controls,      {for TControl}

   Graphics;      {for TColor}



 procedure PaleYellowHints;

 function  QuestionMarkCursor: Boolean;

 procedure RemoveHint (var Hint: THintWindow);

 function  RevealHint (Control: TControl; Color: TColor)

                      : THintWindow;

 procedure ResetQuestionMarkCursor;

 procedure SetQuestionMarkCursor;

 procedure WinHelpContents;

 procedure WinHelpForForm (Sender: TObject);

 procedure WinHelpForFormTab (Sender: TObject);

 procedure WinHelpQuit;

 procedure WinHelpSearch;

 procedure WinHelpTopic (const Topic: string);





implementation

 uses

   Basics,        {for RemoveFirst}

   Classes,       {for Bounds}

   Errors,        {for Err handling}

   ExtCtrls,      {for TNotebook}

   Extras,        {for InstallCursor}

   Forms,         {for TForm}

   SysUtils,      {for StrPCopy}

   TabNotBk,      {for TTabbedNotebook}

   WinProcs,      {for DrawText}

   WinTypes;      {for HELP_PARTIALKEY}



 const

   crQuestionMark = 1;

 var

   PreviousCursor: TCursor;





 procedure PaleYellowHints;

{----------------------------------------------------------------}

{ Makes all Hints for the application a bit paler than standard. }

{----------------------------------------------------------------}

 begin

   Application.HintColor := $00C1FFFF; {Very pale yellow}

 end;





 function QuestionMarkCursor: Boolean;

{----------------------------------------------------------------}

{ Returns state of cursor: true for question mark, else false.   }

{----------------------------------------------------------------}

 begin

   if Screen.Cursor = crQuestionMark

     then QuestionMarkCursor := true

     else QuestionMarkCursor := false;

 end;





 procedure RemoveHint (var Hint: THintWindow);

{----------------------------------------------------------------}

{ Releases the window handle of a Hint previously popped up with }

{ RevealHint.                                                    }

{----------------------------------------------------------------}

 begin

   Hint.ReleaseHandle;

   Hint.Free;

   Hint := nil;

 end;





 function RevealHint (Control: TControl; Color: TColor)

                     : THintWindow;

{----------------------------------------------------------------}

{ Pops up Hint window for the specified Control, and returns a   }

{ reference to the hint object so it may subsequently be removed }

{ with RemoveHint.                                               }

{----------------------------------------------------------------}

 var

   Outcome: THintWindow;

   ShortHint: string;

   AShortHint: array[0..255] of Char;

   HintPos: TPoint;

   HintBox: TRect;

   HeightOfText: Integer;

 begin

   { Create the window: }

   Outcome := THintWindow.Create(Control);

   if Color <> 0 then

     Outcome.Color := Color;

   { Get first half of hint up to '|': }

   ShortHint := GetShortHint(Control.Hint);

   { Calculate Hint Window position & size: }

   HintPos := Control.ClientOrigin;

   Inc(HintPos.Y, Control.Height + 6);

   HintBox := Bounds(0, 0, Screen.Width, 0);

   HeightOfText := DrawText(Outcome.Canvas.Handle,

       StrPCopy(PChar(@AShortHint), ShortHint), -1, HintBox,

       DT_CALCRECT or DT_LEFT or DT_WORDBREAK or DT_NOPREFIX);

   OffsetRect(HintBox, HintPos.X, HintPos.Y);

   Inc(HintBox.Right, 6);

   Inc(HintBox.Bottom, 2);

   { Now show the window: }

   Outcome.ActivateHint(HintBox, ShortHint);

   RevealHint := Outcome;

 end; {RevealHint}





 procedure ResetQuestionMarkCursor;

{----------------------------------------------------------------}

{ Resets cursor from Question Mark cursor.                       }

{----------------------------------------------------------------}

 begin

   PreviousCursor := 0;

   Screen.Cursor := PreviousCursor;

 end;





 procedure SetQuestionMarkCursor;

{----------------------------------------------------------------}

{ Store cursor (for later reset) and set Question Mark cursor.   }

{----------------------------------------------------------------}

 begin

   PreviousCursor := Screen.Cursor;

   Screen.Cursor := crQuestionMark;

 end;





 procedure WinHelpCommand (Command: Word; Data: Longint);

{----------------------------------------------------------------}

{ Calls Application.HelpCommand with the supplied parameters.    }

{ Displays an error message if HelpCommand returns false and     }

{ Debug information is on.                                       }

{----------------------------------------------------------------}

 var

   CommandStr: string;

 begin

   if not Application.HelpCommand(Command, Data) then

{$IFOPT D+}

   begin

     case Command of

       HELP_CONTENTS:   CommandStr := 'HELP_CONTENTS';

       HELP_PARTIALKEY: CommandStr := 'HELP_PARTIALKEY';

       HELP_QUIT:       CommandStr := 'HELP_QUIT';

       else             CommandStr := 'unknown';

     end; {case}

     Err(['Proc: WinHelpCommand',

          'Meth: Application.HelpCommand',

          'Win:  WinHelp',

          'HelpCommand call returned false result',

          'Command was ' + CommandStr]);

   end;

{$ENDIF}

 end;





 procedure WinHelpContents;

{----------------------------------------------------------------}

{ Calls the Windows Help engine and displays the Contents page.  }

{----------------------------------------------------------------}

 begin

   WinHelpCommand(HELP_CONTENTS, 0);

 end; {WinHelpContents}





 procedure WinHelpForForm (Sender: TObject);

{----------------------------------------------------------------}

{ Calls the Windows Help engine with a Topic built from the      }

{ ClassName (less leading 'T') of the parent Form of the Sender. }

{----------------------------------------------------------------}

 begin

 { Go up parent tree until Form is found: }

   while not (Sender is TForm) do

     Sender := TWinControl(Sender).Parent;

   WinHelpTopic(RemoveLeading('T', Sender.ClassName));

 end; {WinHelpForForm}





 procedure WinHelpForFormTab (Sender: TObject);

{----------------------------------------------------------------}

{ Calls the Windows Help engine with a Topic built from the      }

{ ClassName (less leading 'T') of the parent Form of the Sender. }

{ If the form has a (visible) Notebook or TabbedNotebook on it,  }

{ the name of the displayed Tab (less '&' accelerator character) }

{ is appended to the Topic.                                      }

{----------------------------------------------------------------}

 var

   Tab: string;

   I: Integer;

 begin

 { Go up parent tree until Form is found: }

   while not (Sender is TForm) do

     Sender := TWinControl(Sender).Parent;

 { Check components on Form for visible Notebook/TabbedNotebook: }

   Tab := '';

   with TForm(Sender) do

     for I := 0 to ComponentCount - 1 do

       if TControl(Components[I]).Visible then

         if (Components[I] is TNotebook) then

         begin

           with TNotebook(Components[I]) do

             Tab := '_'+ RemoveFirst('&', Pages[PageIndex]);

           Tab := RemoveAll(' ', Tab);

           Break; {out of for loop}

         end

         else if (Components[I] is TTabbedNotebook) then

         begin

           with TTabbedNotebook(Components[I]) do

             Tab := '_'+ RemoveFirst('&', Pages[PageIndex]);

           Tab := RemoveAll(' ', Tab);

           Break; {out of for loop}

         end;

   WinHelpTopic(RemoveLeading('T', Sender.ClassName) + Tab);

 end; {WinHelpForFormTab}





 procedure WinHelpQuit;

{----------------------------------------------------------------}

{ Should be called before app exits.  WinHelpQuit calls Windows  }

{ Help engine and informs it that Help is no longer needed.  If  }

{ no other applications have asked for Help, WinHelp is closed.  }

{----------------------------------------------------------------}

 begin

   WinHelpCommand(HELP_QUIT, 0);

 end; {WinHelpQuit}





 procedure WinHelpSearch;

{----------------------------------------------------------------}

{ Calls the Windows Help engine and brings up the Search dialog. }

{----------------------------------------------------------------}

 const

   ForceSearch = '???';

 var

   AStr255: array[0..255] of Char;

   Data: Longint;

 begin

   WinHelpContents;

   Data := Longint(StrPCopy(PChar(@AStr255), ForceSearch));

   WinHelpCommand(HELP_PARTIALKEY, Data);

 end; {WinHelpSearch}





 procedure WinHelpTopic (const Topic: string);

{----------------------------------------------------------------}

{ Calls Windows Help engine and looks for the supplied Topic.    }

{ If more than one match or no match, brings up Search dialog.   }

{----------------------------------------------------------------}

 var

   AStr255: array[0..255] of Char;

   Data: Longint;

 begin

   Data := Longint(StrPCopy(PChar(@AStr255), Topic));

   WinHelpCommand(HELP_PARTIALKEY, Data);

 end; {WinHelpTopic}





initialization

  PreviousCursor := 0;

  InstallCursor('QUESTIONMARKCURSOR', crQuestionMark);

end.





  Hope something in there (Win)Helps...



A:

I have written a THelper component, which provides additional Help

features. Here are the source files HELPER.PAS, HELPCONS.PAS and 

HELPER.RC



-------------- chew off here for HELPER.PAS

unit Helper;



interface



uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs;



type

  EHelperError = class(Exception)

  end;



  THelper = class(TComponent)

  protected

    procedure Check(Condition: Boolean; Operation: Word);

  public

    procedure ShowContents;

    procedure SearchTopic(const Topic: string; Partial: Boolean);

    procedure ShowContext(ContextNumber: LongInt); procedure

    ShowContextString(const ContextString: string); procedure

    SearchDialog; procedure HelpMacro(const MacroName: string);

    procedure HelpOnHelp; 

  end;



procedure Register;



implementation



{$R HELPER.RES}



uses

  HelpCons;



procedure Register;

begin

  RegisterComponents('Lance', [THelper]);

end;



{ THelper Component }



procedure THelper.Check(Condition: Boolean; Operation: Word);

const

  MaxMsg = 64;

var

  Msg:    PChar;

  PasMsg: string;

begin

  if not Condition then

  begin

    Msg := StrAlloc(MaxMsg + 1);

    try

      LoadString(HInstance, Operation, Msg, MaxMsg);

      PasMsg := StrPas(Msg);

      raise EHelperError.Create(PasMsg);

    finally

      StrDispose(Msg);

    end;

  end;

end;



procedure THelper.SearchTopic(const Topic: string; Partial: Boolean);

var

  Key:      PChar;

  HelpFile: PChar;

  Command:  Word;

begin

  Key := StrAlloc(Length(Topic) + 1);

  try

    StrPCopy(Key, Topic);

    HelpFile := StrAlloc(Length(Application.HelpFile) + 1);

    try

      StrPCopy(HelpFile, Application.HelpFile);

      Check(Application.HelpCommand(HELP_FORCEFILE, 0),

      SHelpCantHelp); if Partial then

        Command := HELP_PARTIALKEY

      else

        Command := HELP_KEY;

      Check(Application.HelpCommand(Command,

                    LongInt(Key)), SHelpCantShowHelpFile);

    finally

      StrDispose(HelpFile);

    end;

  finally

    StrDispose(Key);

  end;

end;



procedure THelper.ShowContents;

var

  HelpFile: PChar;

begin

  HelpFile := StrAlloc(Length(Application.HelpFile) + 1);

  try

    StrPCopy(HelpFile, Application.HelpFile);

    Check(Application.HelpCommand(HELP_FORCEFILE, 0), SHelpCantHelp);

    Check(Application.HelpCommand(HELP_CONTENTS,

                  0), SHelpCantShowTOC);

  finally

    StrDispose(HelpFile);

  end;

end;



procedure THelper.ShowContext(ContextNumber: LongInt);

var

  HelpFile: PChar;

begin

  HelpFile := StrAlloc(Length(Application.HelpFile) + 1);

  try

    StrPCopy(HelpFile, Application.HelpFile);

    Check(Application.HelpCommand(HELP_FORCEFILE, 0), SHelpCantHelp);

    Check(Application.HelpCommand(HELP_CONTEXT,

                  ContextNumber), SHelpCantShowCTX);

  finally

    StrDispose(HelpFile);

  end;

end;



procedure THelper.SearchDialog;

begin

  SearchTopic('', True);

end;



procedure THelper.HelpMacro(const MacroName: string);

var

  Key:      PChar;

  HelpFile: PChar;

  Command:  Word;

begin

  Key := StrAlloc(Length(MacroName) + 1);

  try

    StrPCopy(Key, MacroName);

    HelpFile := StrAlloc(Length(Application.HelpFile) + 1);

    try

      StrPCopy(HelpFile, Application.HelpFile);

      Check(Application.HelpCommand(HELP_FORCEFILE, 0),

      SHelpCantHelp); Check(Application.HelpCommand(HELP_COMMAND,

                    LongInt(Key)), SHelpCantMacro);

    finally

      StrDispose(HelpFile);

    end;

  finally

    StrDispose(Key);

  end;

end;



procedure THelper.HelpOnHelp;

begin

  HelpMacro('HelpOn()');

end;



procedure THelper.ShowContextString(const ContextString: string);

begin

  Check(Application.HelpCommand(HELP_FORCEFILE, 0), SHelpCantHelp);

  Check(Application.HelpJump(ContextString), SHelpCantShowTopic);

end;



end.



---------------- chew here for HELPCONS.PAS



unit Helpcons;



interface



const

 SHelpCantHelp          = 30000;

 SHelpCantShowTopic     = SHelpCantHelp + 1;

 SHelpCantShowContext   = SHelpCantShowTopic + 1;

 SHelpCantShowHelpFile  = SHelpCantShowContext + 1;

 SHelpCantShowTOC       = SHelpCantShowHelpFile + 1;

 SHelpCantShowCTX       = SHelpCantShowTOC + 1;

 SHelpCantMacro         = SHelpCantShowCTX + 1;



implementation



end.



---------------- chew here for HELPERRC



#include "helpcons.pas"



STRINGTABLE 

{

 SHelpCantHelp, "Can't open helpfile"

 SHelpCantShowTopic, "Can't show help topic"

 SHelpCantShowContext, "Can't show Helpcontext"

 SHelpCantShowHelpFile, "Can't search helpfile"

 SHelpCantShowTOC, "Can't show help contents"

 SHelpCantShowCTX, "Can't show help by contextnumber"

 SHelpCantMacro, "Can't execute help macro"

}


HelpFiles

Question


Can you please tell me how to execute a .hlp file from my app.?

Answer


A:

Executing help file in delphi is very easy. All you have to do is just

assigning Application.HelpFile property and the HelpContext property of each

component you have.



Following example demonstrate how to call a help content in 'MYHELP.HLP'

assigned with a context number on [MAP] section in your help project file.



You can get the help content by pressing F1 or the help button (HelpBtn).



.........



[MAP]

demo    2000;



.........



procedure Form1.FormCreate(sender: TObject);

begin

   Application.HelpFile := 'MYHELP.HLP';

   HelpContext := 2000;

end;



procedure Form1.HelpBtnClick(Sender:TObject);

begin

   Application.HelpContext(HelpContext);

end;



A:

Begin

Application.HelpCommand(HELP_CONTENTS, 0);

end;



Pop that into an event handler.  Make sure you specify the application

help file in the project options first.


Searching your application's help file

Question


How can I search in application's help file?

Answer


{

  The following code demonstrates how to bring up the WinHelp "Search"

  dialog for your application's help file.  You can use TApplication's

  HelpCommand method to send the Help_PartialKey command to the WinHelp

  system. The parameter for this command should be a PChar (cast to a

  longint to circumvent typechecking) that contains the string on

  which you'd like to search.  The example below uses an empty string,

  which invokes "Search" dialog and leaves the edit control in the

  dialog empty.

}

procedure TForm1.SearchHelp;

var

  P: PChar;

begin

  Application.HelpFile := 'c:\delphi\bin\delphi.hlp';

  P := StrNew('');

  Application.HelpCommand(Help_PartialKey, longint(P));

  StrDispose(P);

end;




Close    To Top
  • Prev Article-Programming: None
  • Next Article-Programming:
  • Now: Tutorial for Web and Software Design > Programming > delphi > Programming Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction