# Monday, May 16, 2005

SDF v1.3 for Visual Studio 2005

So, I've heard a few requests for VS2005 support for the SDF. The reason we don't have this fully integrated into VS2005 yet is because the extensibility model is significantly changed from VS2003, and since it's a Beta product is still changing. Therefore we'll have a fully integrated installer nearer to the release of VS2005.

In the mean time you can pull the dlls off of a machine with VS2003 and SDF v1.3 installed, or grab them here in a zip file. These are the exact same dlls as you'll get in the v1.3 setup. Just to set your expectations you wont get automatic deployment of the SDF cab files (these are included in the zip for manual deployment). You also won't get the full designer experience - if you use any of our forms controls you'll have to add it through code.

If you encounter any issues using this version from within VS2005, be sure to file a bug report, and make sure you tell us what version of the .NETCF you are targetting (1 or 2) and what platform type (Pocket PC 2003, Windows Mobile 5.0 Smartphone etc) and which version of VS2005, though I wouldn't recommend using anything prior to Beta 2 now it is available.

#    |
# Sunday, May 15, 2005

Windows Mobile Managed APIs Diagram

During his session at MEDC, Robert Levy handed out copies of a cool class library diagram for the new Windows Mobile 5.0 managed APIs, thanks to Robert for allowing me to post the diagram here - simply print to a large sheet of paper and enjoy :)


WM5APIs.gif (242.62 KB)

#    |
# Tuesday, May 10, 2005

Windows Mobile 5.0 Managed APIs

The much anticipated update to Windows Mobile has been announced by Bill Gates this morning. This new platform will be the first platform from Microsoft to include device specific managed APIs in ROM (separate from the .NET Compact Framework itself). These allow access to configuration, telephony, pocket outlook etc from managed code.

But what about existing devices? To add to our existing PocketOutlook library we have produced a WindowsMobile suite which includes a large proportion of WindowsMobile 5.0 APIs for previous versions. More details are available here.

As well as supporting older generations of Windows Mobile, the suite also supports Windows Mobile 5.0, and one library in particular InTheHand.WindowsMobile.Gps provides a managed wrapper around the native GPS API in Windows Mobile 5.0

In due time the PocketOutlook library v1.7 will be released with an object model more closely aligned to Windows Mobile 5.0 APIs.

#    |
# Friday, May 06, 2005

Blog updates during MEDC

MEDC 2005 is nearly upon us. Like many other mobile (and embedded) developers I'm looking forward to this years event which promises to cover the whole range of topics: devices, tools, managed code, native code etc

I'll be acting as roving reporter for Pocket PC Thoughts during the event so I don't expect to be posting updates here. However I hope you will join us over at Pocket PC Thoughts to catch up on what is happening during MEDC.

#    |
# Monday, May 02, 2005

Emulate Screen Taps

You can simulate user activity on your touch-screen device by using the mouse_event API to send the system screen taps. There are a number of reasons you might want to do this from testing your application through to automating some third-party application, the following is example code to send a tap (and release) to any screen co-ordinate:-

[DllImport("coredll")]
private static extern void mouse_event(MOUSEEVENTF dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

[Flags()]
private enum MOUSEEVENTF
{
MOVE = 0x1, /* mouse move */
LEFTDOWN = 0x2, /* left button down */
LEFTUP = 0x4, /*left button up */
RIGHTDOWN = 0x8, /*right button down */
RIGHTUP = 0x10, /*right button up */
MIDDLEDOWN = 0x20, /*middle button down */
MIDDLEUP = 0x40, /* middle button up */
WHEEL = 0x800, /*wheel button rolled */
VIRTUALDESK = 0x4000, /* map to entrire virtual desktop */
ABSOLUTE = 0x8000, /* absolute move */
TOUCH = 0x100000, /* absolute move */
}

public void SendTap(int x, int y)
{
mouse_event(MOUSEEVENTF.LEFTDOWN | MOUSEEVENTF.ABSOLUTE, (int)((65535 / Screen.PrimaryScreen.Bounds.Width) * x), (int)((65535 / Screen.PrimaryScreen.Bounds.Height) * y), 0, 0);
mouse_event(MOUSEEVENTF.LEFTUP, 0, 0, 0, 0);
}

 

The mouse_event method is fairly straight-forward, one thing to notice is that it doesn't accept screen co-ordinates but rather a value from 0 to FFFF in each direction, where FFFF, FFFF is the bottom right corner.


#    |
# Tuesday, April 26, 2005

MEDC 2005 UK Registration now open

Following the main MEDC 2005 which I'm sure you've all heard about, there are a number of smaller events happening worldwide to bring the highlights to the wider audience. One of these is happening in the UK at Microsoft's campus in Reading on Friday the 10th of June. You can now register for the event, which is free but places are limited.

More details on Marcus Perryman's Blog, and the MEDC 2005 UK site.

#    |
# Monday, April 18, 2005

.NETCF v2.0 Beta 2 Redistribuable Package

I'm sure I don't need to mention that Microsoft recently released Beta 2 of their Visual Studio 2005 tools. Alongside this release a redistributable version of the .NETCF v2.0 runtime is available so that you can download to your devices and test code you can download the package here.

Ilya Tumanov posted some useful information on the release on the newsgroup:-

"Visual Studio 2005 download is not required; installation of NETCF V2 Beta
2 won't break existing VS 2003 and/or NETCF V1.
It also works side by side with CF V1 on device (in ROM or RAM).

If you're planning to install VS 2005 Beta 2 later on, you would have to
uninstall NETCF V2 prior to VS installation.

We would appreciate if you try your CF V1 application(s) under V2 and
report incompatibilities so we could fix them.

Here's how to run existing V1 applications under V2:

1. Install V2 on to the device (via Active Sync or copy CAB file to the
device and click on it).
2. Create a configuration file named <App_Name>.exe.config as follows:

<configuration>
<startup>
<supportedRuntime version="v2.0.5056"/>
</startup>
</configuration>

To try application without V1 compatibility enabled, the following section
can be added:

<runtime>
  <compatibilityversion major="2" minor="0"/>
  </runtime>

To run V2 application in V1 compatibility mode (for example if V2 app uses
V1 component), section can be changed as follows:

<runtime>
  <compatibilityversion major="1" minor="0"/>
  </runtime>

3. Copy configuration file to the application folder.
4. Run application as usual.

Please report problems with installation and/or compatibility to this NG.
For CAB problems, please attach CAB log file "Microsoft .NET CF
2.0.LOG.TXT" which can be found in device's root folder. Thanks."

Even if you are not currently evaluating the Visual Studio 2005 tools, I would recommend downloading these runtimes and testing your existing code - there are a number of cases where behaviour has changed in v2.0 but as you can see above you can run an app with v1.0 compiled code in compatibility mode.

#    |
# Friday, April 15, 2005

The great Media Player 10 Automation Challenge!

Media Player 10 is the first device version to have an automation model. Previous versions could be controlled via some undocumented windows messages but that was about it. The Media Player 10 Mobile object model is COM based, so you can't use it directly from .NETCF v1.0. I set about creating a wrapper months ago but it got left due to lack of time. However I've decided there is enough functionality available in it now for it to function. I've not had time to create a sample application, so your challenge if you choose to accept it (and I'll be honest there isn't a prize!) is to create something using the assembly.

Because theres no support for hooking com events with a sink interface the wrapper exposes no events, also because there isn't ActiveX hosting support you won't get any UI - so this is useful for audio content only. The other big limitation is that you must have Media Player 10 on your device.

Other than that feel free to have a play and see what fun you can have with it, any issues suggestions or cool creations you build with it please drop me an email or post a comment.

Download InTheHand.MediaPlayer.zip

#    |
# Monday, April 04, 2005

Time to turn out the lights...

Time to provide a little balance to the previous piece on SetPowerRequirement for Smartphone which looked at the scenario of ensuring the backlight remained on. You might also want to manually turn off the backlight (or another peripherial) to save power. You can do this with SetDevicePower. You pass in the identifier of the hardware device ("BKL1:" being the backlight on most devices), and a power state - thus the backlight can be powered off with the following:-

SetDevicePower("BKL1:", POWER_NAME, DevicePowerState.D4);

POWER_NAME is passed in to the flags argument to indicate that the first argument represents a device name. The Power states run from D0 full power to D4 power off. And without further ado, the P/Invoke:- 

public enum DevicePowerState : int
{
Unspecified = -1,
D0 = 0, // Full On: full power, full functionality
D1, // Low Power On: fully functional at low power/performance
D2, // Standby: partially powered with automatic wake
D3, // Sleep: partially powered with device initiated wake
D4, // Off: unpowered
}

private const int POWER_NAME = 0x00000001;

[DllImport("coredll")]
private static extern int SetDevicePower(
string pvDevice,
int dwDeviceFlags,
DevicePowerState DeviceState);

#    |
# Tuesday, March 22, 2005

SPB Clone Review

I've briefly mentioned SPB Clone here before as a method of deploying software across the enterprise. Fellow MVP Darryl Burling has completed a review of the product over at GeekZone which I recommend you read if you are facing the problem of deploying the same software across a large number of devices.

http://www.geekzone.co.nz/content.asp?contentid=4252

#    |
# Saturday, March 12, 2005

Bluetooth Library (March Edition)

To facilitate using the library in Visual Studio 2005 Betas I have made a few minor updates to the managed Bluetooth library, new/fixed in this release:-

  • Now works under .NETCF 1.0, .NETCF 2.0, .NET 1.1 .NET 2.0 (Not tested under the .NET 1.0 desktop framework but should work).
  • On Windows CE remote name lookups are performed "on-demand" rather than during device discovery to reduce discovery time.
  • Reintroduced the BluetoothSocket helper class which provides a shortcut to create a Socket for working with Bluetooth independently of the existing BluetoothClient / BluetoothListener classes.
  • Removed OpenNETCF.dll dependency, cures deployment problems on desktop machines.

Download the latest version here:-

Downloads

 

#    |
# Friday, March 04, 2005

Control and Component Designers Part Four - Events

This is a quick addendum to part three. In that section we looked at un-hiding some properties in the standard controls which were implemented in .NETCF SP2. As well as adding Fore and Back colour support, SP2 introduced support for a few more events which were declared in the original classes but never fired. Specifically these include the keyboard events KeyDown, KeyUp and KeyPress. Just like the colour properties these can be added to our design time assembly so that we can hook these events from the designer.

[Browsable(true),
Category("Key"),
Description("Occurs when a key is first pressed.")]
public new event KeyEventHandler KeyDown;

[Browsable(true),
Category("Key"),
Description("Occurs after a user is finished pressing a key.")]
public new event KeyPressEventHandler KeyPress;

[Browsable(true),
Category("Key"),
Description("Occurs when a key is released.")]
public new event KeyEventHandler KeyUp;

We declare the events "new" so that they will replace the base class implementation, but as this is design time only, the code generated hooks the events that already exist in the Control class. The category and description attributes improve the grouping in the property pane.

The last event item to cover is the DefaultEventAttribute which can be applied to a class. In our PictureBoxEx class we inherit from the standard PictureBox (Thanks to Sergey Bogdanov for submitting the code). Because I have now added a Click event to the designer (In SP2 the PictureBox supports the Click event) we can make this the default event for the class, so that when you double click on the control in the designer it will automatically rig up a handler for you and drop you into the appropriate place in the code. This makes a little more sense that the PictureBox for which the default event is ParentChanged.

#if DESIGN
    [DefaultEvent("Click")]
    public class PictureBoxEx : System.Windows.Forms.PictureBox
#else    
    public class PictureBoxEx : System.Windows.Forms.PictureBox, OpenNETCF.Windows.Forms.IWin32Window
#endif

Part 1 | Part 2 | Part 3 | Part 4

#    |

Building the Latest SDF v1.3 Source

We get a lot of requests asking for the very latest code for the SDF since tons of exciting stuff has been added (and many issues resolved) since our v1.2 release last year specifically from users starting to work with the VS2005 betas and community previews and would like to use the SDF with these new tools. Firstly just a reminder that the SourceBrowser no longer contains a current record of the source code, which is now maintained in the Vault (Username: guest, Password: guest). From the vault you can see all the latest source files as they are checked in.

If you need a build which you can use with VS2005 Beta you can download from:-

http://www.peterfoot.net/files/OpenNETCF.SDF.1.3.50302.zip

And now the big disclaimer on this build, it's not a final v1.3 release, it's not signed with a key pair and so cannot be installed in the GAC on devices, there is no installer, no help content. This should not be used for release purposes (just like VS2005 itself of course) and we offer no support for this build.

Update: v1.3 is now released, see this post for instructions for using the v1.3 release version in VS2005.

Please remember if you have any product requests, bug reports etc whether you are using the current tools or VS2005 please post them to our new bug submission page, we are grateful for any feedback to help us make v1.3 our best release yet.

#    |
# Wednesday, March 02, 2005

Control and Component Designers Part Three - Extending Existing Controls

Using these techniques it’s possible to extend existing controls and add attributes to improve their designer experience. To illustrate this I’ve taken the example of the ComboBoxEx control. This extends the ComboBox control by overriding runtime behaviour to overcome a data binding issue, and adds BeginUpdate and EndUpdate methods to improve performance when filling the list of items.

The designer experience for the control inherits the behaviour of the ComboBox control. Since the ComboBox’s own designer excludes some designer support which the control now implements as of Service Pack 2 such as Fore and Back Colors we can add these to our designer and have the designer insert the code to set the colour. The following block of code implements these properties in the design version of the control:-

#if DESIGN


[Browsable(true),

EditorBrowsable(EditorBrowsableState.Always),

DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

public new System.Drawing.Color ForeColor

{

get

{

return base.ForeColor;

}

set

{

base.ForeColor = value;

}

}


[Browsable(true),

DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

public new System.Drawing.Color BackColor

{

get

{

return base.BackColor;

}

set

{

base.BackColor = value;

}

}

#endif

Once built we have a combobox with color support, and because the forms designer in Visual Studio uses a standard ComboBox for drawing it already supports drawing itself with the specified colour.

 

Part 1 | Part 2 | Part 3 | Part 4

#    |

Control and Component Designers Part Two - Hanging the Decorations

How the designer interprets your components is from a mixture of reflection to actually see what properties you expose, but also attributes which allow you to override this behaviour.

The first attributes which are required for any component to appear in the toolbox are:-

#if DESIGN

[ToolboxItemFilter("NETCF",ToolboxItemFilterType.Require),

ToolboxItemFilter("System.CF.Windows.Forms", ToolboxItemFilterType.Custom)]

#endif


This ensures that the component only appears on the device controls toolbar and not within a desktop project. We wrap this in an if DESIGN block so that the attribute is not added to the runtime control (because the CF assemblies don’t include this attribute). The ToolboxItemFilterAttribute can be found in the System.ComponentModel namespace.

If you build the libraries now you should be able to add these components to your toolbox. Open a new device project and open a form in the designer, right click the toolbox and select “Add/Remove Items…” then browse to the output of your project e.g. \bin\Designer once you have added the file and closed the dialog you should have some new entries in your toolbox:-

In order for the properties pane to work correctly we need to do some further decorating. For most properties you’ll be dealing with fundamental types which visual studio can display automatically. It is a good practise to specify the default values for these fields, in this way if you set the properties to the default it won’t generate code to assign to the property, also the property pane displays non-default values in bold so you can quickly see which have been set to a specific value. The DefaultValueAttribute accepts an object, for example in the case of the ProcessStartInfo the FileName default is an empty string

#if DESIGN
        [DefaultValue(""), RecommendedAsConfigurable(true)]
#endif
        public string FileName

Some properties will have no meaning at design time such as the Handle property of the Process, using the BrowsableAttribute with a value of false will hide the property

#if DESIGN

[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

#endif

public IntPtr Handle

The DesignerSerializationVisibility attribute ensures that this property is excluded from the data serialized to describe your component.

If you have a property which is of type Object then the designer will have no idea what is valid to assign to this and it will appear greyed out. Some of our components and controls now include a Tag property which allows you to tag an object of any type which may contain supporting data. On the desktop this is exposed as a string, so we do the same in our designer support. At runtime you can still assign any object to this property. We also apply the BindableAttribute which tells the designer that this property may be used in data binding.

#if DESIGN

[Bindable(true), DefaultValue((string) null), TypeConverter(typeof(StringConverter))]

#endif

public object Tag

 

Some properties will use other classes which themselves contain multiple properties. A good example is the ProcessStartInfo which is used with the Process class. In order to allow the designer to display this correctly as a nested object we apply the TypeConverterAttribute and give it a value of ExpandableObjectConverter, this allows the designer to populate the property pane with the various properties contained within it.

#if DESIGN

[TypeConverter(typeof(ExpandableObjectConverter))]

#endif

public sealed class ProcessStartInfo

We apply the same selection of properties to define the default values for the properties within this class. Now the property pane takes on a logical nested appearance and we can setup all of these properties at design time:-

To ensure these properties are written out in our code by the designer we need to add the DesignerSerializationVisibilityAttribute:-

#if DESIGN

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

#endif

public ProcessStartInfo StartInfo

Optionally you can specify categories and descriptions for properties and events. Depending on the user’s preferences the property pane may be shown by category or alphabetically. By default properties are added to the “Misc” category. The grey box below the actual property list will show a short description as defined by the DescriptionAttribute as used here in the BackgroundWorker class.

#if DESIGN

[Category("Asynchronous"),

Description("Event handler to run on a different thread when the operation begins.")]

#endif

public event DoWorkEventHandler DoWork;

Part 1 | Part 2 | Part 3 | Part 4

#    |

Control and Component Designers Part One - Building for Design Time

Introduction

When developing desktop .NET forms projects the toolbox contains a number of components you can drag across to your form and setup via the designer. A component in this case is any class which inherits from System.ComponentModel.Component. Visual Studio generates the appropriate code for you, in just the same way as forms controls except your components sit in a tray below your form.

Over the past few versions of the SDF we have steadily built up a number of components which directly match those available on the desktop, so I decided it would be great to offer exactly the same designer experience.

There are two key points to design time controls, firstly they are compiled against the full .NET framework (since that is what Visual Studio’s form designer uses), secondly they include a number of special attributes to setup the correct behaviour of the component and the properties window.

Setting Up the Build Process

There are two ways to build your designer assembly, either via the command line usually by building a batch file to call the C# compiler with your code files (That’s correct no VB.NET design time controls at this stage) this article was probably the first to describe this process and is still just as relevant today. The other way is to create a desktop Class Library project type and insert your existing code files.

This is the approach I took this time as I’ve used command line build before and fancied a change. I started with a Solution which contains all the affected SDF assemblies – OpenNETCF, OpenNETCF.Drawing, OpenNETCF.Windows.Forms and OpenNETCF.WindowsCE.Forms. OpenNETCF.Drawing exposes no designable types but is used by the two forms assemblies. Within this solution file I created 5 new desktop Class Library projects – OpenNETCF.CF, OpenNETCF.CF.Drawing, OpenNETCF.CF.Windows.Forms and OpenNETCF.CF.WindowsCE.Forms, I then removed these new projects from the solution and moved the project files (.csproj) into the respective folder with their device equivalent (note that device projects have the .csdproj extension). I then opened each of the runtime projects in a text editor and copied all the entries into the design time projects. Finally back in Visual Studio I add these new desktop projects into the same solution. Next in order to allow both sets of files to build side-by-side I create a new configuration for the project called “Designer”. Then in my default “Debug” configuration for the entire solution I set the design time projects (OpenNETCF.CF.*) to use the Designer configuration and all the runtime projects to use the Debug configuration.

Next I go into the project properties for each of the design time libraries and set the output folder to \bin\Designer\ and set a conditional compilation constant for “DESIGN”. We have already used this constant for previous versions when adding designer support to the controls so this already makes much of the libraries “designer safe”.

These OpenNETCF libraries include dependencies to each other so OpenNETCF.CF.Drawing requires a reference to OpenNETCF.CF, OpenNETCF.CF.Windows.Forms requires a reference to both these and so on. These references are easily added with the Add Reference dialog and switching to the Projects pane. Next each of the design time projects needs a couple of standard references to the .NETCF designer assemblies:-

  • System.CF.Design
  • System.CF.Drawing
  • System.CF.Windows.Forms

Additionally a reference to Microsoft.CF.WindowsCE.Forms was required in OpenNETCF.CF.WindowsCE.Forms since InputPanelEx derives from InputPanel. All of these designer assemblies is found within the Visual Studio installation e.g.

C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\Designer

The advantage of going through all these hoops is that both the design time and runtime projects point to exactly the same source code and you can build both assemblies from within your visual studio solution.

 

Designer Support

For each component or control which is exposed to the toolbox an image is required. This should be a 16x16 bitmap with the name of the control including full namespace e.g.

OpenNETCF.Diagnostics.Process.bmp

This is added to the design time project as an Embedded Resource in the root of the project (otherwise folder names are added to the resource name). We could try building the solution now, and will probably come across errors.

A quick way to simplify the process is to remove any code files which are not required by any of your designable components, alternatively you could exclude entire files or code blocks from the design time build process by encapsulating them in if blocks using the compilation constant we setup e.g.

#if !DESIGN

public class NativeStuffWeDontNeedAtDesignTime

{

}

#endif

Concentrating on our components you can actually be quite ruthless with this conditional compilation as long as you expose the public properties which will be displayed in the properties window in the designer. Once you have successfully built the whole solution you’ll have a full set of runtime and design time assemblies, however they are not ready just yet as with all new builds they need decorating before we can move in…

Part 1 | Part 2 | Part 3 | Part 4

#    |