![]() |
|
||||
Writing Administrator ExtensionMy simple plan of writing my own Administrator Extension was as the following:
Choosing the Right SampleI have decided to use the EXTDATVW sample as my base point. The main reason for choosing it was its simplicity. My determination of "simplicity" was "the less source files - the better". I have chosen the project with the smallest number of source files and it turned out to be a working solution. I can't say whether it is the best solution or not because I have not tried the others.The only significant problem I have encountered was mixing C++ with MAPI and EDK in a C style project. The ability to use C++ MAPI interfaces in a C project is important. If you can make it, then everything separates smoothly into two well defined pieces: user interface code and specific functionality which uses MAPI and EDK. User interface code may be easily extended in C by modifying appropriate files. Specific functionality is to be written from scratch.
Modifying the SampleInstalling the ExtensionI have started from learning how to install extension
objects. Obviously, in order to test your extension you need to have
it installed on MS Exchange server site.
Compiling Sample as It Is Then I used the EXTDATVW source files as they are to compile and test
the extension. I just wrapped the makefile into a new project in Developer
Studio, built it and played with it after installation. I have associated
this extension with a user mailbox and saw additional functional property
page when I double clicked on this mailbox.
Using New Project File The next step was to have my own project file generated from scratch instead of a wrapped makefile provided with the sample. I have created a new Win32 DLL project called MyExt (not MFC AppWizard DLL) and added all source files including the .DEF file to it. The project successfully compiled. An attempt to use it, however, failed: I did not see my extension page added to the dialog. I was able to use the debug monitor program (dbmon.exe) to trace the error. When I started dbmon and then double clicked on the object associated with my extension, I saw the following error message on debug monitor screen: "Setting-up Extension page: hinst = 00000000, idd = 102, pfn = 0x10001023, ids = 1. Invalid hInstance for this page". This told me that the extension dll module handle for the Administrator program was NULL. I have fixed this by injected the following line in the ADMIN_Initialize function: hDLLInst = GetModuleHandle( "MyExt.DLL" ); You may see all source files with my modifications in Ext/MyExt directory of my samples. All my injections there are marked with the following comments for your convenience: // BEGIN INJECTED CODE
Stripping Unnecessary Functionality The next very important step is to strip all unnecessary features from the sample thus leaving only a skeleton which you can use as your base point for other extension development. The idea is to keep the skeleton as simple as possible. I have removed all unnecessary source files from the project, having left only Admin.c and ExtdatVw.c. I have also modified the resource file by reducing it to the absolute minimal thing - a page with one control (at least 1 control is required). In addition to this I have made major cuts to the files that were left in the project. The result of this operation is a very simple but functional extension which does nothing except for displaying itself. The page contains only one custom edit control in addition to icon and title controls that are required always (see "Administrator Program Extensions" MSDN article for more details). In fact, at least one additional control is required anyway, but it does not have to be an edit control - it must be any Tab Stop control. A good idea is to use this skeleton as a starting point in an extension
development rather then doing the above few steps. However, I have decided
to write about these steps to give you an evolutional point of view on
it. As you can see the skeleton does nothing. It is very straightforward
C style sample. The "C" is important here, and I will later show how C++
code may be attached to it. Perhaps it will help by demonstrating the technique
which may be used with more complex C style MAPI and Exchange samples where
stripping is not possible or complex.
Extending the Skeleton with C++ MAPI Code The final step before implementing specific functionality would be trying to inject some C++ MAPI code inside your project. In general this could be a non-trivial task. It is likely that following regular procedures here would lead to unresolved externals or multiply defined symbols. The trick of the trade is to use other include files in the right sequence in your .cpp code. Take a look at the simple project Ext/MyExtWithMAPI in my collection of samples which shows how this could be achieved. Basically, I have extended the skeleton with only one thing - it initializes the edit control with the user's last name. It does so by exercising MAPI methods against MS Exchange directory by opening a directory object and analyzing its properties. Minor modifications are introduced to Admin.c file. The ExtdatVw.c file is slightly modified and renamed to ExtDialog.c. A new file named MAPICode.cpp is introduced. It contains implementations of functions dealing with EDK and MAPI. The general idea here is the following: all C++ MAPI and EDK code is
separated in its own source file where functions are declared as extern
"C". This allows for their invocation from within C files. The C code handles
interaction with Administrator program and user interface. It is easy to
extend UI functionality by modifying the resource file and appropriate
functions in ExtDialog.c file. Any specific things that require EDK or
MAPI may be added to your project as separate files.
|