HTML Help keyword lookup

2019-02-16 01:11发布

问题:

I'm having trouble figuring out how to get keyword lookups (HH_KEYWORD_LOOKUP) to work in HTML Help. If I have an index that displays like this:

Machine
    Add
    Edit
    Selection

How do I specify a keyword search that brings up Machine Selection? "Machine; Selection" brings up the Machine keyword; "Selection" and "Machine Selection" don't work at all; neither does "Machine, Selection", even though that's what's displayed in the Index tab of the HTML Help Viewer if the user manually selects the appropriate topic.

回答1:

I think I read (in my many google searches) that HH_KEYWORD_LOOKUP is broken in HTML help, sigh. So Ie came up with this solution to do a search. It will bring up the chm file and enter the keyword into the search box and press the ENTER key to manually do the search.

procedure PostKey(aKey: Word; const aShift: TShiftState; aSpeciaKey: Boolean);
type
  TShiftKeyInfo = record
    shift: Byte;
    vkey: Byte;
  end;
  byteset = set of 0..7;
const
  shiftkeys: array [1..3] of TShiftKeyInfo =
    ((shift: Ord(ssCtrl); vkey: VK_CONTROL),
    (shift: Ord(ssShift); vkey: VK_SHIFT),
    (shift: Ord(ssAlt); vkey: VK_MENU));
var
  flag: DWORD;
  bShift: ByteSet absolute aShift;
  i: Integer;
begin
  for i := 1 to 3 do
  begin
    if shiftkeys[i].shift in bShift then
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0);
  end; { For }
  if aSpeciaKey then
    flag := KEYEVENTF_EXTENDEDKEY
  else
    flag := 0;
  keybd_event(aKey, MapvirtualKey(aKey, 0), flag, 0);
  flag := flag or KEYEVENTF_KEYUP;
  keybd_event(aKey, MapvirtualKey(aKey, 0), flag, 0);
  for i := 3 downto 1 do
  begin
    if shiftkeys[i].shift in bShift then
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0),
        KEYEVENTF_KEYUP, 0);
  end; { For }
end;

procedure CHMSearch(aCHMFilename, aSearch: string);
var
  cfn: string;
  qry: THHFtsQuery;
  hnd: HWND;

  procedure DoSearch(aMsg: string);
  var
    i,n: Integer;
    c: Char;
    shift: TShiftState;
  begin
    if hnd = 0 then Exit;
    Windows.SetFocus(hnd);
    n := Length(aMsg);
    if n > 0 then
    begin
      for i := 1 to n do
      begin
        c := aMsg[i];
        shift := [];
        case c of
          'a'..'z': shift := [];
          'A'..'Z': shift := [ssShift];
          '_': // underscore key
          begin
            keybd_event(VK_SHIFT, 0, 0, 0);
            keybd_event(VK_OEM_MINUS, 0, 0, 0);
            keybd_event(VK_OEM_MINUS, 0, KEYEVENTF_KEYUP, 0);
            keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
            continue;
          end;
          '$': // $ key
          begin
            PostKey(Ord('4'), [ssShift], False);
            continue;
          end;

        end;
        PostKey(Ord(UpCase(c)), shift, False);
      end;
      PostKey(VK_RETURN, [], False);
      PostKey(VK_RETURN, [], False);
    end;
  end;

begin
  cfn := ChangeFileExt(aCHMFilename, '.chm');
  FillChar(qry, SizeOf(qry), 0);
  qry.cbStruct := SizeOf(THHFtsQuery);
  qry.fExecute := TRUE;
  HH.HtmlHelpA(GetDesktopWindow, PAnsiChar(AnsiString(cfn)), HH_DISPLAY_TOC, 0);
  hnd := HH.HtmlHelpA(GetDesktopWindow, PAnsiChar(AnsiString(cfn)), HH_DISPLAY_SEARCH,
    Cardinal(@qry));
  DoSearch(aSearch);
end;


回答2:

Ahaa!!!

After one hours' typing and trying, I figured out that TWO SPACES are needed between the first level keyword and second level keyword, and an "Enter" key is needed at last to show the topic linked from the second keyword!!!!

Remember, exactly two spaces! one or three does not work. The trick is, while typing the second space and second keyword, some other keyword get highlighted in the list of keywords, which can make you think you have already made a mistake and would not continue to finish typing the second keyword! Is this a hoax by Microsoft engineer?

However, although manually it works, seems the software API does not work immediately with the TWO spaces. If I call the following API in C# upon F1 key pressed (I have to use "space" to represent a space here because this website trims two space to one if I use real space):

System.Windows.Forms.Help.ShowHelp(this, "file:///C:/apps/MyHelpContentNew/QACT.chm", System.Windows.Forms.HelpNavigator.KeywordIndex, "key2'space''space'x_subkey_of_key2");

it does not show the topic linked from x_subkey_of_key2. But it's almost there, the Help Window shows up with correct two levels' keywords put in the search TextBox, only missing a "Car-Return"!

Then I tried to add the car-return like this:

System.Windows.Forms.Help.ShowHelp(this, "file:///C:/apps/MyHelpContentNew/QACT.chm", System.Windows.Forms.HelpNavigator.KeywordIndex, "key2'space''space'x_subkey_of_key2\n");

It doesn't work either. So I guess I need send a car-return key to the Help Window programmingly. Will post if I once I implement it.



标签: chm