Sunday, December 30, 2007

Wind of changes and happiness at the end of this year - Welcome Santiago!

I'm very sorry because I know, there were several days without any post on this blog, but I think you'll understand the reasons.

First of all, I have left Q4Tech after almost 8 years of great experiences and lot of friends there. It's just time to go ahead and continue my way. The selected destination was Clarius Consulting where I've already started working as Dev Lead. I've previously worked with Daniel Cazzulino (Kzu) on the development of the Patterns & Practices Mobile Client Software Factory, and some Microsoft Live Labs projects, so this is a familiar place to work for me, and I'm really happy to start this new stage on my professional life with such hi-level team.

But there is another big, huge reason to be happy at this end of 2007, my first son was born on December 24th, What a Christmas present!! The Best one!

Well, he is just 6 days old (or young), and I'm so proud of let you know him, Santiago Gallardo is here:

SantiGallardo

He's the reason because I don't remember what is to sleep 3 hours in a row ;)

Happy New Year for all of you! I'll continue posting about mobility on 2008... see you then!

Tuesday, December 11, 2007

Adaptative UI sample using our multiline MeasureString implementation

I've decided to post a sample application showing how to use the multiline MeasureString code provided on my previous post, to build a dynamic/adaptative UI. It also support screen rotation.

Here you have some screenshots:

image

After changing the text and pressing "Relayout" you can get something like this:

image

And rotating the screen:

image

Finally, this is the source code, enjoy it!

Wednesday, December 5, 2007

Multi-line Graphics.MeasureString implementation on .Net CF

If you have ever tried to build a dynamic UI for a .Net Compact Framework application, probably you've had to build adjustable multi-line labels or text-boxes. It's hard to solve because the only supported overload for Graphics.MeasureString on .Net CF is:

public SizeF MeasureString ( string text, Font font )

When you need to resize or position the controls dynamically in runtime, it's very important to know what should be the size, particularly the height of the multi-line label or multi-line text-box. It's the same problem if you're building a new custom control with a complex layout and you need to measure a potential multi-line string.


Having only this overload on .Net CF, we cannot get a multi-line string size because it calculates just the size of a single-line string. If the string is longer than the string, it gets a big SizeF result but as a single-line text.


Solving the problem


The only solution here is to implement our own multi-line MeasureString method.


To solve the problem, we'll use the native API DrawText. It will calculate the size of the text according with the uFormat parameter and using the graphics (device context) selected font.

[DllImport("coredll.dll")]
static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, int wFormat);

Additionally, if the control if a text-box, we should use the DT_EDITCONTROL flag and add extra 6 pixels (3 pixels at top and 3 pixels at bottom) to the calculated size.


Remember, if you have an empty string, you'll probably need to force one-line size for your controls.


Here's the CFMeasureString sample class source code:

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;

namespace MeasureStringSample
{
public class CFMeasureString
{
private struct Rect
{
public int Left, Top, Right, Bottom;
public Rect(Rectangle r)
{
this.Left = r.Left;
this.Top = r.Top;
this.Bottom = r.Bottom;
this.Right = r.Right;
}
}

[DllImport("coredll.dll")]
static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, int wFormat);
private const int DT_CALCRECT = 0x00000400;
private const int DT_WORDBREAK = 0x00000010;
private const int DT_EDITCONTROL = 0x00002000;

static public Size MeasureString(Graphics gr, string text, Rectangle rect, bool textboxControl)
{
Rect bounds = new Rect(rect);
IntPtr hdc = gr.GetHdc();
int flags = DT_CALCRECT|DT_WORDBREAK;
if (textboxControl) flags |= DT_EDITCONTROL;
DrawText(hdc, text, text.Length, ref bounds, flags);
gr.ReleaseHdc(hdc);
return new Size(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top + (textboxControl? 6 : 0));
}
}
}

And you can use it to resize a label in the following way:

label1.Height = CFMeasureString.MeasureString(CreateGraphics(), label1.Text, label1.ClientRectangle, false).Height;

Now we can start using it and build a dynamic UI on .Net CF.


Update: To support different font sizes, please take a look at this post which shows a good improvement (a.k.a. fix ;)).

Sunday, December 2, 2007

Working with forms in Windows Mobile

As we've already seen, a mobile application UI is naturally modal. Does it mean every form should be open using Form.ShowDialog()?

Of course it doesn't. There are several business requirements (like complex navigation schemas), design and architectural constrains or even basic requirements like the need of implement a wizard that require a different approach. Here's where we need to face new design challenges to provide a rich user experience in our application.

How to show a form in Windows Mobile

It depends on the use case, but you should take care of the form title, the Running Programs window and how it interacts with the multitasking environment.

PocketPC and the Running Programs list

You can show a .Net CF form using Form.Show() or Form.ShowDialog(). In both you'll get in the Running Programs list one instance for each open form, as they were different applications, and you can navigate to any form from that list directly (it will appear disabled if using Form.ShowDialog()).

The first method to prevent this, is every time you show a form, you should change the current form title to an empty string (String.Empty), in the Running Programs List you'll see only the new form title. When you come back, you should change the title (Form.Text property) again to the original title and it will be the one on the Running Programs List. Here you have a sample code:

private void menuItem1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
this.Text = String.Empty;
form.Show();
}
private void Form1_Activated(object sender, EventArgs e)
{
this.Text = "Form1";
}

The second method is using Form.Owner (valid only for .Net CF 2.0+). In this case you should set the Form.Owner property of the new form to the current form, and the title will remain the current form's title. Due to this, we need to change the current title to the new form title and set it back when we come back to the form.

It makes sense if you're using Form.ShowDialog() or if you have a controller form and you're showing kind of a wizard opening different forms and all of them have the same "controller form" as the owner (which is where you start and where you finish the wizard).

Here is the sample code for method 2:

private void menuItem2_Click(object sender, EventArgs e)
{
Form3 form = new Form3();
form.Owner = this;
this.Text = form.Text;
form.Show();
}
private void Form2_Activated(object sender, EventArgs e)
{
this.Text = "Form2";
}

Handling Form_Activate and Form_Deactivate events

Form_Activate is not only useful to set the form title back when the user returns to the form. As we've seen before, Windows Mobile is a multitasking environment and we should deal with it. Here's when Form_Activate and Form_Deactivate are fully helpful.

You can stop unnecessary expensive processes if the application is in background on Form_Deactivate, and start them again when Form_Activate in order to preserve processor, memory and fundamentally battery.

Keep it in mind when you develop more mobile applications.

Tuesday, November 20, 2007

The Modal Nature of Mobile Applications

Probably the most typical design error made on any mobile application development is facing it as a traditional desktop development; especially, regarding the user experience side.

As we can see during almost any mobile development, achieve a good user experience is the hardest goal we have to face. On that way, we should prioritize "simplicity" in our applications.

The simplest user interface you have the best user experience you get. And here, as in most of the mobile development topics, we should get the right balance.

Simplicity for a mobile application UI means:

  • Show less graphic elements as possible, but show all the information required.
  • Show few options but enough to let the user do what he need in the less number of steps possible.

Windows Mobile is a very different environment compared to a desktop platform where you can have a 15" or bigger screen. Due to this constrain, a Windows Mobile application, even each form /dialog on the application, should take ownership of almost all the screen in order to provide the best possible user experience. Actually it's not weird to find full screen applications.

If we need almost all the screen to show any form or dialog, then we can only show one form/dialog at the same time. This is what defines the modal nature of mobile applications. Having a modal approach, a mobile application is closer to get simplicity.

That's the reason because dialogs are full screen by default in any Windows Mobile device. But screen size is not the only constrain on that way, input devices are also constrained and it makes almost inviable a modaless mobile application. Background operations on mobile applications are typically limited to synchronization tasks, and even sync should be performed in foreground very often.

It doesn't mean the user cannot switch between apps. If we don't have explicit business constrains regarding it, multitasking is a good feature and it's not only welcomed, it should be preserved.

Today is highly common to find devices with cellular telephony support. Smartphones and Pocket PC phone edition require the application let the user switch easily to and from phone features.

Multitasking is the reason of having a smart minimize button on the top right corner of Pocket PC forms, or the reason of having a back button on smartphone switching between apps. Home and Phone buttons also allows switching to the device main screen or phone functionality.

On that scenario, our modal mobile application should also be prepared for multitasking, and be prepared for handle the background state preserving processor and battery.

Line of business applications use to have a transactional-approach and high memory consumption. It makes essential in many cases to have an explicit "exit" option. It allows you to verify the complete business operation during the application usage, and free taken resources for other applications.

Next time you design a mobile application, remember: a mobile application should be simple. Being modal it's closer of being simple. But it should also interact with a multitasking environment.

Tuesday, November 13, 2007

Creating a Splash screen for your .Net CF Application

As you already know, performance is a critical issue in any mobile solution. We have to take care of many things, but probably the more important aspect of any mobile development improvement, should be the UI responsiveness.

If the user press a button and wait for 15 seconds with no feedback until the action is finally done, he'll feel the sensation of something going wrong with the application, or probably the need to press the button again. Sometimes a good option is to initialize some load-expensive resources at start-time. The problem here is we already have performance expensive tasks while the application is being launched, and due to adding optimization tries we can found ourselves running an application which takes 20 seconds until the first form is show.

Here's where splash screens help us. It's radically different an application that only shows a wait cursor during 20 seconds until the first form appears than an application which shows the splash screen after 4 seconds letting the user know something is going on, and showing progress during the next 25 seconds even if it's taking more than the original 20 seconds. The key here is feedback, information. The user knows what is going on. He has information, he knows the application is already running, even if it still being loaded.

image

Add a splash screen to your mobile application can looks like a piece of cake, but it's not. There are three important guidelines that you should follow if you want to get the advantages of having a splash screen:

  • It should be shown as soon as possible.
  • Show the splash screen should be a light weight process.
  • It should show progress (or activity at least).

As a .Net CF application usually starts showing a main form, it's recommendable to show the splash screen while the form is being initialized. As we've seen before, it should be a light weight process; ideally it should be as light as possible. A very good option is to create a very simple Splash Form and draw the splash screen directly overriding the OnPaint method. The Splash Form should be maximized (WindowState = Maximized) and totally empty (free of menus or controls).

Then, we can override OnPaintBackground leaving it empty to improve the performance (we don't need to paint a background here anyway), and draw the SplashScreen manually overriding OnPaint:

protected override void OnPaint(PaintEventArgs e)    
{
    Font font = new Font("Arial", 10, FontStyle.Bold);
    if (backgroundBmp == null)
        backgroundBmp = (Bitmap)Properties.Resources.ResourceManager.GetObject("SplashBitmap");
    e.Graphics.DrawImage(backgroundBmp, 0, 0);
    e.Graphics.DrawString("Splash Screen Sample", font, new SolidBrush(Color.Yellow), 37, 30);
    e.Graphics.DrawString("http://www.mobilepractices.com", font, new SolidBrush(Color.White), 7, 50);
    e.Graphics.DrawString("Loading...", font, new SolidBrush(Color.White), 65, 78);

    ShowProgress(0);
}

In this code, we're drawing the full splash screen, but the progress is painted in a different method called "ShowProgress". It will show the progress painting directly on the form graphics:

public void ShowProgress(int percentage)    
{
    Graphics gr = this.CreateGraphics();
    gr.DrawRectangle(new Pen(Color.Black), new Rectangle(32, 95, barwidth, 12));
    gr.FillRectangle(new SolidBrush(Color.Black), new Rectangle(32, 95, (barwidth * percentage) / 100, 12));
}

This method will update the progress quickly while your application is being initialized, without the need of paint the full splash screen for each update.

On the main form constructor on your application ("Form1.cs" in the sample code), you should create and show the splash form for first time, and let the system process the events (Application.DoEvents()) to get the splash visible. This will use OnPaint (and probably this will be the only time OnPaint is called) to draw the splash. From this point we'll use ShowProgress to update the splash showing progress, like in the following sample code (where thread.Sleep is used to simulate some expensive initialization tasks):

public void Initialize(SplashForm splash)    
{
    //Show the splash
    splash.ShowProgress(30);
    //... intialization first steps
    Thread.Sleep(1000);
    //... update splash
    splash.ShowProgress(50);
    //... some intialization steps

...

I'm including a sample application for Windows Mobile 6 Standard Edition (formerly Smartphone). Hope it helps:

Wednesday, November 7, 2007

Building a .cab installer which registers the assemblies in the .Net Compact Framework GAC

Update: I've recently posted a new article about How to create a Smart Device .Cab Installer which is intended for more general purposes than registering assemblies in the GAC. If you're looking for that it can be very helpful. (02/06/2008)

Continuing with the example in the previous post, let's see how we can use Visual Studio 2005 to create a .cab installer which will register the assemblies in the GAC.

The first step is to create a new Smart Device CAB Project:

image

Open the File System Editor (it could be already open) pushing the button on the Solution Explorer toolbar.

image

Create a new "Global Assembly Cache" folder on the file system editor: Right Click on "File System on Target" - "Add Special Folder" - "Global Assembly Cache Folder"

image

Add the assemblies to the "Global Assembly Cache Folder" using the context menu "Add - File" option or just drag & drop them to the folder:

image

Now, you have both files on the GAC Folder. You just need to build the .cab project.

If you take a look at the build result, you'll see the following files:

image

Please pay special attention to the "MyUI.GAC" file. This file is a .gac file with the following content:

%CE2%\MyCustomControls.dll
%CE2%\MyExtendedControls.dll

When the .cab is installed on the device, all the assemblies and the .gac file will be placed on the "\Windows" folder. The next time a .Net CF application is launched, the assemblies will be registered in the GAC.

If you uninstall the .cab from the device (i.e. using the "Remove Programs" option), the .gac file will be removed and the next time a .Net CF app is launched the also assemblies will be removed from the GAC, as we've seen in my previous post. It's just very simple! isn't it?

Monday, November 5, 2007

Working with .gac files

We already know how to get the list of assemblies registered in the .Net Compact Framework GAC, and use the cgacutil.exe tool to register / unregister a specific assembly. Actually we can do it programmatically launching the cgacutil.exe tool from our application. But there is another way to register assemblies in the .Net CF GAC. This way is through .gac files.

Let's say we have two assemblies implementing our custom UI controls:

  • \MyUI\MyCustomControls.dll
  • \MyUI\MyExtendedControls.dll

and we've several apps using them. It makes sense register them in the GAC. We should create a new "MyUI.gac" file in the "\windows" folder with the following content:

\MyUI\MyCustomControls.dll
\MyUI\MyExtendedControls.dll

Remember, both assemblies should be strong-named in order to be registered in the GAC.

When we start a .Net CF application, the cgacutil is executed looking for .gac files in the "\windows" folder and all the assemblies listed on these .gac files are registered.

What if you change the content of your .gac file? Well, the corresponding changes will be made to the GAC: if you delete an assembly from the .gac file it'll be unregistered from the GAC and if you add a new one it'll be registered in the GAC.

If you delete the .gac file, all the assemblies will be removed from the GAC.

How it works

When .Net CF find a new .gac file, it creates a new registry key in the following location:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\3rdParty]

Continuing with our example, it will create the following key:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\3rdParty\MyUI.gac]

containing values for each assembly registered by the .gac file, and a timestamp.

Additionally, it creates references for each assembly in the registry key:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Reference]

Following our example, it will create two registry keys:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Reference\MyCustomControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=F170A8B616315F91]

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Reference\MyExtendedControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=DB19C2BE9EEAE55A]

and a dword value in each key, named "\windows\MyUI.gac".

Some tips

When the .gac is processed, and the assemblies are registered in the GAC, the source files are deleted from the file system. Following our example, both files (MyControls.dll and MyExtendedControls.dll) will be deleted. This is very important for saving space.

Renaming a .gac file can be tricky and it's not a good practice. It's recommendable to delete the old .gac file first and check all the information has been removed from the registry, and then add a new .gac file with the new filename.

Friday, November 2, 2007

Querying the .Net CF GAC programmatically - ListGACTool sample app

If you want to get a list of the assemblies installed on the .Net CF GAC programmatically, you can inspect the device registry accessing the following path:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global]

You'll find there one string value for each assembly registered on the GAC. The name is the assembly full name and the value is the GAC file path.

I'm including here a sample app which you can use to list your GAC in PocketPC. Please pay special attention to the method:

private void updateGacList()
{
gacList.Items.Clear();
RegistryKey gacKey = Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global");
foreach (string valueName in gacKey.GetValueNames())
{
if (valueName.IndexOf(filterTextbox.Text) == 0)
gacList.Items.Add(valueName);
}
}

Here you have a screenshot. As you can see, the app supports assembly name filtering and it's just for learning purposes.

ListGacToolScreenshot

You can download the source code and the binary from the following links:

.Net CF GAC and the "cgacutil.exe" tool

As we've seen in my previous post, we can use the cgacutil tool to detect what .Net CF versions are installed on the device. But cgacutil has a much more important functionallity which is to register and unregister assemblies in the .Net CF GAC.
But, what is the GAC? The GAC (Global Assembly Cache) in the .Net Compact Framework, is a common repository for shared assemblies and its only function is saving storage space on your device.

Actually, in contrast to the full .Net Framework GAC, the .Net CF GAC assemblies are stored in IL (Intermediate Language) and the CLR (Common Language Runtime) needs to compile them each time it loads them. So, the only benefit of having an assembly registered in the GAC is to save space if you have several applications using it, typically a custom framework assembly.

The GAC assemblies are located by default on the "\Windows" folder, with names following this structure:

GAC_<shortname>_v<maj>_<min>_<build>_<rev>_c<culture>_<ref>.dll

where <culture> is neutral for an assembly that doesn't have a culture and <ref> is used to differentiate between multiple versions of the same assembly (i.e. files with different public key token) and is typically 1.

Then you can find the following files in your "\windows" folder:

image

It looks funny, doesn't it? but a simple copy and renaming is not enough. To register an assembly on the GAC, you can use "cgacutil.exe" to do it.

First of all, your assembly must be strong-named - signed with a key-pair if you want to add it to the GAC, please verify that.

Cgacutil.exe is the mobile version of the "gacutil.exe" .Net full framework tool, and we can use it to register an assembly with the following options:

  • /i <assemblyPath>
    Installs an assembly into the global assembly cache.
  • /u <assemblyName>
    Uninstalls an assembly from the global assembly cache.

Let's see an example. If we want to register "mylib.dll" which is located in the "\windows" folder in the GAC, we should execute the following:

cgacutil /i  \windows\mylib.dll

Tip: To open a "Run Window" in PocketPC, you can hold the Action Button pressed while keep taped the clock in the taskbar until a context menu appearas with two options:

image
In the emulator, you can hold the "Ctrl" key instead of the Action Button. Select "Run" and you'll see the "Run Window":

image
enter the command line in the "Open:" field.

Having "mylib.dll" registered, you'll notice a new file in the "\windows" folder named "GAC_mylib_v1_0_0_0_cneutral_1.dll".

Now you can launch your application in the Program Files folder using "mylib.dll" from the GAC without the need of having it in the same folder where your app is placed. Very cool if you have several apps using "mylib.dll" in the same device.

If you want to unregister it, you'll need a little bit more of information, as you don't provide the assembly path, you'll need to provide the assembly version and culture:

cgacutil /u mylib, Version=1.0.0.0, Culture=neutral

And "mylib.dll" is not in the GAC anymore.

I'll talk about how you can access and query the GAC programmatically in my next posts. Stay tuned!

Sunday, October 28, 2007

Detecting what .Net CF version is installed on your device

Are you looking for help detecting what .Net CF version is installed on your device? Do you need to find out if it’s already installed or not? I’ll try to give you some help in both topics.

For the end-user, the easiest way to find the .Net CF version installed on Windows Mobile prior to WM6, is using the “Remove programs” option in the device “Settings” menu. In the list of software installed on your device you can find the .Net CF including the version. If you cannot find the Microsoft .Net Compact Framework there, it’s not installed on your device. Please be careful and do NOT uninstall .Net CF accidentally.
Some devices (i.e. Windows Mobile 6 devices) have .Net CF included on ROM (out of the box). On those devices the previous method cannot help. The best end-user method to detect the .Net CF version on your device is using “cgacutil.exe”. You can find this app using a file explorer in the “\Windows” folder on your device. Running “cgacutil.exe” you’ll see the .Net CF versions installed on your device (i.e. a message showing [3.5.7121.0, 2.0.7045.0] means your device have .Net CF 3.5 Beta 2 and 2.0 SP2). If you cannot find “cgautil.exe” on your device, .Net CF is not installed.

If you’re a developer, probably you’ll need a way to programmatically detect if .Net CF is installed and/or what version is installed on the device. To check if .Net CF is installed, you can use kind of a native code installer, and look on the device registry for the following Key:

[HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework]

You’ll find a dword value for each .Net CF version installed on your device with the version as the name (i.e. two dword values named “3.5.7121.0” and “2.0.7045.0”). The value can be “1” or “0”. A “1” value means the version is installed on ROM and a “0” value means it has been installed manually and can be uninstalled. If you cannot find the registry key or any value in there, the .Net CF is not installed on the device.
Finally, from your .Net CF application you can detect the current version using:

Environment.Version

In a device with several .Net CF versions installed, you can also configure your application to run on a specific version. Take a look at this article to learn a little bit more about it.

What about friendly version names? Here you have a list of .Net CF versions:

  • 1.0.2268.0: 1.0 RTM
  • 1.0.3111.0: 1.0 SP1
  • 1.0.3226.0: 1.0 SP2 (Recalled)
  • 1.0.3227.0: 1.0 SP2 Beta
  • 1.0.3316.0: 1.0 SP2 RTM
  • 1.0.4177.0: 1.0 SP3 Beta
  • 1.0.4292.0: 1.0 SP3 RTM
  • 2.0.4037.0: 2.0 May CTP
  • 2.0.4135.0: 2.0 Beta 1
  • 2.0.4317.0: 2.0 November CTP
  • 2.0.4278.0: 2.0 December CTP
  • 2.0.5056.0: 2.0 Beta 2
  • 2.0.5238.0: 2.0 RTM
  • 2.0.6103.0: 2.0 SP1 Beta
  • 2.0.6129.0: 2.0 SP1 RTM
  • 2.0.7045.0: 2.0 SP2 RTM
  • 3.5.7066.0: 3.5 Beta 1
  • 3.5.7121.0: 3.5 Beta 2

Tuesday, October 23, 2007

Internet Pass-through connectivity problems with ActiveSync and WMDC (Vista) - Error 0x80072f78

A friend called me few days ago asking for help connecting a Windows Mobile 5.0 Palm Treo to the internet via the Vista’s Windows Mobile Device Center (WMDC) pass-through. In this case the Smartphone was connected to the desktop thru Bluetooth, but this is not the first time I have to face this problem. Actually you can find the same problem even in USB connections, and not just using WMDC, also using ActiveSync 4.x.
One of the symptoms of this problem is an error 0x80072f78 trying to browse a site from the device, or just getting an ugly connectivity settings error.
If you’ve tried to solve this problem before looking for help on the web, probably you’ve found kind of a “black magic” solution: a registry tweak adding a new DWORD value named “AllowLSP”. But what is all of this about??
Let’s start from the beginning: LSP = Layered Service Provider. It’s a feature of Microsoft Winsock 2 Service Provider Interface (SPI). It makes possible to modify transport services, i.e. implementing a firewall. You can find more info here.

DTPT (Desktop Pass Through) allows the device to talk with the desktop network (or the internet if the desktop has internet access) while ActiveSync is running. It’s implemented as a socket level proxy technology, including a server side (ActiveSync or WMDC) and a client side implemented as a LSP (the DTPT LSP).

ActiveSync, from its version 4.2 and above, has changed the way it interacts with the Microsoft Windows networking stack to support Layered Service Providers (LSP) on outgoing Desktop-Pass-Through connections. In many corporate environments this provides improved compatibility and policy compliance.
Unfortunately, there are several cases where you can find LSPs interfering with ActiveSync communication. So, we need to enable ActiveSync on the desktop to function together with LSP applications
.

It requires to edit (or create) a DWORD registry key called “AllowLSP” on the desktop, in the following registry path:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services]

The possible decimal values are:

0: Bypass LSPs for incoming and outgoing connections.
1: Bypass LSPs for incoming connection and use LSPs for outgoing connection.
2: Use LSPs for incoming and bypass LPSs outgoing connections.
3: Use LSPs for incoming and outgoing connections.

The value which used to work in this case is “0”, because it bypasses LSPs as previous ActiveSync versions use to do. But if your computer environment relies on LSPs (a very common scenario in corporate networks), probably you’ll need to identify which LSP is causing the conflict and then decide whether you can uninstall the related software package. It’s doable running this command from a command prompt:

netsh winsock show catalog

As result you’ll find a list of each LSP installed on your machine. For sure this information is really cryptic, but it can be helpful in order to determine what you need to remove.
In some scenarios you can use the value of “2”. It allows LSPs for incoming connections but bypasses them for outgoing connections.
It’s highly probable that you need to reset your desktop (or restart activesync killing the “wcescomm.exe” process and launching ActiveSync manually) to reflect the changes.

Additionally, if you have a firewall running, please add the following processes to the application exception list:
  • Wcescomm.exe
  • WcesMgr.exe
  • RAPIMgr.exe
  • CEAPPMGR.exe

If this post cannot help you, probably you can find an answer in this link.

Hope you finally get your device connected to the internet thru ActiveSync!