Recent

Author Topic: Microsoft.WindowsMobile.PocketOutlook.dll  (Read 25049 times)

aji

  • New Member
  • *
  • Posts: 13
Microsoft.WindowsMobile.PocketOutlook.dll
« on: February 07, 2008, 07:01:30 pm »
Anyone have any ideas how to access the PocketOutlook.dll for Windows Mobile 6.
I don't have much experience accessing dll's, so any help would be greatly appreciated.

This is the code I have in a C# application, to add a new task in Outlook:
Code: [Select]

using Microsoft.WindowsMobile.PocketOutlook;
....
  // Open an outlook session
OutlookSession outlookSession = new OutlookSession();
  // Retrieve the tasks from outlook
TaskCollection tasks = outlookSession.Tasks.Items;
Task task = new Task();
task.Subject="test outlook";
task.DueDate= System.DateTime.Now;
tasks.Add(task);
outlookSession.Dispose();


This is what I have figured out so far:

Code: [Select]

var
    h : cardinal;
begin
      h:=Loadlibrary('Microsoft.WindowsMobile.PocketOutlook.dll') ;  

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
RE: Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #1 on: February 09, 2008, 10:11:39 am »
Try searching on google or asking on ms newsgroups or other forums for a C or C++ code that does what you want.

C# code is no good because can't be easely converted into native code.

stootch

  • New Member
  • *
  • Posts: 14
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #2 on: March 05, 2008, 08:30:33 am »
Hi aji

Any progress on accessing POOM?

I've been searching around for a while and came to the conclusion that we -- FreePascal developers -- would need some kind of translation library (dll) which would talk to the original dll and expose methods and properties to Pascal. This is because POOM and other WM2005+ libraries intensively use interfaces which are not well implemented in FPC and literally abandoned in CE port. Of course the 'translation library' should be written in C with one of the MS compilers (perhaps there are others I don't know about?).

Currently I plan to write some subroutines to access contact list. Anyone willing to participate or help? It was long time ago when I did C(++) programming. :cry:

oraitecamonyes

  • New Member
  • *
  • Posts: 31
    • http://blog.ptvet.com
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #3 on: March 05, 2008, 11:56:18 am »
maybe this helps:
http://www.drbob42.com/delphi/headconv.htm

it has the TYPE CONVERSION between C/C++ to PASCAL.
it also has this tool:
Quote
Tool Support - HeadConv v4.20
So far, we have seen that part of the conversion process is easy, part of it is hard, and a lot of it is simple 'monkey' work, that is neither complex nor particularly rewarding to do. In order to support myself in the monkey-work, I've written a little program to help me: HeadConv (latest version is v4.20). Targeted at the serious Delphi developer, the HeadConv Expert will assist in the task of converting the C DLL header files to Delphi import units, thereby giving all Delphi users access to the huge world of third-party C DLLs.
The latest version of HeadConv v4.20 is available as command-line and Wizard edition


another website:
http://rvelthuis.de/articles/articles-cppobjs.html

aji

  • New Member
  • *
  • Posts: 13
Poom
« Reply #4 on: March 06, 2008, 12:54:18 am »
Quote from: "stootch"
Hi aji

Any progress on accessing POOM?

I've been searching around for a while and came to the conclusion that we -- FreePascal developers -- would need some kind of translation library (dll) which would talk to the original dll and expose methods and properties to Pascal. This is because POOM and other WM2005+ libraries intensively use interfaces which are not well implemented in FPC and literally abandoned in CE port. Of course the 'translation library' should be written in C with one of the MS compilers (perhaps there are others I don't know about?).

Currently I plan to write some subroutines to access contact list. Anyone willing to participate or help? It was long time ago when I did C(++) programming. :cry:


I wish I could help, but I can barely use the POOM in C#, and have no ideas about DLL's or programming in C++.  I guess I don't quite understand why FreePascal can't interact directly with the POOM. Can we use the older Pimstore?
I have been searching and searching, but haven't found anything that worked. At this point I'm tempted to write an application in C# and call that from FreePascal.

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #5 on: March 06, 2008, 02:44:29 am »
Quote from: "stootch"
This is because POOM and other WM2005+ libraries intensively use interfaces which are not well implemented in FPC and literally abandoned in CE port.


How do you base this statemente? Are there bug reports for interfaces on the bug tracker? Are there bug reports specifically for wince? I'm never seen one. Free Pascal *does* implement interfaces on all platforms.

I still remain with my original statement. Please someone post some C or C++ code that does what you want here so I can help you convert it to Pascal.

C# code helps nothing because it can't be easely converted to Pascal.

Quote
It was long time ago when I did C(++) programming. :cry:


There is absolutely nothing you can do in C/C++ that you can't in Free Pascal.

aji

  • New Member
  • *
  • Posts: 13
C++ code example
« Reply #6 on: March 07, 2008, 05:56:03 pm »
Quote from: "sekel"

I still remain with my original statement. Please someone post some C or C++ code that does what you want here so I can help you convert it to Pascal.


Here is the code for displaying tasks from Pocket Outlook. This is taken from Microsoft's PoomMaster example:

Code: [Select]

// ************************************************************
// POOMTASKS.CPP
//
// Implementation of reading / creating POOM task information
//
// Copyright 1986-2003 Microsoft Corporation, All Rights Reserved
#include "PoomMaster.h"

// **************************************************************************
// Function Name: AddTaskFolderText
//
// Purpose: Reads and adds existing POOM tasks to the main listbox
//
// Arguments:
//    IN IPOutlookItemCollection * pItenCol - ptr to the Tasks default folder
// collection interface
//
// Return Values:
//    Describes the return type an meaning of each value.  E.g.:
//    BOOL
//    returns TRUE if the item was successfully read and added. Otherwise FALSE
//
// Description:  
//   This function iterates through the collection of tasks, reading
// properties from each. The string data is then added to the main
// listview control
BOOL AddTaskFolderText(IPOutlookItemCollection * pItemCol)
{
HRESULT hr;
BSTR bstrSubject;

ITask * pTask = NULL;
int cItems = 0;

hr = pItemCol->get_Count(&cItems);

for (int i = 1; i <= cItems; i++)
{
hr = pItemCol->Item (i, (IDispatch**)&pTask);

hr = pTask->get_Subject(&bstrSubject);

AddToList(bstrSubject);
pTask->Release();
}

return TRUE;

}

// **************************************************************************
// Function Name: GetTaskPriority
//
// Purpose: Returns the Task importance given an index from the listbox
//
// Arguments:
//    IN int nIndex - position within the listbox which corresponds (off-by-one)
// with the position in the item collection
//
// Return Values:
//
//    int
//    returns olImportanceLow, olImportanceNormal, or olImportanceHigh
//
// Description:  
//   This function takes an index, gets the corresponding Task item, and returns
// its Importance property
int GetTaskPriority(int nIndex)
{
IFolder * pFolder = NULL;
IPOutlookItemCollection * pItemCol = NULL;
ITask * pTask = NULL;
LONG nRetVal;

GetPoomFolder(olFolderTasks, &pFolder);
pFolder->get_Items(&pItemCol);

pItemCol->Item(++nIndex, (IDispatch**)&pTask);

pTask->get_Importance(&nRetVal);

return nRetVal;
}
// **************************************************************************
// Function Name: TaskIsComplete
//
// Purpose: Returns the Task completion state given an index from the listbox
//
// Arguments:
//   none
//
// Return Values:
//
//    BOOL
//    returns TRUE if the task is complete, FALSE otherwise
//
// Description:  
//   This function takes an index, gets the corresponding Task item, and returns
// its Complete property
BOOL TaskIsComplete(int nIndex)
{
IFolder * pFolder = NULL;
IPOutlookItemCollection * pItemCol = NULL;
ITask * pTask = NULL;
VARIANT_BOOL vbIsComplete;

GetPoomFolder(olFolderTasks, &pFolder);
pFolder->get_Items(&pItemCol);

pItemCol->Item(++nIndex, reinterpret_cast<IDispatch**>(&pTask));

pTask->get_Complete(&vbIsComplete);

return vbIsComplete;
}
// **************************************************************************
// Function Name: NewTaskProc
//
// Purpose: Processes messages for the new task dialog window
//
// Arguments:
//    IN HWND hDlg - handle to the dialog window
//  IN UINT message - indentifier for message to be processed
//  IN WPARAM wParam - message parameter
//  IN LPARAM lParam - message parameter
//
// Return Values:
//  LRESULT
// The return value is the result of the message processing and depends on
// the message sent.
//
// Description:  
//    This is a standard dialog window message processing function. It handles
// WM_INITDIALOG and WM_COMMAND messages. Upon receipt of an IDOK notificationm
// a new task is created according to values entered for subject and importance
LRESULT CALLBACK NewTaskProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{

BSTR bstrDesc;
int nPriority;
IPOutlookApp * pOutApp = NULL;
ITask * pTask = NULL;

switch (message)
{

case WM_INITDIALOG:


InitNewItemDlg(hDlg);

SendMessage(GetDlgItem(hDlg, IDC_IMPORTANCE), CB_INSERTSTRING, 0, (LPARAM) _T("High"));
SendMessage(GetDlgItem(hDlg, IDC_IMPORTANCE), CB_INSERTSTRING, 0, (LPARAM) _T("Medium"));
SendMessage(GetDlgItem(hDlg, IDC_IMPORTANCE), CB_INSERTSTRING, 0, (LPARAM) _T("Low"));

SendMessage(GetDlgItem(hDlg, IDC_IMPORTANCE), CB_SETCURSEL, 1, 0);

return TRUE;

case WM_COMMAND:

switch (LOWORD(wParam))
{
case IDM_CANCEL:

EndDialog(hDlg, IDCANCEL);
break;

case IDM_OK:
case IDOK:

GetCtrlBstr(hDlg, IDC_TASKDESC, &bstrDesc);

nPriority = SendMessage(GetDlgItem(hDlg, IDC_IMPORTANCE), CB_GETCURSEL, 0, 0);

if (nPriority == 0)
nPriority = olImportanceLow;
else if (nPriority == 1)
nPriority = olImportanceNormal;
else
nPriority = olImportanceHigh;

if (SysStringLen(bstrDesc) > 1)
{
if (GetPoomApp(&pOutApp))
{
if (SUCCEEDED(pOutApp->CreateItem(olTaskItem, reinterpret_cast<IDispatch**>(&pTask))))
{
pTask->put_Subject(bstrDesc);
pTask->put_Importance(nPriority);
pTask->Save();

pTask->Release();
pOutApp->Release();
}
}
}


EndDialog(hDlg, IDOK);
return TRUE;

}
break;
}
return FALSE;
}


and PoomMaster.h:
Code: [Select]


#if !defined(AFX_POOMMASTER_H__6FF2A2E6_F8C1_478E_A5FA_DEC0CEE72870__INCLUDED_)
#define AFX_POOMMASTER_H__6FF2A2E6_F8C1_478E_A5FA_DEC0CEE72870__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <pimstore.h>

#include <windows.h>
#include <aygshell.h>
#include "resource.h"


//interface IFolder;

#define MENU_HEIGHT 26

enum eDisplayMode {EDM_TASKS, EDM_CONTACTS, EDM_CALENDAR};

BOOL InitPoom(HWND hwnd);
void ShutdownPoom();
BOOL GetPoomFolder(int nFolder, IFolder ** ppFolder);
BOOL PopulateList(int nFolder);
BOOL GetPoomApp(IPOutlookApp **ppOutApp);
BOOL AddTaskFolderText(IPOutlookItemCollection * pItemCol);
BOOL AddContactsFolderText(IPOutlookItemCollection * pItemCol);
BOOL AddCalendarFolderText(IPOutlookItemCollection * pItemCol);
void AddToList(TCHAR * tszTxt);
int GetTaskPriority(int nIndex);
BOOL TaskIsComplete(int nIndex);

void GetCtrlBstr(HWND hDlg, int nCtrlId, BSTR * pbstrTxt);


BOOL InitNewItemDlg(HWND hDlg);

LRESULT CALLBACK NewContactProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK NewTaskProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK NewAppntmntProc (HWND, UINT, WPARAM, LPARAM);



#endif // !defined(AFX_POOMMASTER_H__6FF2A2E6_F8C1_478E_A5FA_DEC0CEE72870__INCLUDED_)


Does this help?

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: C++ code example
« Reply #7 on: March 07, 2008, 07:34:52 pm »
Quote
Does this help?


Yes, but this is only the example application code. There is something else missing with the real headers to the library, probably one of the other include files. I would guess it's:

#include <pimstore.h>

About the example code, it isn't hard to translate to pascal. I'll give you an example. Both the .h and the .cpp go to the same .pas in pascal. Also add Windows and ctypes on the uses clause. Maybe other stuff will also be necessary.

Code: [Select]

BOOL TaskIsComplete(int nIndex)
{
   IFolder * pFolder = NULL;
   IPOutlookItemCollection * pItemCol = NULL;
   ITask * pTask = NULL;
   VARIANT_BOOL vbIsComplete;
   
    GetPoomFolder(olFolderTasks, &pFolder);
   pFolder->get_Items(&pItemCol);

   pItemCol->Item(++nIndex, reinterpret_cast<IDispatch**>(&pTask));

   pTask->get_Complete(&vbIsComplete);
   
   return vbIsComplete;
}


becomes:

Code: [Select]

function TaskIsComplete(nIndex: cint): cbool;
var
   pFolder: IFolder = nil;
   pItemCol: IPOutlookItemCollection = nil;
   pTask: ITask = nil;
   vbIsComplete: VARIANT_BOOL; // what is that? A Variant?
begin    
   GetPoomFolder(olFolderTasks, @pFolder);
   pFolder.get_Items(@pItemCol);

   Inc(nIndex);
//   pItemCol.Item(nIndex, reinterpret_cast<IDispatch**>(&pTask)); This looks complex. Having the declaration of IPOutlookItemCollection would help a lot ...
   pItemCol.Item(nIndex, pTask);

   pTask.get_Complete(@vbIsComplete);
   
   Result := vbIsComplete;
end;

aji

  • New Member
  • *
  • Posts: 13
RE: Re: C++ code example
« Reply #8 on: March 07, 2008, 08:24:32 pm »
Thanks for the code example. I'll try and work with it next week. In the meantime I found the pimstore.h file which would explain the entry point for the dll (?). It's split into c++ and c interface.
Here is the beginning:
Code: [Select]

#ifndef __ITask_FWD_DEFINED__
#define __ITask_FWD_DEFINED__
typedef interface ITask ITask;
#endif  /* __ITask_FWD_DEFINED__ */

#ifndef __TaskItem_FWD_DEFINED__
#define __TaskItem_FWD_DEFINED__

#ifdef __cplusplus
typedef class TaskItem TaskItem;
#else
typedef struct TaskItem TaskItem;
#endif /* __cplusplus */

#endif  /* __TaskItem_FWD_DEFINED__ */

#ifndef __ITask_INTERFACE_DEFINED__
#define __ITask_INTERFACE_DEFINED__

/****************************************
 * Generated header for interface: ITask
 * at Mon Dec 07 11:02:04 1998
 * using MIDL 3.02.88
 ****************************************/
/* [dual][full][helpstring][uuid][object] */



DEFINE_GUID(IID_ITask, 0x37c78ce0, 0x202c, 0x11d2, 0x8f, 0x18, 0x0, 0x0, 0xf8, 0x7a, 0x43, 0x35);



Here is everything that refers to the subject part of the task: (c interface)
Code: [Select]

/* [propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Subject )(
            ITask __RPC_FAR * This,
            /* [retval][out] */ BSTR __RPC_FAR *ppwsz);

/* [propput] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_Subject )(
            ITask __RPC_FAR * This,
            /* [in] */ BSTR pwsz);

#define ITask_get_Subject(This,ppwsz)   \
    (This)->lpVtbl -> get_Subject(This,ppwsz)

#define ITask_put_Subject(This,pwsz)    \
    (This)->lpVtbl -> put_Subject(This,pwsz)


It's this part that makes me want to give up and start learning a foreign language instead :roll:

I don't know much about entry points to dll's and feel totally lost.

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: RE: Re: C++ code example
« Reply #9 on: March 07, 2008, 11:39:43 pm »
Quote from: "aji"
I don't know much about entry points to dll's and feel totally lost.


There is nothing about dll entry points in the header, and there also shouldn't be. It's just declaration of some type. Unfortunatelly they look too incomplete, like a forward declaration and the real declaration would be somewhere else ... just don't know where.

Search for IPOutlookItemCollection in the files you have and find where it's declared. Lazarus has a Find in Files dialog which is very useful in this cases.

The code you posted would be translated to something like this:

Code: [Select]

type
  ITask = interface
    ['{37c78ce0-202c-11d2-8f18-0000f87a4335}']
  end;

  TaskItem = record
  end;


As you can see the methods of the interface are missing. The C interface isn't necessary, we already have the object oriented one.

stootch

  • New Member
  • *
  • Posts: 14
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #10 on: March 11, 2008, 05:34:47 am »
Quote from: "sekel"
How do you base this statemente? Are there bug reports for interfaces on the bug tracker? Are there bug reports specifically for wince? I'm never seen one. Free Pascal *does* implement interfaces on all platforms.

Does IDispatch work correctly? Last time I checked it didn't:
Quote
Remark: Dispatch interface support for variants is currently broken in the compiler.

Quote from: "sekel"

There is absolutely nothing you can do in C/C++ that you can't in Free Pascal.

Agree. However, things get complicated when your code must cooperate with or use C/C++ code (DLLs).

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #11 on: March 11, 2008, 10:35:06 am »
Quote from: "stootch"

Does IDispatch work correctly? Last time I checked it didn't:


Yes, you are right, but it isn't clear at this point for me that the PocketOutlook requires that. It even has a C interface as a last resource.

Quote
Agree. However, things get complicated when your code must cooperate with or use C/C++ code (DLLs).


I'd say someone needs to do it once and then everyone will be able to use the created interface without major headaches.

You might want to know it's also possible to pay a bounty for someone to write the interface. That's how the Apache translations got done:

http://wiki.lazarus.freepascal.org/Bounties

stootch

  • New Member
  • *
  • Posts: 14
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #12 on: March 12, 2008, 09:24:39 am »
Quote from: "sekel"

it isn't clear at this point for me that the PocketOutlook requires that


Excerpt from pimstore.h:

Code: [Select]

DEFINE_GUID(IID_IContact, 0x7f804e40, 0x2010, 0x11d2, 0x8f, 0x18, 0x0, 0x0, 0xf8, 0x7a, 0x43, 0x35);

#if defined(__cplusplus) && !defined(CINTERFACE)

    interface DECLSPEC_UUID("7F804E40-2010-11d2-8F18-0000F87A4335")
    IContact : public IDispatch
    {
    public:
   
   <cut>

        virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_CompanyName(
            /* [retval][out] */ BSTR __RPC_FAR *ppwsz) = 0;


IDispatch appears almost everywhere, so we can forget about accessing POOM this way for a while.

Quote from: "sekel"
It even has a C interface as a last resource.


Yes, indeed. Take a look at this:

Code: [Select]

#else   /* C style interface */

    typedef struct IContactVtbl
    {
        BEGIN_INTERFACE

       <cut>

        /* [propget] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CompanyName )(
            IContact __RPC_FAR * This,
            /* [retval][out] */ BSTR __RPC_FAR *ppwsz);


STDMETHODCALLTYPE is simply __stdcall and since our code runs (mostly) on ARMs, we can ignore calling convention. The __RPC_FAR thing is a macro that ensures returning value is of correct type. This can be ignored too. BSTR is a binary string and we can use WideString instead. What's left? Oh, IContact. See where the problem is?

So, "C style interface" is not a counterpart to C++ but seems to be supplement for those who want to stick with C.

I'll repeat my statement: we need a kind of C middlelib which would "flatten" objects or interfaces into simple exported functions we could make use of.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2584
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #13 on: March 12, 2008, 12:32:54 pm »
Just to note, there is no compiler support for dispatch interfaces, however, you can still use them manually. (it takes some more work and understanding though)

Sample of code when IDispatch is fully supported:
Code: [Select]

var
  V: OLEVariant;
  S: String;
begin
  V := GetSomeDispatchableObject;
  S := V.GetText;
end;


Rough sample of code when doing manual (and something the compiler generates for the above example):
Code: [Select]

var
  D: IDispatch;
  T: ITypeInfo;
  S: String;
  id: CInt;
  Params: TDispParams;
  Res: OLEVariant;
  error: CUInt;
begin
  D := GetSomeDispatchableObject;
  D.GetIdOfnames(IID_NULL, 'GetText', 1, id);
  D.GetTypeInfo(id, 0, T);
  //use T to find out the params and result types (in our case no args)
  Params.rgvarg := nil;
  Params.rgdispidNamedArgs := nil;
  Params.cArgs := 0
  Params.NamedArgs := 0;
  // finally call GetText
  D.Invoke(id, IID_NULL, 0,  DISPATCH_METHOD, Params, Res, nil, error);
  S := Res;
end;
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

stootch

  • New Member
  • *
  • Posts: 14
Microsoft.WindowsMobile.PocketOutlook.dll
« Reply #14 on: March 16, 2008, 06:40:18 am »
Thanks for tip, Marc. I'll try it a bit later -- as for me it requires some serious tests to understand things better. Luckily I haven't thrown out my Delphi yet ;)

Meanwhile I found a workaround and currently can access Pocket Outlook's data, both reading and writing. I will post full description soon.

 

TinyPortal © 2005-2018