An MSHTML Import Library

Only a handful of functions exported by MSHTML.DLL are formally documented in the Windows SDK. The MSHTMHST.H header file has prototypes for the documented functions and for one more:

Armed with these prototypes, a programmer who seeks to use one of these functions might naturally just name the function in a function call. The linker would resolve the reference from an import library, so that when the executable is loaded, the system loads MSHTML.DLL, locates the function and stores its address wherever the linker provided. To the programmer, it couldn’t be easier. Very likely the overwhelming bulk of real-world programmers don’t even think for a moment, or even know, about how any of this works.

For the MSHTML functions, the SDK would instead have the programmer write some supporting code that uses LoadLibrary to load MSHTML.DLL, uses GetProcAddress to locate the function, and then calls the function indirectly. For some, but not all, of the above functions, the SDK helpfully defines types for the function pointers. It’s not a lot of extra work and the programmer can easily enough dress it as the body of the wanted function, so that the function can be called naturally wherever it is wanted elsewhere in the code. For example:

STDAPI 
ShowHTMLDialogEx (
    HWND hwndParent,
    IMoniker *pMk,
    DWORD dwDialogFlags,
    VARIANT *pvarArgIn,
    WCHAR *pchOptions,
    VARIANT *pvarArgOut)
{
    static HMODULE mshtml = NULL;
    if (mshtml == NULL) {
        mshtml = LoadLibrary (TEXT ("mshmtl.dll"));
        if (mshtml == NULL) return HRESULT_FROM_WIN32 (ERROR_DELAY_LOAD_FAILED);
    }
    static SHOWHTMLDIALOGEXFN *pfn = NULL;
    if (pfn == NULL) {
        pfn = (SHOWHTMLDIALOGEXFN *) GetProcAddress (mshtml, "ShowHTMLDialogEx");
        if (pfn == NULL) return HRESULT_FROM_WIN32 (ERROR_DELAY_LOAD_FAILED);
    }
    return pfn (hwndParent, pMk, dwDialogFlags, pvarArgIn, pchOptions, pvarArgOut);
}

Especially if the programmer works a little at avoiding redundancy, the effect is that the programmer writes much the same code that the linker anyway provides for its Delay Load Import feature. To my mind, this is just more reason that the functions should be supported so that it actually is the linker that does this work. Microsoft surely thinks so, too. See that each of the documentation’s directions to programmers about having to use LoadLibrary and GetProcAddress is followed by a warning—a “security alert” no less—about using LoadLibrary incorrectly.

Obviously, the Windows SDK ought to provide an import library for the documented MSHTML functions. Though no evidence is known that Microsoft has an MSHTML.LIB which has somehow been omitted from the Windows SDK, the easiest way by far to work around the lack of an MSHTML.LIB is to make one and then forever after proceed as if there had been no omission. (By the way, it is easily established that Microsoft does already have an import library to cover both the documented and undocumented MSHTML functions. It is named MSHTMLP.LIB and is used for calling MSHTML functions from IEFRAME.DLL and INETCPL.CPL.)

Building a suitable import library does require that the programmer write some code, but less than needed even in the simple example above. Create one C++ source file, here named MSHTML.CPP. Include WINDOWS.H as usual and MSHTMHST.H for the prototypes. Then for each of the functions that are to be importable, reproduce the prototype but provide a trivial body, e.g.,

STDAPI 
ShowHTMLDialogEx (
    HWND hwndParent,
    IMoniker *pMk,
    DWORD dwDialogFlags,
    VARIANT *pvarArgIn,
    WCHAR *pchOptions,
    VARIANT *pvarArgOut)
{
    return E_NOTIMPL;
}

Create a module definition file, here called MSHTML.DEF, with the obvious content:

EXPORTS
    CreateHTMLPropertyPage
    RunHTMLApplication
    ShowHTMLDialog
    ShowHTMLDialogEx
    ShowModelessHTMLDialog

Now compile the source file and feed both the object file and the module definition file to the librarian:

cl /c mshtml.cpp
lib mshtml.obj /def:mshtml.def /out:mshtml.lib

The output is an import library such as Microsoft might have provided all along. Whether you build it yourself or download an (x86) import library for the documented MSHTML functions, add it to the import libraries for linking and you can thenceforth ignore Microsoft’s documentation where it says such things as “you need to dynamically load and call this function by using the LoadLibrary and GetProcAddress functions.”