Skip to content

F1 and the screen context ​

The difference between a chatbot and a help assistant is that the second one knows where the user is when they ask. HelpChatAI builds that context natively, on the main thread, and hands it to the provider — the chat page never sends it, so it cannot be stale or forged.

What the context contains ​

FieldWhere it comes from
ScreenNameName of the active form
ScreenLabelcaption of the active tab sheet, or of the form
ScreenTypeclass name of the form
HelpKeywordthe deepest HelpKeyword found
HelpContextthe deepest HelpContext found (when no keyword)
FocusedControlName of the focused control

The search starts at the focused control and walks up through its parents, with the form last: a grid with its own keyword wins over the tab sheet, which wins over the form. That is how one screen can have different help for different parts of it.

What the provider actually searches with is a search hint: the readable HelpKeyword when there is one, otherwise the screen label. Class names and internal component names are never used as search terms — they would only add noise.

Declaring the help of a screen ​

Use the standard Delphi properties. The value that works best is the title of the page of your manual, because that is what the retriever matches against:

pascal
// VCL
LeadsTab.HelpType := htKeyword;
LeadsTab.HelpKeyword := 'Leads';          // the title of a page of the manual

// numbers work too, if your manual is indexed by context id
OrdersForm.HelpType := htContext;
OrdersForm.HelpContext := 4040;

In FireMonkey the same properties live on TStyledControl (forms do not have them): put them on tabs and panels.

What F1 does ​

Two mechanisms, in this order:

  1. The Delphi help system. With RegisterHelpViewer := True (the default) the component registers a viewer implementing ICustomHelpViewer and IExtendedHelpViewer. When a control in the chain declares help, the VCL routes F1 to the help system exactly as it would to a CHM viewer, and the help system calls HelpChatAI. Application.HelpKeyword(...), Application.HelpContext(...) and HelpShowTableOfContents reach it too.
  2. The fallback. Where nothing declares help — the VCL would do nothing at all — the component's own F1 handler opens the chat with the current screen, if HandleF1 is True.

This is why you should not hook Application.OnHelp yourself: what you declared already works, and mixing the two produces the classic double question.

Both mechanisms, one question

A key repeat, or a request that arrives twice, cannot send the same question twice: identical questions within 1.5 seconds are shown but sent once.

In FireMonkey there is no routing at all: see The FMX component.

Refining the context ​

OnGetContext is called every time the context is built, just before it is used:

pascal
procedure TMainForm.HelpChatGetContext(Sender: TObject; var AContext: THelpChatContext);
begin
  // a screen whose meaning depends on what it is showing
  if (AContext.ScreenName = 'DocumentForm') and (FDocument <> nil) then
    AContext.ScreenLabel := 'Documento ' + FDocument.Kind;
  // or a keyword you compute instead of declaring
  if AContext.HelpKeyword = '' then
    AContext.HelpKeyword := CurrentModuleHelpTopic;
end;

Use it also to remove things: if a screen label contains a customer name, blank it — only the screen name, label, type and keyword ever reach a provider, but that is still your data.

Asking about a screen from your own code ​

pascal
HelpChatAI.OpenForHelp('Leads', 0);                        // that screen
HelpChatAI.OpenForCurrentScreen;                           // what F1 does
HelpChatAI.OpenWithQuestion('How do I prepare a proposal?');  // a question of yours

And the standard way, which goes through the help system and therefore through HelpChatAI:

pascal
Application.HelpKeyword(PageControl.ActivePage.HelpKeyword);

Released under the Apache License 2.0