Tuesday, September 28, 2004

210.aspx

Using the POOM from .NET CF 1.0

I organize my work (and a fair bit of my life) with the Outlook task list. In Outlook I have a customized view that shows all tasks due today, grouped by priority. This feature does not exist on the Pocket PC so I implemented a simple task manager with embedded VB which I used a lot on my old iPAQ. I didn't want to install the VB runtime on my new iPAQ 4150 so I decided to rewrite it in .NET CF.


I didn't get far before I hit the first hurdle though: accessing Pocket Outlook with .NET CF.


The problem is that Pocket Outlook is only available via the IPOutlookApp COM interface and .NET CF does not support calling COM components. The latest news I have from Microsoft is that this will be fixed in the next version. I quickly found the commercial PocketOutlook In The Hand component from InTheHand for accessing POOM. Both The Windows Mobile Team Blog and Omar Shahine refer to the InTheHand component as the way to go. But, in the end, I decided to continue on my DIY quest for several reasons;



  • I wanted to learn how to access COM components from .NET CF
  • I didn't feel like paying $40 for a component I will only use on a personal project

The only way to call a COM component with .NET CF is to write a standard DLL that wraps the COM methods. A lot of work, as POOM has a lot of objects, methods and properties. The great news is that you can find all the free tools and source code you need on the Microsoft web site(s):



The POOM C++ wrapper support all the objects (at least the ones I have checked). It also comes with a .NET CF client that shows how to access the Pocket Outlook contacts.  The .NET CF client is fairly limited as it only imports some of the C++ managed DLL methods. It is very simple to extend as you only have to add new DllImport's. I added the methods (get and set) for accessing the DueDate and it compiled like a charm but bombed on the Pocket PC when I tried to set the DueDate. I found the problem after having a closer look at the C++ code. The (put) DueDate method signature was:


HRESULT ITask_put_DueDate(ITask* thisPtr,


           DATE st)


{


  return thisPtr->put_DueDate(st);


}


 


The problem is the st argument. It passes an OLE Automation DATE which is 8 bytes.  .NET CF doesn't support arguments larger than 4 bytes (32 bit) so the source code has to be changed to pass a pointer (4 bytes) to a date:


HRESULT ITask_put_DueDate(ITask* thisPtr,


           DATE* st)


{


  return thisPtr->put_DueDate(*st);


}


 


The C# code has to be fixed as well. The correct DllImports are:


[ DllImport("PocketOutlook.dll", EntryPoint="ITask_get_DueDate") ]


private static extern int do_get_DueDate(IntPtr self,


                                          ref double dueDate);


 


[ DllImport("PocketOutlook.dll", EntryPoint="ITask_put_DueDate") ]


private static extern int do_put_DueDate(IntPtr self,


                                          ref double dueDate);


 



Almost there, one more thing do do: add a C# property wrapper for the DllImports


public System.DateTime DueDate


{    


      get


      {                      


            double doubleDate = 0.0;


            PocketOutlook.CheckHRESULT(do_get_DueDate(this.RawItemPtr, ref doubleDate));                   


            return PocketOutlook.OleDateToDateTime(doubleDate);


      }    


 


      set


      {                      


            double doubleDate = PocketOutlook.DateTimeToOleDate(value);


            PocketOutlook.CheckHRESULT(do_put_DueDate(this.RawItemPtr, ref doubleDate));


      }


}


 


The code uses the .NET 1.0 CF Date conversion source code I posted earlier to convert the DATE arguments to System.DateTime


Fix the bugs in the Microsoft code you have a free .NET CF POOM client. Cool Or What?

13 comments:

  1. Hi,



    you can't imagine, how grateful i am. For this, i searched the whole fu*** web, and lasty found it

    here. All there is, is Inthehand here and there, or buy the stuff, but how to do it without buying..



    All i want to say is : thank you very much!



    Thomas.

    ReplyDelete
  2. Hi!

    This is just amazing.Thank you very much!!! U have save me!!! :)

    Thanks again

    ReplyDelete
  3. Glad you found the information you were looking for! I went crazy looking for the pieces of the puzzle as well.



    I can put the compiled C++ dll on the site if you want to download the fixed binaries directly.



    I was considering extending the .NET wrapper to support the entire set of POOM functionality, but is a lot of cut and paste of boilerplate code and testing so I am not sure if it is worth the effort. Especially as I don't need it for my apps (at least not yet).

    ReplyDelete
  4. Can u please post your precompiled dll on your site? thanks for the help on POOM! :)

    ReplyDelete



  5. thanks very much



    including pocket 'inbox' process?

    ReplyDelete
  6. POOM does not give access to the Inbox folder but to the Calendar, Cities, Contacts, Infrared and Tasks folders.

    ReplyDelete
  7. Oh ,I see.



    By the way, How can I access the Inbox folder ?



    I want to read/write the mail messages.



    Could you give me any information to me?



    Thanks again!

    ReplyDelete
  8. thanks a lot.



    but my device is hp iPAQ 6500,



    it is using Windows Mobile 2003 SE.



    how do I access the Inbox data?

    ReplyDelete
  9. I am on a business trip today & tomorrow. I will get back to you by the weekend.

    ReplyDelete
  10. hi Egil Hogholt,



    CEMAPISample.zip still can not help me,



    it 's a MFC application.



    but my clients need me to use Non-MFC dll or app,



    I having trouble, like CArray,CByteArray,CString,...etc ,



    these are MFC class using in the CEMAPISample.zip sample.



    I dont know how to replace them with standard c++?



    Sir,Can you help me again?



    Thanks a lot first!





    -Almond

    ReplyDelete
  11. I can understand that your client does not want an application that depends on external DLLs like MFC. But, what if you build using MFC as "static library" instead of the default "Shared DLL"? In that case it is completely transparent to the client as the MCF code will be included in your exe/dll so it does not require any external dlls.



    Cheers,

    Egil

    ReplyDelete
  12. Hi



    Stupid question, what's the copyright on the PocketOutlookWrapper? Safe to use in my own applications? I see copyright Microsoft at the top of the code so I'm not sure, there are no terms listed.



    Regards



    Igor

    ReplyDelete