HOWTO: Build a Microsoft Word Add-in (WLL) Using Visual C++ID: Q183758
|
A WLL is an add-in for Microsoft Word that you can build with any compiler
that supports building DLLs (dynamic link libraries). This article is
designed to get you started building WLLs with Microsoft Visual C++ 5.0. To
follow the steps outlined in this article, you should have some experience
building DLLs and you should have the Microsoft Word Developer's Kit, which
contains the necessary files to build a WLL.
For information about how to obtain the Word Developer's Kit, see the
Microsoft Press Web site at the following address:
http://mspress.microsoft.com/
#include "stdafx.h"
InitWCB( lpwcb, retType, lpBuffer, cBufferSize );
to the following:
InitWCB( lpwcb, retType, (UCHAR *)lpBuffer, cBufferSize );
Change the following lines:
case 's':
AddStringParam( lpwcb, va_arg(marker, LPSTR));
to the following:
case 's':
AddStringParam( lpwcb, (UCHAR *)va_arg(marker, LPSTR));
static short (WINAPI *pfn_wdCommandDispatch) ();
short WINAPI wdCommandDispatch(short CommandID, // fci
short DlgOptions, // grfDlg
short cArgs,
LPWDOPR lpwdoprArgs,
LPWDOPR lpwdoprReturn)
{
if (pfn_wdCommandDispatch == NULL)
FARPROC) pfn_wdCommandDispatch = GetProcAddress(
GetModuleHandle(NULL), "wdCommandDispatch"
);
return ((*pfn_wdCommandDispatch)(
CommandID, DlgOptions, cArgs, lpwdoprArgs, lpwdoprReturn)
);
}
to the following:
typedef unsigned short (CALLBACK *URET) (
short, short, short, LPWDOPR, LPWDOPR
);
URET pfn_wdCommandDispatch;
short WINAPI wdCommandDispatch(short CommandID, // fci
short DlgOptions, // grfDlg
short cArgs,
LPWDOPR lpwdoprArgs,
LPWDOPR lpwdoprReturn)
{
if (pfn_wdCommandDispatch == NULL)
pfn_wdCommandDispatch = (URET)GetProcAddress(
GetModuleHandle(NULL), "wdCommandDispatch"
);
return ((*pfn_wdCommandDispatch)(
CommandID, DlgOptions, cArgs, lpwdoprArgs, lpwdoprReturn)
);
}
typedef struct
{
short cArrayDimensions;
short ArrayDimensions[];
} ARRAY_DEF;
to the following:
typedef struct
{
short cArrayDimensions;
short *ArrayDimensions;
} ARRAY_DEF;
#include "capilib.h"
#include "wdcmds.h"
#include "wdfid.h"
// DocId of WLL session...
short g_docId;
// General-purpose variables...
static char buf[8192];
int err;
// Routine to report errors encountered...
void ReportError(char *msg) {
static char errBuf[1024];
sprintf(errBuf, "%s, Error = %d", msg, err);
::MessageBox(NULL, errBuf, "WLL Error", MB_SETFOREGROUND);
}
// Table of functions that we will register...
struct {
char *name; // Function name...
char *desc; // Function description...
} g_funcTbl[] =
{
{"MyMotd", "Message of the day"},
{"InsertTime", "Insert Time"},
{0, 0} // List is null-terminated
};
// Menu name
UCHAR *g_menuName = (UCHAR *)"&Custom Menu";
// wdAutoOpen() - entry point for WLLs...
short __stdcall wdAutoOpen(short DocID) {
// Some diagnostic output, remove from your final code ...
::MessageBox(NULL, "In wdAutoOpen()!", "Msg", MB_SETFOREGROUND);
// Store the docId for later use...
g_docId = DocID;
// Register our functions...
int i;
for(i=0; g_funcTbl[i].name; i++) {
err = CAPIRegister(
DocID, (UCHAR *)g_funcTbl[i].name,
(UCHAR*)g_funcTbl[i].desc
);
if(err) {
sprintf(buf, "CAPIRegister(%s, %s)",
g_funcTbl[i].name, g_funcTbl[i].desc);
ReportError(buf);
}
}
// Add our menu...
err = CAPIAddMenu(DocID, g_menuName, 1, 0);
if(err) ReportError("CAPIAddMenu()");
// Add our menu items...
for(i=0; g_funcTbl[i].name; i++) {
err = CAPIAddMenuItem(
DocID, g_menuName, (UCHAR *)g_funcTbl[i].name,
(UCHAR *)g_funcTbl[i].desc, -2, 0
);
if(err) {
sprintf(buf, "CAPIAddMenuItem() for %s",
g_funcTbl[i].name);
ReportError(buf);
}
}
// Initialize crt pseudo-random number generator...
srand(time(0));
return TRUE;
}
// Displays a message of the day (MOTD)...
short __stdcall MyMotd(void) {
char *name[] = {
"Rebekah",
"Brent",
"Michael",
"Joseph",
"Bob",
0
};
char *quote[] = {
"An apple a day, keeps the doctor away!",
"Carpe Diem: Seize the Day!",
"What you dare to dream, dare to do!",
"I think, therefore I am.",
"A place for everything, and everything in its place.",
"Home is where the heart is.",
0
};
int nNames, nQuotes;
for(nNames=0; name[nNames]; nNames++);
for(nQuotes=0; quote[nQuotes]; nQuotes++);
sprintf(buf, "%s says '%s'",
name[rand()%nNames], quote[rand()%nQuotes]
);
::MessageBox(NULL, buf, "XLL MOTD", MB_SETFOREGROUND );
return 0;
}
// Inserts time at current document location...
void __stdcall InsertTime(void) {
WCB wcb;
InitWCB(&wcb, TypeShort, NULL, 0);
_strtime(buf);
AddStringParam(&wcb, (UCHAR *)buf);
err = wdCommandDispatch(
wdInsert, CommandAction, wcb.cArgs, wcb.wdoprArgs, lpwdoprNil
);
if(err) {
ReportError("wdInsert");
}
}
; ANewWLL.def : Declares the module parameters for the DLL.
LIBRARY "ANewWLL"
DESCRIPTION "ANewWLL Windows Dynamic Link Library
EXPORTS
; Explicit exports can go here
wdAutoOpen
MyMotd
InsertTime
Microsoft Word Developer's Kit (ISBN: 1-55615-880-7)
© Microsoft Corporation 1999, All Rights Reserved.
Contributions by Joe Crump, Microsoft Corporation
Additional query words: wll vc wdcommanddispatch capilib wdopr capi wcb
Keywords : kbVC500 kbSDKWord kbWord kbGrpDSO kbOffice2000
Version : :; WINDOWS:97; winnt:5.0
Platform : WINDOWS winnt
Issue type : kbhowto
Last Reviewed: June 18, 1999