MobileDeveloping Pocket Outlook Add-Ins

Developing Pocket Outlook Add-Ins content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

If you take a closer look at standard Pocket PC Pocket Outlook applications like Calendar, Contacts or Tasks, you will notice that they all contain a Tools menu. Moreover, through this menu you are able to, for example, beam selected items. Pocket Outlook provides an opportunity for external applications to embed their commands into the Tools menu. As easily as you can imagine, your application may manipulate Outlook items by all the ways POOM offers you, directly from standard Pocket PC software.

To get there, you need to perform only a few simple steps. Actually, this whole task can be broken into the following steps:

  • Implement a DLL that exports the CePimCommand function.
  • Register the Add-In for the desired application (Calendar, Contacts, or Tasks).

The next sections will describe these tasks in more detail.

Implementing an Add-In DLL

As noted above, your DLL has to implement and export the following function:

void EXPORT CePimCommand(HWND hWnd, PIMTYPE ptData,
UINT uDataCount, HANDLE *rghData,
void *pReserved)

When a user selects your command, this function will be called automatically. So, the DEF-file may look like the following:

; POOM2.def : Declares the module parameters for the DLL.
;DESCRIPTION ‘POOM2 Windows CE Dynamic Link Library’
; Explicit exports can go here

Now, take a closer look at the CePimCommand function and its parameters. The first two parameters are a window handle and type of calling application; in other words, Calendar, Contacts, or Tasks. In case your program will want to perform some actions upon a caller, it is very well set up. PIMTYPE should be declared as follows:

typedef enum tagPIMTYPE

Earlier versions of Windows CE have had different ordering of these applications; hence, this enumeration will work just fine on Pocket PC 2000 and later.

The next two parameters, uDataCount and rghData, bring us items selected in the caller application; for example, the specific Contact Item and so forth. To manipulate those items, you should pass the standard Pocket Outlook initialization sequence to obtain a POOM Application object (see the previous article, “How to Add Pocket Outlook Features to Your Mobile Application“). Once you’ve done this, you can continue operating in a regular POOM manner. rghData keeps object identifiers for selected items, so you may get actual objects by calling the IPOutlookApp.GetItemFromOid method:

ITaskPtr pTask;
CComBSTR bstrText;
for (int i = 0; i < uDataCount; i++)
hr = pPOOMApp->GetItemFromOid((long)rghData[i],
if ( SUCCEEDED(hr) )

The code snippet above performs the simplest loop over passed Task Items and displays their subjects. You may be required to carry out more complicated operations; for example, displaying a Contact’s photo or other additional information, but nevertheless you have full control over what’s going on.

Below, you will find a slightly more complicated sample illustrating that you are free to implement any required behavior in terms of GUI or functionality (see Figure 1 as an example):

void DoAction(HWND hWnd,PIMTYPE ptData,UINT uDataCount,
HANDLE *rghData,void *pReserved)
HRESULT hr = 0;
CLSID clsid;
LPOLESTR pProgID = L”PocketOutlook.Application”;
hr = CLSIDFromProgID(pProgID,&clsid);
IPOutlookAppPtr pPOOMApp;
hr = pPOOMApp.CoCreateInstance(clsid, NULL,
if ( FAILED(hr) )
AfxMessageBox(L”Failed to CreateInstance”);
AfxMessageBox(L”Failed to Logon”);
CArray<ITask*,ITask*> arrTasks;
CComBSTR bstrText;
for (int i = 0; i < uDataCount; i++)
ITask *pTask = NULL;
hr = pPOOMApp->GetItemFromOid((long)rghData[i],
if ( SUCCEEDED(hr) )
if ( arrTasks.GetSize() )
CAddInDlg dlg(&arrTasks);
for (int i = 0, s = arrTasks.GetSize(); i < s; i++)
BOOL CAddInDlg::OnInitDialog()
CComBSTR bstrSubject;
COleDateTime dtDueDate;
DATE date;
CString sLine;
for (int i = 0, s = m_pArrTasks->GetSize(); i < s; i++)
ITaskPtr pTask = m_pArrTasks->GetAt(i);
if ( 0 == pTask->get_DueDate(&date) && date != DATE_NONE )
dtDueDate = date;
sLine.Format(L”%s Due %02d/%02d/%02d”,
dtDueDate.GetYear() % 2000);
sLine.Format(L”%s Due None”,
return TRUE;

Figure 1

As a bottom line, CePimCommand just serves as an entry point for your application; you are totally free to develop software as complicated as only you can imagine.

Register Your Add-In

The simplest but most important step in deploying your Add-In is to register it to be used from the required Pocket Outlook application. To make it happen, there are only a few really simple steps you should do to proceed:

  1. Create a key in registry under HKLMSoftwareMicrosoftPimAppsPimExtensions
    To avoid any conflicts with any other possible add-ins, you can put here; for example, your company name.
  2. Create two entries under this key:

    • DLL (REG_SZ)—To provide a full path to your DLL; for example, WindowsPOOM2.dll.
    • Menu (REG_SZ)—To define the text of your Command in appropriate Tools menu; for example, “Call Our Developer Test.”

Figure 2

Usually, such registration is performed during the installation process; you only need to define appropriate Registry entries in your favorite Install tool, that’s all. Please note that you may insert your command (or commands) into several applications, getting it registered for each one of them. The result of such registration is shown in Figure 3:

Figure 3

Later on, your Add-In will get a caller type through the ptData parameter of the CePimCommand function. Unfortunately, you won’t be able to place several commands into one DLL because there is no info about which command was selected.


Now, you have enough information and samples to get POOM working in any way you just want to. With the growing popularity of mobile solutions, you can significantly enforce your applications by providing integrated support with Pocket Outlook. I obviously skipped some minor details in the discussions, but all you need to get started, you already know. Just do it.


Download the accompanying code’s zip file here.

About the Author

Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers’ lives in the mobile jungles a little bit simpler.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories