Tuesday, December 20, 2005

So if you're working with Microsoft's new Microsoft.WindowsMobile.PocketOutlook namespace and trying to use the OutlookCollection.Restrict method to filter by a Contact's (or any PimItem's) ItemId field, you will likely run into a problem.

First, let me say the ItemID Class sucks.  It exposes basically nothing useful but a ToString() method, even though it holds numeric data.  And the first item added to POOM gets the ItemId of 0x80000001, which you might note is an *unsigned* number (again, the CLS is a pain for not allowing unsigned numbers).  So if you have an ItemId class and you want to use it, you have to do something like this:

unchecked
{
    int myId = int
.Parse(m_outlookSession.Contacts.Items[0].ItemId.ToString())
}

Really, that's how you have to do it.

So, let's say we have a Contact's ItemId and we want to see if the current session has said Contact.  One might try this:

m_outlookSession.Contacts.Items.Restrict("[ItemId]=" + itemId.ToString());

A nice try, but that gives you the not-so-helpful exception:

The query string is incorrectly formatted.
Parameter name: [ItemId]=-2147483647

Alright, so ItemId only exposes itself as a string, and Restrict has little in the way of useful documentation or samples, so maybe we can try it as a string like so:

m_outlookSession.Contacts.Items.Restrict("[ItemId]='" + itemId.ToString() + “'“);

Well that gives a similar exception, just adding the single quotes:

The query string is incorrectly formatted.
Parameter name: [ItemId]=-'2147483647'

Because I've used POOM from C++, I know that ItemId seems new to me, so just as a lark I figure I'll try 'Oid' as a field name instead, and keep it as a numeric:

m_outlookSession.Contacts.Items.Restrict("[Oid]=" + itemId.ToString());

Lo and behold, success!

Now technically this might not be a true bug, but it's sure not documented anywhere, nor would it be at all intuitive to guess if you'd not used C++ to access an IContact (which exports an Oid field, *not* an ItemId) before.  Bad Windows Mobile Team.  BAD!

Things needed:

  • The ItemID needs to have an explicit operator for conversion to an int at the very least.  A ToInt32 or ToIntPtr or something of the sort would be useful.
  • Either name the field Oid like it's stored in the database, or provide some sort of substitution so when I filter by ItemId the underlying class converts that to Oid.
  • The least they could have done was give exception text like “The field cannot be found in the collection“
  • Documenting how to remove a Restrict once set would be useful (I used Restrict(“[Oid]<>0“) for lack of any better idea)
12/20/2005 10:15:43 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
 Tuesday, December 13, 2005

Steven Pratschner has posted a really good blog entry on how the CF 2.0 CLR works.  Take a look.

12/13/2005 6:11:42 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, December 09, 2005
 Thursday, December 08, 2005

If you're seeing stange behavior in Media Player under CE 4.2, this might be of interest.

Symptom:

I have an MPEG4 QVGA file (WMV file extension) recorded with a bitrate of about 1000kbps.  When I play the video on the desktop everything is just fine.

When I play it on the device, bot the audio and video play, but the video "lags" the audio, and not by a small amount.  It's an incremental loss, so they start out fine, but over time the video get further and further behind the audio which plays at what sounds like a normal rate.

For example, when I play off of a CF card, by the time the audio is at 0:30 in, the video is only showing the frames from about 0:15.  You read that right, it's like the video is playing at about half speed.  If I play directly from RAM, the lag is about 30-40%.

Some other observations:

  • The "progress" bar on Media Player tracks with the audio, so when I play a 3:30 video, then the timer says 3:30, the audio finishes, yet the video continues to play, and from CF it will play for over another minute.  There's not enough memory on this thig for it to be buffering that entire minute of video somewhere.
  • If I pause playback at some point where the audio and video are out of sync, then restart, both continue from where they left off, still out of sync.
  • If I stop the video, drag the progress slider to some point in the middle of the video and start it, the audio and video start synchronized at that point and begin diverging immediately.
  • If I add a load to the system by holding my finger on the touchpanel and wiggling the media player window around, thereby causing lots of interrupts, the lag amount does not change at all - so it seems load on the system doesn't affect how far off it gets.
  • If I resize the window, making the video eitehr much larger (out to VGA) or much smaller than the 320x240 it was recorded at, the lag does not change.
  • The video plays fine on my WM5.0 device with a PXA270 (no graphics accelerator) off of SD, smooth video and audio.
  • The video plays ok on my Pocket PC 2003SE device from CF or SD.  The audio is smooth, but the video is a bit choppy from dropped frames.  The important thing though is that even with that, the video and audio are still in sync.  That's how I thought Media Player was supposed to work and would be the behavior I'd expect on the custom hardware.

Explanation from Microsoft

“The problem was rooted from a frame dropping algorithm developed in Windows CE media player before 5.0. We have fixed correspondent bugs in CE 5.0 regarding this issue. So, from 5.0, CE media player does not have this problem.

If the HW resource is plentiful, e.g. faster CPU and memory bus speed (270 compared to 255), there would not be any frame drop. So, there won't be any A/V sync problem, as you see on the 270 and desktop.

When you read data from a memory card (depending on how fast your card is), or display high bitrate video (e.g. 1mbps QVGA for 255), or on a slow CPU, CE Media Player on 4.2 could potentially trigger this frame dropping mode and therefore exhibit the A/V sync issue when dropping frames.

Windows CE Media Player and PocketPC Media Player use a different code base because CE Media Player needs to support a variety of HW platforms while PPC media player focuses on a single environment. This issue of A/V sync when dropping frames does not exist in the PocketPC Media Player code base.”

12/8/2005 6:07:21 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Tuesday, November 29, 2005

The Crime:  My CE device runs a CF app just fine when I deploy it manually, but once I connect to it from Studio for deployment and then cycle the power, not just my app, but all CF apps no longer work.  Reflashing the image on the device repairs the sitation.  What the hell is going on?

The Evidence:
Article #1: Studio saves connection security info in the device registry
Article #2: Studio saves connection security info in RAM of the device (in the root folder)
Article #3: When a CAB file is expanded, RegFlushKey is called
Article #4: When Studio deploys the CF, it does so as a CAB
Article #5: When a device is reset all RAM is lost
Article #6: The CF requires that the info in RAM and the registry match to launch

Verdict:
When I make a connection some info is stored on the device in RAM and the registry.  When I deploy, half that is persisted.  When I reset the device or pull power the other half is lost, causing all CF apps to no longer run on the device unless I erase the persistent registry (which depending on your device may mean reflashing the whole damned thing).
 
Sentence:
Run DelCryptoKeysDevice.exe (part of Windows CE Utilities for Visual Studio .NET 2003 Add-on Pack 1.1) to erase the info from the registry.  Doing it on startup by adding it to your image and this to platform.reg means you can forget about it:
[HKEY_LOCAL_MACHINE\init]
        "Launch55"="DelCryptoKeys.exe"
        "Depend55"=hex:14,00, 1e,00

11/29/2005 4:50:47 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  |