Translator: Xu Jingzhou
Download sample source code
Introduction
You may have seen some new custom toolbar buttons or menus added by other software in word2000, Access2000, excel2000, powerpoint2000, and other software tools under Office2000, when you click them, different responses will occur. Below, let's also implement these functions. It should be noted that here we do not use VB/VBA to implement it, but use ATL (Active Template Library) in vc6) 3.0. In Office2000, whether it is word2000, Access2000, excel120000, powerpoint2000 or outlook2000, the programming methods and steps of their com plug-ins are extremely similar (except for the key values in the Registry and the corresponding types of libraries imported ).
Basic knowledge
An internal com plug-in under Office2000 must implement_ Idtextensibility2Dispatch interface,_ Idtextensibility2The dispatch interface is defined inMsaddin designerType Library (msaddndr. dll/msaddndr. TLB), usually located in<Drive letter>/program files/common files/designer._ Idtextensibility2The following five interface functions must be implemented in the interface (generally, you only need to write the code in onconnection and ondisconnection:
1.Onconnection: Processing when loading the plug-in to the memory (the plug-in can be automatically loaded when the program starts ).
2.Ondisconnection: Processing when the plug-in is loaded from the memory.
3.Onaddinsupdate: Handle changes to the com plug-in.
4.Onstartupcomplete: Process when the plug-in is loaded when the application starts.
5.Onbeginshutdown: Processing when the application is closed and the plug-in is just loaded.
Register plug-ins
Only when the internal com plug-in of the corresponding application is correctly registered can the application be loaded. You need to create the following key values in the registry:
HKEY_CURRENT_USER/software/Microsoft/office/<theofficeapp>/addins/<progid>
Theofficeapp indicates the corresponding program name, such as Word and outlook,ProgidString Representation of the unique identifier of the internal com plug-in program, such as outlook2000addin. addin.
ProgidThe following four key values are created:
1.Friendlyname: String type, plug-in name, which will be displayed in the com loading dialog box of the corresponding program.
2.Description: String type, description of the plug-in.
3.Loadbehavior: DWORD type, which determines the form in which the plug-in will be loaded. When its value is 0x03, it is automatically loaded when the application is loaded (this value is generally used), and when its value is 0x08, it controls the user to activate the load.
4.Commandlinesafe: DWORD type. It can be set to 0x01 (true) or 0x00 (false ).
For a complete description of other key values, see the latest msdn.
Implementation
Next, we will create an internal com plug-in of outlook2000 as an example to show you step by step how to minimize the whole process of creating an internal plug-in of Office2000. As follows:
Open vc6.0 and selectAtl com Appwizard, Enter outladdin in the project name on the right, and click Next to accept the default optionsDynamic link library (DLL)Unchanged. You can select the followingAllow merging of proxy-stub code(Allow merge proxy/placeholder) check box option, click Finish to complete the project creation.
Next, select the menuInsert-> new ATL objecItems. In the displayed ATL object wizard dialog box, select the correspondingObjectsCorrespondingSimple ObjectOption, click Next, in the pop-up dialog boxShortnameEnter outlookaddin inAttributes(Property page) selectedSupport isupporterrorinfoClick OK to insert the ATL object.
Then, import the Type Library to implement_ Idtextensibility2Interface, after compiling and interpreting the project aboveClassviewInCoutlookaddinRight-click the class, and selectImplement Interface. In the displayed implementation interface dialog box, clickAdd typelib, In the pop-upBrowse type LibrariesIn the dialog box, scroll down to selectMicrosoft add-in designer (1.0)Subitem. Click OK. In the displayed interface List dialog box, select_ Idtextensibility2Interface, click OK to complete the import. The system will automatically generate an empty five required interface functions mentioned above.
Register the compiled plug-inFileView-> resource filesOpen the outlookaddin. RGS registration file and add the following internal plug-in registration code to the bottom of the file:
// Added the key value hkcu {software {Microsoft {office {outlook {addins {''outladdin. outlookaddin ''{Val friendlyname = S' 'outlook2000 plug-in'' Val description = S' use the outlook2000 plug-in developed by ATL ''val loadbehavior = d' 00000003 ''Val commandlinesafe = D '000000 ''}}}}}}}
Compile this project. If it is correctly registered, it will be available in OutlookCOM add-onThe corresponding name is displayed in the plug-in dialog box. To load or uninstall the com plug-in Office2000, follow these steps:
1. If you have added the "COM add-on" command to the "Tools" menu, go to step 1.
2. Click the "Custom" command in the "Tools" menu, and then click the "commands" tab.
3. In the "category" box, select "Tools ".
4. Drag the "COM add-on" from the "command" box to the "tool" menu. When the "Tools" Menu displays the menu command, point the mouse pointer to the position where you want the "COM add-on" command to appear on the menu, and release the mouse button.
5. Click the close button.
6. Click the "COM add-on" command in the "Tools" menu and Perform one of the following operations:
● To add an add-on, select the check box next to the add-on name in the "available add-on" list. If the required Add-on is not in the "available add-on" list, click "add", find the add-on to be added, and click "OK.
● To uninstall the add-on from memory but keep its name in the list, clear the check box next to the add-on name.
● If you want to delete an add-on from the list and delete it from the add-on list registered in the Registry file, select the name of the add-on and click the delete button.
In office applications, although menus and toolbar buttons look different, they are essentially the same type of objects.CommandbarsThe set contains all command lines in the program, such as toolbar and menu bar. EveryCommandbarsEach set hasCommandbarObject corresponds to it,CommandbarObjects can contain otherCommandbarObjects, which are used as buttons or menu commands. EveryCommandbarAll will passCommandbarcontrolsObject referenced,CommandbarcontrolsIt can also contain a groupCommandbarcontrolObject. EveryCommandbarcontrolCan containCommandbarAnd can be used to access control properties. EveryCommandbarcontrolObject.CommandbarcontrolsControl set in.CommandbarcontrolThere are three forms:
●Commandbarpopup): It is equivalent to a menu item in a menu bar.
●Commandbarcombobox): It is similar to the control of the combo box in the toolbar. It includes a toolbar and a drop-down arrow next to the toolbar. Click this button to display more menu commands with icons.
●Button (commandbarbutton): It is equivalent to a Standard toolbar button, that is, a button with an icon.
In the example program below, we will create a toolbar in outlook2k and add two buttons to it, and create a menu bar in its menu "tool, these operations can be completed in the onconnection interface function.
FirstTo import the Office and Outlook libraries in the project, you can add the following statement to the stdafx. h file (note: the path can be set according to the path installed in the Office ):
// The office2k and outlook2k types libraries required for the import Project # import "E:/program files/Microsoft Office/office/mso9.dll" rename_namespace ("Office"), named_guidsusing namespace office; # import "E:/program files/Microsoft Office/office/msoutl9.olb" rename_namespace ("Outlook"), raw_interfaces_only, named_guids using namespace outlook;
Second, Let's create a toolbar in outlook and add two buttons on it.
The Code is as follows:
// Handle stdmethod (onconnection) (idispatch * application, ext_connectmode connectmode, idispatch * addinst, safearray ** custom) {ccomptr <Office: _ commandbars> spcmdbars; // outlook application interface _ applicationccomqiptr <Outlook: _ Application> spapp (application); atlassert (spapp); // obtain the commandbars interface ccomptr <outlook ::_ explorer> spexplorer; spapp-> activeexplorer (& spexplorer); hresult hR = spexplorer-> get_commandba RS (& spcmdbars); If (failed (HR) return hr; atlassert (spcmdbars ); // Add a toolbar and its two Bitmap Buttons ccomvariant vname ("New outlook2k "); ccomptr <Office: commandbar> spnewcmdbar; // Add the tool bar ccomvariant VPOs (1); ccomvariant vtemp (variant_true); // temporary ccomvariant vempty (disp_e_paramnotfound, vt_error ); // use the add method to add a toolbar at the specified position and point spnewcmdbar to it. spnewcmdbar = spcmdbars-> Add (vname, VPOs, vempty, vtemp); // obtain the commandbarcontrols of the new toolbar To add the button ccomptr <Office: commandbarcontrols> spbarcontrols; spbarcontrols = spnewcmdbar-> getcontrols (); atlassert (spbarcontrols); // msocontroltype :: msocontrolbutton = 1 ccomvariant vtoolbartype (1); // display toolbar ccomvariant vshow (variant_true); ccomptr <Office: commandbarcontrol> spnewbar; ccomptr <Office: commandbarcontrol> spnewbar2; // use the add method in commandbarcontrols to add the first button and point the spnewbar to it. spnewbar = spbarcont ROLS-> Add (vtoolbartype, vempty, vshow); atlassert (spnewbar); // use the add method in commandbarcontrols to add the second button, and point spnewbar2 to spnewbar2 = spbarcontrols-> Add (vtoolbartype, vempty, vshow); atlassert (spnewbar2); // specify the _ commandbarbutton interface for each button, you can specify the display style of buttons and other ccomqiptr <Office: _ commandbarbutton> spcmdbutton (spnewbar); ccomqiptr <Office: _ commandbarbutton> spcmdbutton2 (spnewbar2); atlasse RT (spcmdbutton); atlassert (spcmdbutton2); // set the bitmap button style. The bitmap size is 32x32. Place it in the clipboard and paste it with pasteface () on the specified button. hbitmap hbmp = (hbitmap): LoadImage (_ module. getresourceinstance (), makeintresource (idb_bitmap), image_bitmap, success);: openclipboard (null);: emptyclipboard ();: setclipboarddata (cf_bitmap, (handle) hbmp);: closeclipboard ();: deleteobject (hbmp); // set the display style spcmdbutton-> putstyle (Office: msobuttonicon Andcaption); HR = spcmdbutton-> pasteface (); If (failed (HR) return hr; spcmdbutton-> putvisible (variant_true ); spcmdbutton-> putcaption (olestr (" 1"); spcmdbutton-> putenabled (variant_true); spcmdbutton-> puttooltiptext (olestr (" 1 ")); spcmdbutton-> puttag (olestr ("button 1 sign"); // display the new toolbar spnewcmdbar-> putvisible (variant_true ); // set the second toolbar button style spcmdbutton2-> putstyle (Office: msobuttoniconandcaption); // specify the second button The bitmap is the pre-defined bitmap spcmdbutton2-> putfaceid (1760); spcmdbutton2-> putvisible (variant_true); spcmdbutton2-> putcaption (olestr ("button 2 ")); spcmdbutton2-> putenabled (variant_true); spcmdbutton2-> puttooltiptext (olestr ("button 2 prompt message"); spcmdbutton2-> puttag (olestr ("button 2 flag ")); spcmdbutton2-> putvisible (variant_true); m_spbutton = spcmdbutton; m_spbutton2 = spcmdbutton2 ;......
Next, Let's create a new menu bar in the menu "tool. The Code is as follows:
_ Bstr_t bstrnewmenutext (olestr ("new menu bar"); ccomptr <Office: commandbarcontrols> sp1_ctrls; ccomptr <Office: commandbarcontrols> spcmdbarctrls; ccomptr <Office :: commandbarpopup> spcmdpopup; ccomptr <Office: commandbarcontrol> sp1_ctrl; ccomptr <Office: commandbar> spcmdbar; // obtain the HR = spcmdbars-> terminal (& spcmdbar) of the outlook Main Menu through commandbar ); if (failed (HR) return hr; // retrieve the commandbarcontrols spcmdctrls = spcmdbar-> getcontrols (); atlassert (spcmdctrls ); // Add a ccomvariant vitem (5), sp1_ctrl = sp1_ctrls-> getitem (vitem), atlassert (sp1_ctrl), and idispatchptr spdisp under the 5th "Tools" menu; spdisp = spcmdctrl-> getcontrol (); // obtain the commandbarpopup interface ccomqiptr <Office: commandbarpopup> ppcmdpopup (spdisp); atlassert (ppcmdpopup ); response = response-> getcontrols (); atlassert (spcmdbarctrls); ccomvariant vmenutype (1); // control type-menuccomvariant vmenupos (6); ccomvariant response (response, vt_error ); ccomvariant vmenushow (variant_true); // The Menu displays ccomvariant vmenutemp (variant_true); // temporary ccomptr <Office: commandbarcontrol> spnewmenu; // use the add method to create a new menu bar spnewmenu = spcmdbarctrls-> Add (vmenutype, vmenuempty, vmenuempty, vmenutemp); atlassert (spnewmenu ); spnewmenu-> putcaption (bstrnewmenutext); spnewmenu-> putenabled (variant_true); spnewmenu-> putvisible (variant_true); // use commandbarbutton to display the bitmap ccomqiptr <Office :: _ commandbarbutton> spcmdmenubutton (spnewmenu); atlassert (spcmdmenubutton); spcmdmenubutton-> putstyle (Office: msobuttoniconandcaption ); // same method as the bitmap of the first button added to the toolbar spcmdmenubutton-> pasteface (); // display menu spnewmenu-> putvisible (variant_true); m_spmenu = spcmdmenubutton;
In this way, by loading the com plug-in through the method mentioned above in outlook, we can see the interface effect shown in 1, but there is no response when you click it. Finally, let's solve this problem.
Toolbar buttonCommandbarbuttonThe dispatch interface RESPONSE event is_ Commandbarbuttonevents. ATL provides two template classesIdispeventimpl <>AndIdispeventsimpleimpl <>To receive interface events. Here we use idispeventsimpleimpl (because it does not require additional Type Library Information ). It needs to set the sink (receive) ing, call the parameter information back and forth through the _ atl_sink_info structure, and finally connect to or disconnect from the source interface through dispeventadvise and dispeventunadvise. The implementation method is as follows:
1. Add idispeventsimpleimpl inheritance to the coutlookaddin inheritance class. The Code is as follows:
class ATL_NO_VTABLE COutlookAddin : public CComObjectRootEx<CComSingleThreadModel>,……public IDispEventSimpleImpl<1,COutlookAddin,&__uuidof(Office::_CommandBarButtonEvents)>
2. Declare the callback parameter information of the _ atl_sink_info structure. Add the following statement to the outlookaddin. h file:
// Button Event Response Information declaration extern _ atl_func_info onclickbuttoninfo;
Add the Definition Statement to the outlookaddin. cpp file as follows:
// Button Event Response Information definition _ atl_func_info onclickbuttoninfo = {cc_stdcall, vt_empty, 2, {vt_dispatch, vt_byref | vt_bool }};
3. Add the sink ing as follows:
EGIN_SINK_MAP(COutlookAddin)SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickButton1, &OnClickButtonInfo)SINK_ENTRY_INFO(2, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickButton2, &OnClickButtonInfo)SINK_ENTRY_INFO(3, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickMenu, &OnClickButtonInfo)END_SINK_MAP()
4. Add event functions. Add the Declaration in outlookaddin. h:
void __stdcall OnClickButton1(IDispatch * /*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault);
Add the following implementation to outlookaddin. cpp:
// Tool bar 1 Click Event Response Function void _ stdcall coutlookaddin: onclickbutton1 (idispatch */* Office: _ commandbarbutton **/Ctrl, variant_bool * canceldefault) {uses_conversion; ccomqiptr <Office: _ commandbarbutton> pcommandbarbutton (CTRL); hinstance result = ShellExecute (null, _ T ("open"), _ T ("http://www.vckbase.com"), null, null, sw_show );}
5. Finally, open or disconnect the interface. The method is as follows:
● In the last part of the onconnection interface function, add the following code to open the connection:
CommandButton1Events::DispEventAdvise((IDispatch*)m_spButton);
● In the ondisconnection interface function, add the following code to disconnect:
CommandButton1Events::DispEventUnadvise((IDispatch*)m_spButton);
This completes the minimum requirements for an internal office plug-in. After compilation, you can open outlook2000 to see how it works. For more information about the code, see the sample source code in the article, which contains detailed notes.
References:
Building an office2k com addin with VC ++/ATL -- Amit dey
ATL Development Guide (version 2)-Tom Armstrong & Ron Patton