Undocumented Windows Help 3.1/4.0
The Good, the Bad, and the Ugly

Paul A. O'Rear

Helpful Solutions (owner)

Sageline Software (co-owner)

pao@sageline.com

 

Macros:

Windows Help 3.1:

ExtInsertItem

Usage ExtInsertItem(`menu-id', `item-id', `item-name', `macro', position, enabled-state)

- the position item is 0 based. An integer value that specifies the position of the menu item in the menu. Position 0 is the first position in the menu.

- enabled-state. See chart below

ExtInsertMenu

Usage ExtInsertMenu(`parent-id', `menu-id', `menu-name', position, enabled-state)

0 0x0 MF_ENABLED

1 0x1 MF_GRAYED

2 0x2 MF_DISABLED

+4 0x4 MF_BITMAP

+8 0x8 MF_CHECKED

+16 0x10 MF_POPUP (this is default)

+32 0x20 MF_MENUBARBREAK

+64 0x40 MF_MENUBREAK

+128 0x80 MF_HILITE

+256 0x100 MF_OWNERDRAW

+512 0x200 MF_USECHECKBITMAPS

2048 0x800 MF_SEPARATOR

* items in gray are not of direct use in WinHelp, but are provided for completeness.

ExtAbleItem

Usage ExtAbleItem(`item-id', enabled-state)

Despite the interesting things you can do with the enabled-state parameter of ExtInsertItem and ExtInsertMenu, ExtAbleItem is only aware of the MF_ENABLED and MF_GRAYED states and will not use any of the other states.

 

JumpHash

Usage JumpHash(`filename', hash-code)

Enables jumping to a topic based on the hash value derived from the topic id

PopupHash

Usage PopupHash(`filename', hash-code)

Enables jumping to a topic in a popup window based on the hash value derived from the topic id

Use the Hashed value of a topic's topic ID. TopicID Hasher.

Generate

Usage Generate(windows_message/WM_XXX, wParam, lParam)

The equivalent of SendMessage() for WinHelp only - skips the requirement of an RR() routine for SendMessage.

FloatingMenu

Usage FloatingMenu()

Launches the floating menu from a hotspot or anywhere else that a macro can be executed.

Command

Usage Command(command-number)

Uses the Resource IDs of any of the WinHelp elements as follows:

File|Open 1101

File|Print 1103

File|Exit 1105

Edit|Copy 1203

Edit|Annotate 1202

Bookmark|Define 1301

Bookmark|More 1302

(if Bookmarks are on the menu then they start with 1303 and increase from there)

Help|How to Use Help 10003

Help|Always on Top 10002

Help|About Help 1503

Items added to menus with any of the standard macros will be assigned numbers starting with 10004 in the order they are added.

 

Windows Help 4.0:

Command

Usage Command(command-number)

Uses the Resource IDs of any of the WinHelp elements as follows:

File|Open 1101

File|Print 1103

File|Exit 1105

Edit|Copy 1203

Edit|Annotate 1202

Bookmark|Define 1301

Bookmark|More 1302

(if Bookmarks are on the menu then they start with 1303 and increase from there)

Options|Keep Help on Top|Default 1470

Options|Keep Help on Top|On Top 1471

Options|Keep Help on Top|Not On Top 1472

Options|Display History Window 1453

Options|Font|Small 1462

Options|Font|Normal 1460

Options|Font|Large 1461

Options|Use System Colors 1465

Help|Version 1503

Tab

Usage Tab(num_custom_tab)

Tab() or Tab(0) -- Find

Tab(n) -- Custom Tab n

Tab(n + 1) -- Contents (if no custom tabs are defined, then Tab(1) brings

up the contents.

Notes on Tabs: From the API when Help is not yet launched, most normal methods of obtaining a specific tab fail. If you want the Contents tab use Tab(n+1), if you want the Find tab use Tab(0), if you want the Index tab, you must use the HELP_PARTIALKEY command with an empty string. Once help is launched most navigation methods work as expected; it's in the launching that it breaks down.

ExtInsertItem/Menu notes:

In WinHelp 4.0 these two macros do not work properly with the floating menu. A long standing complaint. Separators show up as blank areas, and sub-menus are not created.

ShowInWindow

Usage ShowInWindow(`window_name') or SW(`window_name')

Causes the current topic to be displayed in the window type passed in the window_name parameter.

In order to make this work correctly, the macro needs to be followed with a Generate() macro call that forces the topic to be repainted:

Generate(1030, 0, 1) - this is an undocumented native method that WinHelp itself uses to force a repaint of a topic.

ex. SW(`proc4'):Generate(1030, 0, 1)

Only the short form of this macro works?

FlushMessageQueue = Flush() = FH()

Same as Flush macro - forces WinHelp to finish processing the messages in its message queue before proceeding with the next macro.

JumpWindow

Same as UpdateWindow() and was apparently the original name. If you check your HCW.HLP file you'll see UpdateWindow() listed with JW() as the short form... If JumpWindow() makes more sense to you, you can use it - the compiler accepts it and uses it properly.

The UGLY - macros that appear in the compiler and that will compile, but that don't work...

BrowseForHelpFile()

ShowFolder()

both compile without any questions, but neither appear to work.

- when compiled and executed WinHelp specifies that this macro requires a windows 4.1 help file.

Undocumented ShortCut Forms:

AN() for Annotate()

DEB() for DestroyWindow()

EP() for ExecProgram() which is still functional in WinHelp 4.0

TC() for TCard()

Add your own custom check marks to your help system with this interesting method:

Automatic Conversion of RegisterRoutine parameters.

There's a nice little feature that WinHelp has that helps in the use of API functions as macros in help files - RegisterRoutine() macro. Unfortunately, as many have found out using 16-bit DLLs with 32-bit help files can cause nightmares on Windows NT. The good news? WinHelp has some internal code that actually translates calls to a few specific OS DLLs that are used for Windows API calls, that will work whether you're on NT or not. Here's how it works:

1) first it checks if the DLL has any extension present; if not it appends ".DLL"

2) if the DLL passed is either "USER.DLL" or "USER.EXE" it converts it to "USER32.DLL"

3) if the DLL passed is either "GDI.DLL" or "GDI.EXE" it converts it to "GDI32.DLL"

4) if the DLL passed is "mmsystem.dll" it converts it to "winmm.dll"

5) on NT if it can't open the DLL it will report it missing.

6) if on 95 it will create a thunk and try to open it. If it can't do this it will report it missing.

7) it will try to get the address of the function from the DLL.

8) if it fails and the DLL passed (or modified to) is either "USER32.DLL" or "winmm.dll" it will append an "A" to the function name and try to get the address of the function again.

9) if both of these methods of obtaining the function address fail and Help Author mode is on, a message will be reported stating that

"The function xxx could not be found in xxx."

providing you with some help as to what the problem may be.

Plus: in WinHelp 4.0, the parameter list to functions passed via RR() is not case sensitive as it was in WinHelp 3.1x.

In WinHelp 3.1, RR() parameters had the following variations:

Character

Data type

Equivalent Windows data type

u

Unsigned short integer

UINT, WORD, WPARAM

U

Unsigned long integer

DWORD

i

Signed short integer

BOOL (also C int or short)

I

Signed long integer

LONG, LPARAM, LRESULT

s

Near pointer to a null-terminated text string

PSTR, NPSTR

S

Far pointer to a null-terminated text string

LPSTR, LPCSTR

v

Void (means no type; used only with return values)

None. Equivalent to C void data type.

in WinHelp 4.0 and in the 32-bit operating systems all values are long/32-bits so that the parameters have the following variations:

Character

Description

U or u

unsigned number

I or i

signed number

S or s

string

v

type unknown

=

The character previous to this one is the return type of the parameter.

This makes conversion of Windows API calls whose own parameter types didn't change except for the size of their data types (16-32-bits) virtually transparent and not requiring any special effort on the help author's part. It also makes it possible to use help files that use some fancy techniques only from API calls portable across all operating systems.

The WinHelp API

Windows Help 3.1:

undocumented calls:

HELP_QUIT2

= 6

'HEX 6h

- same as HELP_QUIT

HELP_SHOWWINDOW

= 7

'HEX 7h

- will simply bring WinHelp back into focus - or if it was intentionally hidden by the calling application, will show it again.

HELP_HASH

= 149

'HEX 95h

- equivalent to the JumpHash() macro - dwData is hashnumber

HELP_HASH_POPUP

= 150

'HEX 96h

- equivalent to the PopupHash() macro - dwData is hashnumber

HELP_TOPIC_ID

= 259

'HEX 103h

- equivalent to the JumpID() macro - dwData is topic id string

HELP_TOPIC_ID_POPUP

= 260

'HEX 104h

- equivalent to the PopupID() macro - dwData is topic id string

HELP_FOCUSWINDOW

= 262

'HEX 106h

- will bring a particular help window into focus - dwData is windowname string

HELP_CLOSEWINDOW

= 263

'HEX 107h

- equivalent to CloseWindow() macro - dwData is windowname string

HELP_CONTEXTNOFOCUS

= 264

'HEX 108h

- same as HELP_CONTEXT, but doesn't give the window focus.

HELP_VARIOUS

= 514

'HEX 202h

- this is a special call WinHelp will issue to itself under various circumstances with prior conditions - it appears normally unable to be called from outside of WinHelp - dwData is frequently the value 0xA.

 

full list for WinHelp3.1

HELP_CONTEXT

= 1

'HEX 1h

HELP_QUIT

= 2

'HEX 2h

HELP_INDEX

= 3

'HEX 3h

HELP_CONTENTS

= 3

'HEX 3h

HELP_HELPONHELP

= 4

'HEX 4h

HELP_SETINDEX

= 5

'HEX 5h

HELP_SETCONTENTS

= 5

'HEX 5h

HELP_QUIT2

= 6

'HEX 6h

HELP_SHOWWINDOW

= 7

'HEX 7h

HELP_CONTEXTPOPUP

= 8

'HEX 8h

HELP_FORCEFILE

= 9

'HEX 9h

HELP_HASH

= 149

'HEX 95h

HELP_HASH_POPUP

= 150

'HEX 96h

HELP_KEY

= 257

'HEX 101h

HELP_COMMAND

= 258

'HEX 102h

HELP_TOPIC_ID

= 259

'HEX 103h

HELP_TOPIC_ID_POPUP

= 260

'HEX 104h

HELP_PARTIALKEY

= 261

'HEX 105h

HELP_FOCUSWINDOW

= 262

'HEX 106h

HELP_CLOSEWINDOW

= 263

'HEX 107h

HELP_CONTEXTNOFOCUS

= 264

'HEX 108h

HELP_MULTIKEY

= 513

'HEX 201h

HELP_VARIOUS

= 514

'HEX 202h

HELP_SETWINPOS

= 515

'HEX 203h

 

Windows Help 4.0:

HELP_CONTEXT

= 1

'HEX 1h

HELP_QUIT

= 2

'HEX 2h

HELP_INDEX

= 3

'HEX 3h

HELP_CONTENTS

= 3

'HEX 3h

HELP_HELPONHELP

= 4

'HEX 4h

HELP_SETINDEX

= 5

'HEX 5h

HELP_SETCONTENTS

= 5

'HEX 5h

HELP_QUIT2

= 6

'HEX 6h

HELP_SHOWWINDOW

= 7

'HEX 7h

HELP_CONTEXTPOPUP

= 8

'HEX 8h

HELP_FORCEFILE

= 9

'HEX 9h

HELP_CONTEXTMENU

= 10

'HEX Ah

HELP_FINDER

= 11

'HEX Bh

HELP_WM_HELP

= 12

'HEX Ch

HELP_SETPOPUP_POS

= 13

'HEX Dh

HELP_FORCE_GID

= 14

'HEX Eh

HELP_TAB

= 15

'HEX Fh

HELP_TCARD_DATA

= 16

'HEX 10h

HELP_TCARD_OTHER_CALLER

= 17

'HEX 11h

HELP_HASH

= 149

'HEX 95h

HELP_HASH_POPUP

= 150

'HEX 96h

HELP_KEY

= 257

'HEX 101h

HELP_COMMAND

= 258

'HEX 102h

HELP_TOPIC_ID

= 259

'HEX 103h

HELP_TOPIC_ID_POPUP

= 260

'HEX 104h

HELP_PARTIALKEY

= 261

'HEX 105h

HELP_FOCUSWINDOW

= 262

'HEX 106h

HELP_CLOSEWINDOW

= 263

'HEX 107h

HELP_CONTEXTNOFOCUS

= 264

'HEX 108h

HELP_MULTIKEY

= 513

'HEX 201h

HELP_VARIOUS

= 514

'HEX 202h

HELP_SETWINPOS

= 515

'HEX 203h

HELP_TCARD

= 32768

'HEX 8000h

 

Help Topics Tab definitions for use with HELP_TAB

CUSTOM_TAB

= 0

FIND_TAB

= -1

INDEX_TAB

= -2

CONTENTS_TAB

= -3

 

DLLs:

Undocumented LGetInfo values (16-bit):

GI_HDE

0x64

Handle to Display Environment struct

GI_CURFM

0x65

Handle to current open filename

GI_FFATAL

0x66

Fatal Exit flag

GI_GETCURWINTYPE

0x67

Handle to current window type string

GI_FPRINTING

0x68

Busy executing macro or printing flag

undocumented LGetInfo values (32-bit):

GI_LCID

0x9

Handle to LCID of helpfile

GI_CURFM

0x65

Handle to current open filename

GI_FFATAL

0x66

Fatal Exit flag

GI_FPRINTING

0x68

Busy executing macro or printing flag

 

Undocumented Callback Functions:

cf. my help files available for Internal functions, RR declarations, HELPDECO file format stuff.

 

Undocumented common WinHelp structures:

HFS, FSHEADER_RAM, FSH, and BTH

hfs = pointer to an FSHEADER_RAM structure of the following construction:

typedef struct tagFSHEADER_RAM

{
FSH * fsh;
BTH * hbt;
UINT fid;
LPSTR fm;
}

where FSH is a structure of the following construction:

typedef struct tagFSH

{
WORD wMagic;
BYTE bVersion;
BYTE bFlags;
LONG lifDirectory;
LONG lifFirstFree;
LONG lifEof;
}

and BTH is a structure of the following construction:

typedef struct tagBTH

{
WORD wMagic;
BYTE bVersion;
BYTE bFlags;
WORD cbBlock;
CHAR rgchFormat[15];
short bkFirst;
short bkLast;
short bkRoot;
short bkFree;
short bkEOF;
short cLevels;
DWORD lcEntries;
}

Undocumented special versions of WinHelp available through MSDN:

WinHelp 3.1/3.50.900 (32-bit version) - including BTree and Internal File System test dialogs, add-button, execute macro, etc.

WinHelp 4.0 - including special error and processing messages as well as extra floating menu options.