Using the Pocket Outlook Object Model SDK

Microsoft Corporation

August 1999

Summary: With the Pocket Outlook® Object Model (POOM), developers can build Microsoft Visual Basic® and Visual C++® applications that access the data and functionality of Pocket Outlook running on a Windows® CE device. (11 printed pages)

Click to copy the POOMSDK sample files.

With the Pocket Outlook Object Model (POOM), developers can build Microsoft Visual Basic and Visual C++ applications that access the data and functionality of Pocket Outlook running on a Windows CE device. In so doing, programmers can add sophisticated contact management, task tracking, and calendar scheduling capabilities to Windows CE applications. For example, developers can use POOM to manipulate the Calendar, Contacts, Tasks, and World Clock data on several varieties of Windows CE-based devices including the Palm-size PC, Handheld PC, and Handheld PC, Professional Edition. With POOM, you can develop applications that significantly increase the productivity of your mobile employees.

Building an Application Using POOM

In this sample, we will develop an application that retrieves a list of “today’s” contacts, tasks, and appointments from Pocket Outlook and displays them in list boxes. When the user wants to view a specific item in detail, we will use Pocket Outlook to show it. The user interface for the “VBToday” application is fairly straightforward:

Figure 1. User interface for VBToday application

This document will highlight the techniques used to access POOM from a Windows CE application written in Visual Basic. For more information, consult the in-code documentation in the accompanying downloadable POOM SDK sample files. For information on using POOM from a Visual C++ application, consult the in-code documentation in the accompanying downloadable POOM SDK sample files. The Visual C++ project duplicates the functionality found in the Visual Basic sample and includes examples on additional features found in the POOM SDK.

Installing POOM

Installing POOM is a three-step process, after which the POOM library is available on the device for developers to target with both Visual C++ and Visual Basic applications.

Install the POOM SDK

Double click on the PIMSTORE.EXE application and specify a target directory to which the files will be copied. Once copied, the directory should look like this:

Figure 2. Target directory

Among the extracted files is the POOM documentation. The POOM documentation describes the object model in detail, providing information on member variables and functions and is a valuable resource in including Pocket Outlook functionality with your applications.

Copy the DLL to the device

Once extracted, the POOM DLL must be copied to the \Windows directory on the device. Several POOM DLLs ship with the POOM SDK. Each DLL corresponds to a different processor family:

Processor Type DLL Name
Hitachi SH3 pimstore_sh3.dll
Hitachi SH4 pimstore_sh4.dll
StrongArm pimstore_sa1100.dll
MIPS 4000 Series pimstore_r4100.dll
MIPS 3000 Series pimstore_r3000.dll

Select the appropriate DLL and copy it to the device. Ignore any warnings about conversion problems. Once the DLL is on the device, rename it “PIMSTORE.DLL”.

Register the DLL on the Device

In order to register the DLL, you will need Microsoft Visual C++ 6.0 and the Windows CE Toolkit for Visual C++ 6.0. Start Visual C++ 6.0 and create a new project based on the “WCE Application” template. When the Wizard appears, select “A Simple Windows CE Application” and press “Finish”.

Figure 3. WCE Application wizard

In the resulting code Window, change the WinMain function to look like this:

int WINAPI WinMain(   HINSTANCE hInstance,
         HINSTANCE hPrevInstance,
         LPTSTR    lpCmdLine,
         int       nCmdShow)
{
   return RegisterPOOM();
}

Next, add the following code snippet above the WinMain function:

typedef HRESULT (*HRFUNC)();

HRESULT RegisterPOOM()
{
    HINSTANCE hPimstore;
    HRFUNC pProc;
    HRESULT hr;

    // Register POOM
    hPimstore = LoadLibrary(TEXT(“pimstore.dll”));
    if (!hPimstore)
    {
        return E_FAIL;
    }

    pProc = (HRFUNC) GetProcAddress(hPimstore, TEXT(“DllRegisterServer”));
    if (!pProc)
    {
        FreeLibrary(hPimstore);
        return E_FAIL;
    }

    hr = pProc();
    FreeLibrary(hPimstore);
    return hr;
}

Select the target device you wish to deploy to. In this case, the H/PC Pro 2.11 was selected:

Figure 4. Selecting target device

Now press the Build button to compile. You should get no errors or warnings. Press the Execute button to run the application. The registration application is a console application, so you should get no affirmative feedback. Nevertheless the POOM DLL is now registered on the device and we are ready to create our sample application.

Including POOM

In order to start using POOM, we must first define an object based on the PocketOutlook object. In addition, we should create constants that we can use later to specify whether we would like to retrieve contacts, tasks, or appointments from Pocket Outlook:

‘Although these constants are defined in the Object Browser, VBCE
‘will treat these constants as variables when running. Thus, we 
‘will need to define these constants ourselves so we can use them.
Const olFolderCalendar = 9
Const olFolderTasks = 13
Const olFolderContacts = 10

Dim pol As PocketOutlook.Application

Logging On to Pocket Outlook

In order to use POOM, we must first call CreateObject to instantiate the PocketOutlook object in the Form_Load function.

    ‘Call CreateObject to get the Application object. Note that 
    ‘this is a global variable, so we can access this object in 
    ‘other functions.
    Set pol = CreateObject(“PocketOutlook.Application”)
    

Once completed, we need to log on to Pocket Outlook. In the code snippet below, we call the Logon function, passing it the HWND to the parent window of our application. This ensures that any windows created by our application through Pocket Outlook are children of our application’s main window.

    ‘Now we will log on--this must be the first thing we do. 
    ‘Since we are going to be displaying items, we pass in the 
    ‘form’s HWND to Logon so that dialog boxes will be parented to 
    ‘this window. Otherwise, the user could go and display
    ‘multiple items at a time, which just wouldn’t work.
    pol.Logon (Form1.hWnd)

Getting Contacts

Upon execution, the application will query Pocket Outlook for a list of all contacts in the database. In so doing, the application will need to retrieve the Folder object corresponding to the Contacts database. Just as in the Outlook® 98 object model, a call to GetDefaultFolder, passing in the olFolderContacts constant created earlier, will retrieve a list of all Contact items in the database.

Once the Contact items collection is obtained, we can iterate through it, extract the “File As” information, and add it to the list. We will also set the Key attribute for the list item to the value of the Object ID (OID) for the contact item. We will use the Key attribute later on when we need to display individual contacts, tasks, and appointments.

    Dim myItems As PocketOutlook.Items
    Dim i As Integer
    Dim contItem As PocketOutlook.ContactItem
    Dim itmX As ListItem
    
    ‘Here we want to add all the Contacts to the listview. Start
    ‘by getting the Contacts folder, and then get its Item
    ‘Collection.
    Set myItems = pol.GetDefaultFolder(olFolderContacts).Items
    For i = 1 To myItems.Count

        ‘Add this item
        Set contItem = myItems.Item(i)
        Set itmX = ContactList.ListItems.Add(i, , contItem.FileAs, 0, 0)
        
        ‘Set the key to be the item OID--this way we won’t store 
        ‘the entire item in the listview (which would take lots of 
        ‘memory), but we can still access this item using
    ‘GetItemFromOid later
        itmX.Key = contItem.Oid

    Next i

Getting Tasks and Appointments

A similar technique is involved in obtaining information from the Tasks and Appointments databases, provided that the appropriate constant is passed to the GetDefaultFolder method. Unlike the LoadContacts method, both the LoadTasks and LoadAppointments methods restrict the information displayed to items that are due or occur “today.”

For example, after getting the items collection in the default task folder, we can call the Restrict method on the Items collection to ferret out the tasks for a specific date.

    ‘Grab the tasks folder, and get the item collection.
    Set myItems = pol.GetDefaultFolder(olFolderTasks).Items
    
    ‘Here we use Restrict to find only those items with a due date
    ‘of today. todaysItems will be a new Item Collection which
    ‘contains only those items which pass the restriction of
    ‘occuring today.
    Set todaysItems = myItems.Restrict(“[DueDate] = “““ & Date & ““““)
    For i = 1 To todaysItems.Count
   …

The rest of the function is similar to the procedure we used to iterate through the collection of Contact items.

For the appointments list box, a slightly different approach is taken. Rather than using the Restrict method on the items collection, we enumerate through the collection using the Find and FindNext methods, using only the items whose date matches “today.” Either technique is acceptable for this kind of function.

Displaying a Specific Contact

When the Display Contact button is pressed, we need to use Pocket Outlook to display the Contact information. Rather than creating our own visual representation of a Contact, we will simply invoke the Display method to have the Pocket Outlook application itself show the contact information. In so doing, we can maintain a consistent appearance between our application and the built-in Pocket Office applications.

Remember, the Key attribute for a given contact, task, or appointment item was set with the Object ID (OID) of the item as it is stored in the Pocket Outlook database. Once we determine which item is selected when the button is pressed, we can use the Key attribute, the OID, to get a pointer to the item, which we will instruct Pocket Outlook to display.

    ‘OK, get the entry ID and display this item.
    Dim contact As PocketOutlook.ContactItem
    Dim iSel As Integer
    
    ‘If there is a selected item, let’s display it.
    If (TypeName(ContactList.SelectedItem) <> “Nothing”) Then
        ‘Remember that the Key is really the OID of this contact.
        ‘We can call GetItemFromOid to get the contact item and
    ‘then display it.
        iSel = ContactList.SelectedItem.Index
        Set contact = pol.GetItemFromOid(ContactList.ListItems(iSel).Key)
        contact.Display
        
        ‘Contacts are the only items which will be updated after a 
        ‘call to Display. Thus, we can simply reset the text of 
        ‘this item in the listview to the new FileAs property--
        ‘in case it changed. This saves us from having to 
    ‘repopulate the entire list.
        ContactList.ListItems.Item(iSel).Text = contact.FileAs
    End If

Once we are finished displaying an item, we will reinsert it into the list, just in case the user changed the Contact. A similar approach to retrieving, displaying, and refreshing items is used for tasks and appointments. However, for tasks and appointments, instead of simply reinserting the item into the list after displaying it, we need to refresh the entire list. This is because there is no way to determine whether the date or other information was actually changed, causing the task or appointment to no longer fall on “today.”

Logging Off from POOM

Finally, before quitting our application we must log off from POOM in the Form_Unload function:

    ‘We are closing the form .. at this point, we should log off
    ‘from Pocket Outlook.
    pol.Logoff

More with POOM

As part of the Windows CE Plus Pack, the PIMToday application provides users with similar functionality to our sample application. Using POOM, PIMToday queries Pocket Outlook for all of the contacts, tasks, and appointments for “today.” As an additional POOM resource, the Visual C++ source code for the PIMToday application is also provided as part of this sample.

The Visual C++ source code includes analogous functionality to functionality found in our sample. For example, the Visual C++ code for populating a list box with contact information is very similar to its Visual Basic counterpart:

       IContact *pContact = NULL;

        i = 1;
        pItems->Item(i, (IDispatch **) &pContact);
        while (pContact)
        {
            // Add an item and store the OID, please.
            pContact->get_Oid((long *) &oid);
            hr = AddListViewItem(hwndList, oid, i-1);
            if ( FAILED(hr))
            {
                DEBUGMSG(1,(TEXT(“AddListViewItem() failed.\n”)));
            }

            // Now get the next item
            pContact->Release();
            pContact = NULL;
            pItems->Item(++i, (IDispatch **) &pContact);
        }
        
        if ( pContact ) pContact->Release();

You can access POOM functionality using the language that’s most appropriate for the task at hand and the language of your choice, preserving the same programming model.

Summary

The VBToday application we created is a small example of the functionality found in POOM. The new Pocket Outlook Object Model adds sophisticated contact management, task tracking, and calendar scheduling capabilities to Windows CE applications. Based on the Microsoft Outlook 98 Object Model, POOM makes it easy for Visual Basic and Visual C++ developers to build customized collaborative solutions across a range of Windows CE-based mobile devices.