Many WinHelp3 developers have asked "How can I set up FTS in a Windows 3.x helpfile running on a Win3.x machine?"
There are several good HATs (Help Authoring Tools) that will do this, but you might find that you don't need them. The 16-bit FTS engine from Version 1.0 of Microsoft's Multimedia Developer's Kit (MDK) does the job very well.
One of the really nice things about the MDK Search engine is that it "hits". And it can recall previous searches from VIEWER.INI, in your Window directory. (VIEWER.INI is also used by a whole range of other products.)
Here are the six simple steps to creating an indexed WinHelp3 file - or an indexed multi-file suite, if you wish:
The files you need from the MDK are:
The DLLs are generally easy to find, as they were distributed to support early MDK products,
Viewer 1.0 has long since been superseded, so you might have to look around a bit for the
executables. (Later versions used a different search engine which doesn't work with WinHelp3.)
The indexing EXEs (FORAGE, W_SCAN and INDEX) were included in the MS Developer's Library
The whole package, including GETMLT, is available for download from HelpMaster as FTSKIT16.ZIP and also from Jon Noring's site as FTSKIT.ZIP.
Assume a Windows Help project called FRED1. You must tell WinHelp which full-text search routines to use. In the project file FRED1.HPJ, add these lines to whatever you'd normally have in the [CONFIG] and [BAGGAGE] sections:
[CONFIG]Save FRED1.HPJ. If you are creating a multi-helpfile index, repeat the above for each .HPJ file.
; initialize DLLs
RR("ftengine", "LoadFTEngine", "U")
RR("ftui", "InitRoutines", "SU")
; declare the main routines
RR("ftui", "ExecFullTextSearch", "USSS")
RR("ftui", "SwitchToTopicsFound", "U")
; provide ways to use them
; letter "F"
; bag.ini must be all lower case. Baggage filenames are case sensitive.
The .HPJ file(s) refer to a bag.ini file. This is a plain text (ASCII) file, that tells the FTS engine the name of the index file, and whether the index is to be shared by multiple helpfiles. It contains a line to say how many helpfiles are included (groupcount), a line for each group which records the name of its helpfile, and two lines for each group (helpfile), showing the title which should be used in the Search dialog and the name of the index file.
For a single helpfile called FRED1.HLP, if the index file is to be FRED.IND, bag.ini should look like this:
[bag.ini]If two or more helpfiles are to share an index, change the groupcount and separately define each group and its title. Since the .IND file is to be shared, all the Indexfile= lines must be identical. Up to 15 groups can share a common index.
If FRED1.HLP and FRED2.HLP are to share the index FRED.IND, bag.ini should look like this:
[bag.ini]All the helpfiles must use the same bag.ini file. It is preferable that all the helpfiles be compiled in a common directory. If this is not convenient, copy bag.ini to each of the directories where their .HPJ files are, before compiling the .HLP files. (After compiling, you will have to move the helpfiles to a common directory for indexing.)
Next you'll need a field-description file, GENERIC.FLD, which is a simple textfile containing the following lines:
topic [inline, search, stop](The one file can be used for all your indexing projects.)
filename [catalog, string]
address [catalog, fixed(4)]
length [catalog, fixed(4)]
topicTitle [catalog, trunc(32)]
topicNSR [inline, search, stop]
You won't want your searches to be clogged by common or noise words. You can use an ASCII text stop-words file (GENERIC.STP) to exclude listed words from the index.
The words in my GENERIC.STP are:
0 1 2 3 4 5 6 7 8 9 a an and as at be but by do for from have he in it me not of on or she that the there they this to us we when where which with you
Note, though, that each excluded word should be entered on a separate line in the file, like this:
0You can add words to this list, or use a different list of stop-words for each project. If you work in a language other than English, you could create your own file for each language you use. The file does not have to be named GENERIC.STP - it could be called
One drawback of the
OK, you now have your HPJ, bag.ini, and the FLD and STP files, so you're ready to compile the helpfile(s) and create the full-text index. You can do it the easy way or the hard way. The easy way is to use the batch file below. I call it INDXHLP.BAT, but you could use almost any other name if you wish. (Just change the fifth line, for consistency.)
INDXHLP.BAT takes a list of parameters which tell it which helpfiles are to be indexed, followed by the name of the index file (as defined in bag.ini).
It then compiles each of those helpfiles, indexes the whole suite, and deletes all workfiles.
It can be used to index just one helpfile, or up to 15 (the maximum allowed by the indexing software).
rem At least two parameters must be given
if not .%2==. goto :Doit
echo INDXHLP hlp1 hlp2....hlp15 index
echo "hlp1..." are names of one to fifteen .HPJ files
echo (but without the .HPJ extension)
echo which describe the helpfiles to be compiled and indexed
echo "index" is the name of the .IND file to be produced
echo (ie. the name defined in bag.ini)
echo IMPORTANT!! the index name MUST be the LAST parameter!!
rem Delete all old PH files
if exist *.PH del *.PH
rem Compile all - produce HLP, PH, BUG (errorlog defined in HPJ)
rem Compile first-listed HLP
rem Get next parameter
rem While there is another HLP to do...
if not .%2==. goto :Loopit
rem ...otherwise, the only remaining parameter (now %1) is the IND filename
rem Semicolon prevents prompting, forces output filename BAG.MLT based on BAG.INI
rem Produce one or more ANS files, each named for their HLP file
forage /m BAG.MLT
rem Produce WRS, OCA, ZON, ZOS, CFG using first param to w_scan (%1) as filename
rem ANS input files are identified by BAG.MLT
rem Produce CFG and IND with filename %1
rem Now clean up the directory
if exist *.PH del *.PH
rem Change the next line if your HCP errorlogs don't have a BUG extension
if exist *.BUG del *.BUG
for %%f in (CFG OCA WRS ZON ZOS) do del *.%%f
A few things to note:
That's it. Whenever you're ready, run IDXHLP.BAT. It should produce an .IND file to go with your product. When you distribute the help file(s), just make sure that you also include the .IND and the FTUI, FTENGINE and MVAPI DLLs.
OK - over to you. And good luck!
So you want to do it the hard way? Or maybe you just want to know more about the syntax of the MDK indexing programs?
Although the material available to me (from unknown sources) gave a good explanation of how to use the MDK tools, I did some additional testing to clarify the usage of GETMLT, FORAGE, W_SCAN and INDEX. The results are still incomplete, but they might be useful to you. However, this page is long enough already, so I won't document them here.
Instead, I've included those results in one of two demo helpfiles (what else?) built with the batch file above. Oddly enough, it's called FRED2.HLP. The other one of the pair (FRED1.HLP) contains the full text of this page as a handy reference.
Click to download FRED.ZIP (115KB).
By the way - you don't need to recompile your FTS-capable WinHelp3 product for your Win95 clients. Just ship it as is. The custom FTS button will still work, although it will display the Win95 Search dialog instead of the rather more useful MDK dialog. (Your carefully-constructed .IND file will be ignored - Win95 will create its own index.)
You must still include the MDK DLLs - the helpfile won't start up properly without them, although I don't know whether they are actually used under Win95.
And you should consider including a .CNT file, particularly if the product is a multi-file suite. FRED.ZIP includes a simple .CNT for each of its helpfiles, to save you the the trouble of making them. If you want more information on .CNTs for running WinHelp3 files on Win95, check http://www.pcug.org.au/~jcarroll/whcnt.htm