An add-in library function accesses Word by calling the wdCommandDispatch function. This is the only function in Word that your add-ins will call. The wdCommandDispatch function lets you call virtually all WordBasic statements and functions. It passes the same arguments as those described for WordBasic statements and functions in Part 2, "WordBasic Reference."
Here is the syntax for the wdCommandDispatch function:
// Windows short FAR PASCAL wdCommandDispatch( short CommandID, short DlgOptions, short cArgs, LPWDOPR lpwdoprArgs, LPWDOPR lpwdoprReturn ); // Macintosh pascal short (*wdCommandDispatch) ( short CommandID, short DlgOptions, short cArgs, LPWDOPR lpwdoprArgs, LPWDOPR lpwdoprReturn );
For platform-specific details about declaring wdCommandDispatch in your WLL code, see "Platform-Specific Notes About wdCommandDispatch" later in this section.
Understanding each of the parameters of the wdCommandDispatch function is important. The following paragraphs detail the purpose and use of each parameter.
This is the WordBasic command Word is to execute. The names of available functions are provided as constants in the header file WDCMDS.H. Most of these command names closely parallel their WordBasic equivalents.
This is the "dialog options" parameter, and is only necessary for WordBasic commands that correspond to Word dialog boxes. This parameter is ignored if
the command doesn't involve a dialog box. The following constants for this parameter are defined in WDCAPI.H.
Returns default values for the dialog box's fields, without actually activating the dialog box. This is similar to the GetCurValues statement in WordBasic.
Activates the dialog box. This is similar to the Dialog statement in WordBasic. If the function is set to return values from Word, the field settings are just returned to the calling code, and no implied action takes place.
Causes the action indicated by the dialog box to actually take place. When combined with CommandDialog, the dialog box will first be displayed, letting the user make any desired changes to the fields, and then the dialog box's action will take place.
This is the number of Word arguments being passed. (Arguments for Word commands are wrapped in a data structure called a WDOPR.) The next parameter, lpwdoprArgs, points to an array of WDOPR arguments; cArgs simply provides the count for this array.
This is a pointer to an array of WDOPR arguments passed to the function dispatcher; in other words, these are the actual arguments for the Word command. Building up this array of arguments is an important part of preparing to call wdCommandDispatch. The next section explains this parameter in greater detail.
This parameter points to a single WDOPR data structure that returns one data item from a WordBasic function. The returned data item can be any of the supported WDOPR data types. When using wdCommandDispatch to execute WordBasic statements that correspond to dialog boxes, you should set this parameter to lpwdoprNil. If you are calling a WordBasic statement that can also be called as a function — for example, Bold and Bold() — this parameter must correspond to how you want to use the statement: as a statement or as a function.
The following topics address specific issues about accessing wdCommandDispatch and the Word API on the Windows 3.x, Windows 95, Windows NT, and Macintosh platforms.
In Windows 3.x, a WLL imports wdCommandDispatch directly from Word version 6.0 for Windows. By declaring the function as described earlier in this section and including the function in the IMPORTS section of the .DEF file for you WLL, your add-in library will work correctly in Windows 3.x.
In Windows 95 and Windows NT, importing functions directly from applications (as Windows 3.x allows) is discouraged. To use wdCommandDispatch successfully in Windows 95 and Windows NT, your WLL should declare the following function:
static unsigned int (*pfn_wdCommandDispatch) () = NULL; { if (pfn_wdCommandDispatch == NULL) pfn_wdCommandDispatch = GetProcAddress(GetModuleHandle(NULL), "wdCommandDispatch"); return ((*pfn_wdCommandDispatch) (CommandID, DlgOptions, cArgs, lpwdoprArgs, lpwdoprRetrun)); }
After declaring this function, the WLL should behave the same as one created for Windows 3.x. However, bear the following details in mind when programming 32-bit WLLs or migrating 16-bit WLLs to 32-bit WLLs:
Passing Floating-Point Parameters on a RISC Platform If you are writing external DLLs or WLLs to run in Word version 6.0 for Windows NT or Word version 7.0 on a RISC platform, you should be aware of the following issue. Although some processor architectures define a special mechanism for supplying floating-point parameters to functions, WordBasic always passes parameters to external functions using the method for integers, pointers, and structures. Therefore, if your code includes functions with floating-point parameters that will be declared and called by WordBasic macros, you need to use a special technique for passing the parameters. To access floating-point parameters within a DLL or WLL, you must declare them as structures, and then copy them into a local variable for use within your routine. You can use the following structure and macro definition to accomplish this. struct WORDARGDBL { char x[sizeof(double)]; }; #define DblArgValue(a) (*(double*)&(a)) Here is an example of how you can use this structure and definition in a WLL function: double WINAPI AbsCapi (struct WORDARGDBL arg1) { InitWCB (&wcb, TypeDouble, NULL, 0); AddDoubleParam (&wcb, DblArgValue(arg1)); err = wdCommandDispatch (wdAbs, 0, wcb.cArgs, wcb.wdoprArgs, &wcb.wdoprReturn); return wcb.wdoprReturn.Double; } |
A Macintosh code resource cannot import a function directly from an application. Therefore, the application must provide the resource with a pointer to the parameters for wdCommandDispatch. Every time Word calls the WLL, it passes a pointer to a WCDB structure. Here is the structure:
typedef struct _WCDB { short cac; char fLock; char fPurge; char szFunction[66]; pascal short (*pfnWordCapi)(); short *prgParams; union { long Short; long Long; double Double; uchar *String; } retval; } WCDB;
Element | Description |
cac | CAPI Call, the action to be taken by the main function. The defined actions are cacCallFunction, cacCallTimer, cacTerminate, cacWdAutoOpen, cacWdAutoRemove, and cacWindEvent. |
fLock | Specifies whether the WLL should remain locked after being called. |
fPurge | Specifies whether the WLL should be purged after being called. |
szFunction | The function being called from WordBasic; cac is cacCallFunction. On the Macintosh, if the function being called does not exist in the WLL, the WLL should return CAPINoSuchFunction (5) to Word. |
pfnWordCapi | A pointer to wdCommandDispatch. |
prgParams | A pointer to the parameter list passed to szFunction. |
retval (union) | The return value of szFunction, if any, as one of the data types specified in the union. |
In the main function of the WLL, the dispatcher must be based on the value of the CAPI Call (cac) passed by Word. Apart from this behavior, a Macintosh WLL should work the same as a Windows WLL.
Note
On the Macintosh, WordBasic passes function names to a WLL in all uppercase. For simplicity and speed, a WLL should be written to perform a case-insensitive comparison to determine which function in the WLL is being called.
At the same time Word passes a pointer to the WCDB for a WLL to use, it passes a pointer to lUser, a long that holds global data for the WLL. Word initializes this value to 0 (zero); a WLL can modify the data at any time, and Word will return the current data in lUser each time it calls the WLL.