Monday, May 29, 2006

Windows CE != Windows Mobile

"Windows Mobile is not Windows CE (and vice-versa), Windows Mobile has Windows CE as its core – WM 2003 was based on WinCE 4.x, WM 5.0 is based on WinCE version 5 – plus a standard shell, applications and APIs." (link and a follow up here)

Wednesday, May 24, 2006

Alpha Blending

Since my last post was on drawing transparency color keys in .NET CF, I thought I should explore alpha blending as well. It is possible to do alpha blending .NET CF, but not without some effort (i.e., venturing into p/invoke). Here, at the .NET CF UI and More blog, the author writes:

Briefly, there are two ways to do alpha blending in WM5: the AlphaBlend() function and with the Image COM object in the Imaging API.

He then goes on to explain how to implement these two methods. (direct link). The happy alternative is offered through OpenNetCF (who else) in their SDF 2.0 library. See Alex Feinman's post here.

Transparency

This morning I googled around for "standard transparency colors" in hopes that I would find a color key that is typically used to represent transparency in images. In .NET CF, the only way to make part of an image transparent is through the following code:

ImageAttributes attr = new ImageAttributes();
attr.SetColorKey(Color.White, Color.White);
Rectangle rDest = new Rectangle(xImage, yImage, Image.Width, Image.Height);
g.DrawImage(Image, rDest, 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel, attr);


In this case, the color "white" would be made transparent in the given Image. Note that although SetColorKey allows the developer to specify a transparency color range, I believe that this range is limited to one color on .NET CF. During my search, I found that the standard chroma key is "bright pink." However, it's also convention to automatically select the chroma key based on the upper-left hand corner pixel of the image, in hopes that this is representative of the "background" pixels. Here's a post by Ed Kaim (MSFT) that really explains this well imo.

"However, the issue you're raising is why Microsoft recommends the usage of ImageAttributes in order to draw transparency, and why the top left pixel is called out as a prime source. First of all, ImageAttributes is the only feasible way to draw transparency in managed code on the .NET Compact Framework. Otherwise you'd have to go pixel by pixel and only draw the nontransparent ones, which would be slow and painful. The reason the top left pixel is offered is because it's often transparent in images with transparency. Sure, it's not *always* transparent, but it's usually transparent, due to its location in the image and the fact that most pictures on buttons don't go all the way to the top left border. However, you can decide that your standard chroma key color is bright pink (as many do) and hardcode your ImageAttributes object to use that color for all images, provided you do the work in the art to make sure the same exact color is used on the transparent spots in your files, whatever format they may be."

Monday, May 22, 2006

Retrieving an Assembly's PublicKeyToken

The short of it is, use the sn -T blah.dll command (see link). Here's the step-by-step for finding the PublicKeyToken of the System.Data.SqlServerCe.dll:

1. Open up the Visual Studio 2005 Command Prompt from the Start Menu. That should set the environment for using VS2005 commands.
2. C:\>cd "C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\"
3. Type "sn -T System.Data.SqlServerCe.dll"

The sn utility will return something like: Public key token is 3be235df1c8d2ad3

Note: if you do not include a capital T (but instead a lowercase, -t), you will receive the following error: "Failed to convert key to token -- The public key for assembly '(null)' was invalid."

ActiveSync 4.1, Sit & Spin

As a .NET CF developer, I'm getting quite tired of dealing with the obvious failings of ActiveSync. It is, without a doubt, one of the most frustrating programs I've been forced to deal with. I'm currently struggling with the problem where you plug-in a Windows Mobile 5.0 device to a desktop machine running ActiveSync 4.1 and ActiveSync just sits there and continuously spins the green icon while displaying "Connecting." It will literally do this for hours (if I let it). See screen below:


I've scoured the net for a solution and have found none. This has been happening off and on since I started working on Windows Mobile 5.0 devices. Unfortunately, I have not been able to diagnose the cause. Restarting the device does not solve the problem. Restarting the desktop (which I hate doing) does not solve the problem. Sometimes, moving the USB cable from one port to another works, but not always. I can waste a full hour or so simply trying to get my activesync connection up so I can debug my program. :(

Oh and the online KB has a few reported issues with regards to ActiveSync 4.1:
http://support.microsoft.com/kb/911422/en-us
http://support.microsoft.com/kb/912240/en-us

and, perhaps most relevant,

http://support.microsoft.com/kb/911423/en-us

Sadly, however, none of these quite get at the issue I am experiencing. This last link is closest but simply blames the problem on Windows Firewall (which I've disabled to see if it has any effect, it does not).

Update (05/22/2006 11:42AM): It appears that the ActiveSync 4.2 Beta Preview is now available and it comes with a USB troubleshooter. I'm going to try it now. See these two blog posts by Jason Langridge (here and here).

Update (05/24/2006 5:27PM): So far ActiveSync 4.2 has worked perfectly for me--I have not run into the "sit and spin" problem (or any problem) since upgrading.

Update (05/26/2006 1:59PM): Despite upgrading to ActiveSync 4.2 on my laptop, I still have the "sit & spin" problem when connecting to my Windows Mobile 5.0 devices. The horribly ironic thing is that the "USB troubleshooter" promised in ActiveSync 4.2 is actually just a webpage and not, say, a tool. This is so frustrating. I really can't imagine being the only one with this problem as its occurred on my desktop machines (both work, school and home) and laptop with a variety of WM 5.0 devices. I am not running any firewall except the Windows XP built-in firewall (and even when I disable it, ActiveSync still just sits there spinning).

Update (06/02/2006 9:07PM): I got my laptop to work again with ActiveSync. I uinstalled ActiveSync 4.2, restarted, and then reinstalled 4.2. Now things seem to be working for the moment. Incidentally, after this reinstall, I actually got the SmartPhone emulator to cradle via the Device Manager which has never worked for me properly. Note that my work desktop machine, which had a behaving install of ActiveSync 4.2 just stopped working today. However, like with my laptop, a full reinstall of 4.2 seemed to fix the problem.

Update (06/13/2006 10:21AM): Both my advisor and my mentor at work have run into the "sit & spin" problem. The solution of upgrading to 4.2 beta and restarting seems to solve the problem, but only temporarily. My advisor also tried to manually unblock all the ActiveSync ports in Windows Firewall; however, this did not seem to make a difference. As I've noted in the past, I've completely disabled Windows Firewall to try and debug the "sit & spin" problem and it's not made a difference, so his experiences are not surprising.

Update (06/13/2006 11:00AM): I want to reemphasize how I often solve the "sit & spin" problem as strange as it might sound. I have four USB ports on the back of my computer. If I encounter the feared continuously spinning green ActiveSync icon, I unplug my USB cord from the back of the computer and move it to another port while my WM 5.0 device is still connected to the other end. ActiveSync then appears to do some initialization (e.g., my tray shows off another icon that's animated) and then immediately connects properly. This only works for those ports in the back of my computer that have not yet had ActiveSync connections. Once I move the cord to all four ports, I must uninstall ActiveSync and start the process all over.

Update (07/02/2006 1PM): I spent a large amount of my Sunday morning and early afternoon determined once and for all to get to the bottom of the ActiveSync sit & spin problem. My laptop (Dell 710m) has Windows Firewall installed as well as McAfee VirusScan 8 and two USB ports. I tested both USB ports with two different USB cords and three different WM 5.0 devices (the i-Mate K-JAM, the Cingular 2125, and the T-Mobile SDA), all of which would not connect to my laptop, despite all efforts (see the sit & spin problem above). Once the green ActiveSync taskbar icon spins for a certain amount of time, a dialog (new to ActiveSync 4.2) asks me if I'd like to be forwarded to a troubleshooter webpage. If I select OK, I am forwarded to a page entitled "If ActiveSync Cannot Receive Data Through Port 990" (here) . The first three steps are trivial and meant to ensure that you have USB connections enabled both on the desktop and device (and yes I double and triple checked, everything looks fine in this regard). The last point (point 4), states that if I have an internet firewall, make sure its enabled to accept ActiveSync connections. Well, as previously stated, I only run Microsoft's Firewall program and upon examination, they do specifically allow connections from all ActiveSync related .exes. Just to ensure the firewall wasn't my problem, I turned it off but ran into the same problem. Finally, I uninstalled ActiveSync 4.2 and reinstalled it as directed by the USB troubleshooter here (step 9). Unfortunately, though this has worked for me in the past, uninstalling ActiveSync and rebooting my devices and desktop did not solve the problem. So, now I'm stuck. No ActiveSync and no solution. I did find a set of relatively helpful links though for ActiveSync troubleshooting (the fact that there is a community formed around this problem should say something to Microsoft, no?). Here are the links:

1. ActiveSync 4.X Troubleshooting Guide - Connection Flow - provides a very thorough look at ActiveSync issues with respect to establishing a connection (by Chris De Herrera)
2. ActiveySync 4.X Troubleshooting Guide - Firewall, VPN, Proxy Issues (also by Chris De Herrera)
3. Bev Howard's Solving ActiveSync Issues
4. TCP ports required by ActiveSync (I found this the first day I experienced the sit & spin problem, but since tweaking these ports in Windows Firewall never solved anything I never linked to it. I do so for thoroughness now).
5. ActiveSync 4.0/4.1 TroubleShooter Guide
6. The ActiveSync Troubleshooter (which 4.2 dynamically links to when a problem is encountered)

I have not seen an outpouring of complaints on the newsgroups about this problem, though this post is one of the most actively visited on my website so presumably others are encountering it as well. By a rough estimate, I figure the Microsoft ActiveSync development team owes me about 20 hours of my time (perhaps more) based on this problem alone. Others at my research lab have also spent countless hours trying to get their WM 5.0 devices to connect to ActiveSync. Now, as computer scientists we are used to tooling around and debugging programs as well as fault-prone systems. We typically can navigate around these problems. However, if ActiveSync 4.X is broken (and, imo, it is very f*ing broken) it have dramatic implications for the userbase of our WM 5.0 product. If our users can't sync their devices, then they can't (#1) install our application and (#2) use the desktop side of our application.

Update (07/02/2006 8PM): I made a post to the microsoft.public.pocketpc.activesync newsgroup about this problem (here). I also copied the post to my blog here.

Update (07/04/2006 11AM): It appears that my ActiveSync Sit & Spin issue has been resolved and in bit of probably all too common misplaced blame, it was not the fault of Microsoft as I suspected. See here and here.

Wednesday, May 17, 2006

.NET Micro Framework

See Daniel Moth's posting here. Also, the "official" webpage here.

Tuesday, May 16, 2006

Simkin# (or SimkinCS if you will)

Out of a desire to have a scripting language for the .NET Compact Framework, I've recently ported Simkin from Java to C#. Simkin is a "high-level lightweight embeddable scripting language for Java or C++ and XML" originally written by Simon Whiteside. This page has an online demo in Java (warning, might not play nice in all browsers).

Here's a screenshot of SimkinCS running in .NET in a demo app. Click on the picture for a larger view. You can download this proof-of-concept application here.

(left: before execution, right: after execution)

Update (May 17th, 2006 @ 2:02PM): You need the .NET 2.0 runtime environment to run this application. You can download the .NET 2.0 redistributable package here. This is the reason why the application fails to run and returns the error "The application failed to initialize properly (0xc0000135)" on some systems. My guess is, though, if you read this blog you likely have .NET 2.0 installed on your machine.