Building An Outlook COM Add-In With VC /ATL - Command and conquer
(Page 4 of 7 )
In office applications, menus and toolbars are combined into a fully programmable collection called CommandBars. CommandBars are common sharable programmable objects that are exposed by all office applications as a part of it's object model.
CommandBars represent a unified mechanism through which individual toolbars and menu items can be added to the corresponding application. Each CommandBars collection comprises of individual CommandBar objects. Each CommandBar object again contains a collection of CommandBarControl objects, called CommandBarControls.
CommandBarControls represent a complex hierarchy of objects and sub objects that comprise its object model. A CommandBarControl can itself contain a CommandBar object, accessible through the CommandBar property of the control. Finally, each CommandBarControl object within the CommandBarControls collection of controls can be either a CommandBarComboBox (toolbar combo box), a CommandBarButton (toolbar button), or a CommandBarPopup (popup menu).
In our add-in, we'd like to add the following user-interface elements to Outlook:
- 2 toolbar buttons (with bitmaps) in a new toolband.
- A new popup menu item (with bitmap) to the 'Tools' menu.
First off, we need to import the office and outlook type libraries into our project. To do this, open the project's stdafx.h file and add the following #import directives:
#import "C:\Program Files\Microsoft Office\Office\mso9.dll" rename_namespace("Office") named_guids
using namespace Office;
#import "C:\Program Files\Microsoft Office\Office\MSOUTL9.olb" rename_namespace("Outlook"), raw_interfaces_only, named_guids
using namespace Outlook;You may need to change the paths above to match the location where Microsoft Office is installed on your system
Now that we're all set, let's dig into some code. Firstly, the toolband and toolbar buttons.
In the outlook object model, the application object is at the top of the object hierarchy, representing the entire application. Through it's ActiveExplorer method, we get the explorer object that represents the currently active window. We will use the GetCommandBars method to get the CommandBars object that, as you know, is a collection of all of Outlook's toolbands and menu items. We simply call the add method of the CommandBars collection with relevant parameters to add a new toolband.
Adding new buttons to the toolband is as simple as getting the toolband's CommandBarControls collection and then calling its add method. Finally, we query the buttons for the CommandBarButton object that we'll use to set button styles and other button properties, such as caption, tooltip text, etc.
The code snippet to do everything mentioned above look like this:
STDMETHODIMP CAddin::OnConnection(IDispatch * Application, ext_ConnectMode ConnectMode,IDispatch * AddInInst, SAFEARRAY * * custom)
{
CComPtr < Office::_CommandBars> spCmdBars;
CComPtr < Office::CommandBar> spCmdBar;
// QI() for _Application
CComQIPtr spApp(Application);
ATLASSERT(spApp);
// get the CommandBars interface that represents Outlook's
//toolbars & menu items
CComPtr spExplorer;
spApp->ActiveExplorer(&spExplorer);
HRESULT hr = spExplorer->get_CommandBars(&spCmdBars);
if(FAILED(hr))
return hr;
ATLASSERT(spCmdBars);
// now we add a new toolband to Outlook
// to which we'll add 2 buttons
CComVariant vName("OutlookAddin");
CComPtr spNewCmdBar;
// position it below all toolbands
//MsoBarPosition::msoBarTop = 1
CComVariant vPos(1);
CComVariant vTemp(VARIANT_TRUE); // menu is temporary
CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
//Add a new toolband through Add method
// vMenuTemp holds an unspecified parameter
//spNewCmdBar points to the newly created toolband
spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp);
//now get the toolband's CommandBarControls
CComPtr < Office::CommandBarControls> spBarControls;
spBarControls = spNewCmdBar->GetControls();
ATLASSERT(spBarControls);
//MsoControlType::msoControlButton = 1
CComVariant vToolBarType(1);
//show the toolbar?
CComVariant vShow(VARIANT_TRUE);
CComPtr < Office::CommandBarControl> spNewBar;
CComPtr < Office::CommandBarControl> spNewBar2;
// Add first button
spNewBar = spBarControls->Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow);
ATLASSERT(spNewBar);
// Add 2nd button
spNewBar2 = spBarControls->Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow);
ATLASSERT(spNewBar2);
_bstr_t bstrNewCaption(OLESTR("Item1"));
_bstr_t bstrTipText(OLESTR("Tooltip for Item1"));
// get CommandBarButton interface for each toolbar button
// so we can specify button styles and stuff
// each button displays a bitmap and caption next to it
CComQIPtr < Office::_CommandBarButton> spCmdButton(spNewBar);
CComQIPtr < Office::_CommandBarButton> spCmdButton2(spNewBar2);
ATLASSERT(spCmdButton);
ATLASSERT(spCmdButton2);
// to set a bitmap to a button, load a 32x32 bitmap
// and copy it to clipboard. Call CommandBarButton's PasteFace()
// to copy the bitmap to the button face. to use
// Outlook's set of predefined bitmap, set button's FaceId to //the
// button whose bitmap you want to use
HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(),
MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);
// put bitmap into Clipboard
::OpenClipboard(NULL);
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
::CloseClipboard();
::DeleteObject(hBmp);
// set style before setting bitmap
spCmdButton->PutStyle(Office::msoButtonIconAndCaption);
HRESULT hr = spCmdButton->PasteFace();
if (FAILED(hr))
return hr;
spCmdButton->PutVisible(VARIANT_TRUE);
spCmdButton->PutCaption(OLESTR("Item1"));
spCmdButton->PutEnabled(VARIANT_TRUE);
spCmdButton->PutTooltipText(OLESTR("Tooltip for Item1"));
spCmdButton->PutTag(OLESTR("Tag for Item1"));
//show the toolband
spNewCmdBar->PutVisible(VARIANT_TRUE);
spCmdButton2->PutStyle(Office::msoButtonIconAndCaption);
//specify predefined bitmap
spCmdButton2->PutFaceId(1758);
spCmdButton2->PutVisible(VARIANT_TRUE);
spCmdButton2->PutCaption(OLESTR("Item2"));
spCmdButton2->PutEnabled(VARIANT_TRUE);
spCmdButton2->PutTooltipText(OLESTR("Tooltip for Item2"));
spCmdButton2->PutTag(OLESTR("Tag for Item2"));
spCmdButton2->PutVisible(VARIANT_TRUE);
//..........
//..........
//code to add new menubar to be added here
//read on
//..........Next: Command and conquer (contd.) >>
More C++ Articles
More By Amit Dey