Win32Api

Mon, January 31, 2005, 04:01 PM under MobileAndEmbedded
Every .NET developer is familiar with platform invocation services (PInvoke), the ability to call native functions declared in dlls via the DllImport attribute. In the early .NET days it was common to see queries about specific API declarations, but 4 years down the road you would have thought people would stop asking and instead use the ready-made ones easily found all over the web. This blog entry is proof of the opposite and it will serve as my pointer next time someone requests a particular Win32 DllImport declaration.

First place to go is the pinvoke wiki (tip: check out the Helpful tools). This was started by Adam Nathan (author of the only COM Interop book you need, which covers interoperability in general and not just COM).

From a Compact Framework perspective, the first place to go is the OpenNETCF source. Search it for the API name you are after and steal the C# DllImport declaration :-)

In addition to the above, since I often refer to a Win32Api class in both newsgroup and blog posts, I include here a link to my own Win32Api.vb (as the extension suggests, it is in VB.NET so the C#-challenged amongst you may prefer it)

Win32Api is a class with the dllimports that I use in my projects (exposed as Shared methods). It started life years ago when I was doing desktop development and was subsequently morphed to support both compact and Full frameworks (hint: look for the FULL_FRAME compilation constant). I don't claim to have crafted every declaration myself, quite the opposite, half of them are probably lifted from ready made declarations found on the web :-)

Blog link of the week 04

Sun, January 30, 2005, 03:50 PM under Links
- "You should log unhandled exceptions, not just swallow them!" I have met many that refuse to adopt my advice (usually the type that love On Error Resume Next). If I can't convince you of the opposite, maybe this blog entry will.

- Some obvious, some not so obvious; overall a great post that brings together in one place the wisdom of when to go async and related advice

- Some humour on Unit testing :-D
(if you are a sensitive TDD advocate, keep your knickers on please, it is only a joke!)

PB SDK for VS

Fri, January 28, 2005, 12:58 PM under MobileAndEmbedded
For those that write Compact Framework applications for custom CE devices, the VS emulators are not as useful as they are for PPC development.

We always advise people to get an SDK from the device manufacturer – or even better an actual device to test against. I have been lucky to be playing with a real device from day 1, never having to use the emulator for real development. If you are trying to generate an SDK from Platform Builder, you may find that it is not easy to get it right first time, and more often than not you end up with a black-screen emulator that VS.NET 2003 cannot connect to. The fun bit is where the emulator works OK in eVC, and then when you try to use it in VS, not only it doesn't work but it actually hoses the emulator in such a way that it stops working in eVC, but I digress.

So I thought it useful to include here the *exact* steps that work for us when building (and exporting) an SDK for use in both VS and eVC. Enjoy :-)

1. Make a new platform based on Emulator BSP
2. Configure the image as you require (make sure the image includes .NET Compact Framework, toolhelp.dll and Smart Device Authentication Utility)
3. Make sure that KITL support is disabled in the image (i.e. when you select Platform -> Settings -> Build Options, the only thing that should be checked is "Enable EBOOT Space in Memory")
4. Build the Emulator image
5. Configure the SDK
On the emulation tab - this is up to you e.g. memory size = 64MB and screen size = 320x240, 8 bit
On the transports tab - Make sure Microsoft KITL Transport is *not* checked, set ActiveSync as the default
On the Development Languages Tab - Select everything (so the same SDK will work in eVC++ and VS.NET)
On the Startup Servers tab - Make sure they're all selected and that ActiveSync is the default.
6. Build the SDK

Default Font ignored

Thu, January 27, 2005, 01:01 PM under MobileAndEmbedded
In a Sentence (or five)
When NETCF controls are created they have a default Font. You would expect the default Font to be picked from the platform (operating system) default Font. However, that is not the case and instead they start of with Tahoma. This cannot be defended as a design choice so it must be a bug! Vote for it to be fixed (the bug is present in CF 1.0 and CF 2.0).

Repro Steps
1. Create a new form
2. Add a button to it (or any other control including custom ones)
3. In the button event handler put the following code:
MessageBox.Show(this.Font.Name,Button1.Font.Name); //C#
MessageBox.Show(Me.Font.Name,Button1.Font.Name) ' VB
4. You see Tahoma, Tahoma (assuming your system default is Tahoma)

5. Change the system's default Font to Arial or Courier New (or some other Font on your unit)
HKLM\System\GDI\SysFnt\Nm
HKLM\System\GWE\Menu\BarFnt\Nm
HKLM\System\GWE\Menu\popFnt\Nm

6. Reset the unit and run the test again
7. You see Arial, Tahoma (they should both be Arial - or whatever the system default is)

Why Fix the Bug
1. 99.99% of controls never have their Font changed by the developer; in fact the only times we change font is for size or style, not name. Hence we expect the Font to be the system default.
2. If we run an app like that on a unit where the default font has changed, it will not pick it up.
3. eVC defaults to system Font so there is no precedence of hardcoding default fonts
4. As the repro steps show, there is inconsistency within the implementation itself. The title bar caption/text the default font whereas the other controls use the hardcoded Tahoma
5. Further inconsistency is that the menu fonts are picked up properly. Even the built-in error handler dialog picks up the correct Font.
6. Changing the Font of every control in Smart Device projects is more cumbersome than the desktop since changing the Font of a container (e.g. Form, Panel) does not propagate to the children controls (no Ambient properties on CF)

How I came across it
Due to other reasons, we have to change the default font of our platform to Arial. Half the screens look odd and I now have to go and explicitly change the Font for all controls. Yes I know "poor me" but that is not the point. Next time we decide to change the default Font I will have to change the hardcoded values since the NETCF controls are not smart enough to pick the default.

How small?!

Wed, January 26, 2005, 03:26 PM under MobileAndEmbedded
Most people associate Compact Framework target devices with Pocket PCs only. This is very convenient for the developer in many ways, e.g. a screen resolution of 240x320 and the presence of a stylus are presumed in most cases.

Imagine you are targeting a device with a very small display (e.g. 105x32mm, 240x64pixels). Naturally, you need to maximise the amount of elements you can fit on a screen, to make it useful. If you take the imaginary scenario further and say that the display is *not* touchscreen (instead hardware buttons provide the only way to drive the UI), then it becomes even more obvious that the GUI controls should be as small as possible (just large enough to read and as small as you can get away with).

Imaginary scenarios interest me, so I thought I'd see how the CF (and by extension WinCE) caters for such an eventuality. The focus is on the Height of controls (Width is not only pretty much adjustable, but also not the dominant limiting factor).

Naturally the following controls are irrelevant: Panel, PictureBox and Timer.

The following controls can be resized (and where applicable their Font is changeable to accommodate the size reduction):
Button, Label, TextBox, ListBox, ProgressBar, TabControl, TrackBar, Datagrid, TreeView, ListView, HScrollBar and VScrollBar

The Toolbar does not have a Size property, but its height is controlled by the size of the images associated with it (on custom WinCE devices, not PPC!). So by adding 8x8 icons to the ImageList associated with the toolbar (or by just changing the ImageSize property), the toolbar will be high enough to fit those images - nice. Like the Toolbar, the TreeView and ListView also play nice with the image size (if there is an ImageList associated with them, otherwise like I said in the previous paragraph, the Size/Font properties also work).

Once the size and Font of controls such as ListView, ListBox and TreeView is decreased, it sticks out like a sore thumb that their scrollbars are too thick. Not a big problem, though, as this can be controlled by the following registry settings:
HKLM\System\GWE , DWORD values "cxHScr", "cyHScr", "cxVScr", "cyVScr"

Menus (MainMenu, ContextMenu and MenuItem) are resized according to their Font. However, they do not expose a Font property, so you are stuck with whatever the default Font is for the platform. You can change that through the registry:
HKLM\Menu\BarFnt , DWORD "Ht" for height , DWORD "Wt" for boldness: 700 or 400
HKLM\Menu\PopFnt same as above, but this applies to menu items rather than the menu bar

The following controls are problematic:
-DomainUpDown and NumericUpDown can have their height changed but, before you get too excited, their Font is *not* changeable and in fact attempting to assign a Font results in a NotSupportedException at runtime! Net result: these controls have, effectively, a fixed minimum height (The CF 2.0 story is the same, except now the Font property is not exposed at all).
-ComboBox and StatusBar have the reverse problem: You can change their Font but not their Height - it compiles but no runtime change is observed (The CF 2.0 story is the same, except now the Height property is not exposed at all).
-CheckBox and RadioButton shrink, but the square box and circle respectively are of fixed size!
-We saw that menus can be shrunk based on Font size, but the Menu bar *height* is not configurable.

Showing off some of the above is this screen capture

VOTE for the WinCE/NETCF teams to improve in this area.

We already saw registry settings for scrollbars and menu font, here is one more that helps (reset is required before any effect takes place for all these):
HKLM\System\GWE , DWORD "cyCap" changes the height of a windows caption/title bar. Note that, if the Font is not changed accordingly, the text will not be rendered.

For more registry entries see here. I have played with all of them on our platform and found that they are more geared for large displays rather than smaller ones. In other words, the defaults are already targetting small displays, so if you want to go smaller there isn't much there :-(

Desktop to PPC (Part B)

Tue, January 25, 2005, 03:17 PM under MobileAndEmbedded
Continuing from part A (if you haven't read it, we'll wait for you...go on then :-)

5. Take over the device
Popular desire amongst devs is to take over the device. Their app is so important that nothing else should be accessible. This is not as bad as it may sound, as in some cases the application really is the raison d'etre of the device. Every solution described seems to create more issues, so there doesn't seem to be a clean one-rule-fits-all. If you have this requirement, here are some links for you to pursue [1, 2, 3, 4, 5, 6] (in other words search for "full screen" and "kiosk")

6. File System
The storage system on PPCs is similar to the desktop, with only a couple of differences. There is no C:\ drive; everything starts at the root, so an example path is this: "\Program Files\Some Folder\MyApp.exe". More importantly, there is no concept of current directory, the implication of which is that you must always use absolute paths (like the example above). To get the directory of your NETCF app, see this. Note that the OpenFileDialog will only let you browse the "My documents" directory, so if you need to go to other places you have to create your own.

7. Memory Constraint
An obvious difference with PPC devices is the limited memory that is available. When the device runs into low memory situations, it will start closing open windows (this is not minimising, it is real closing). If you get in such a scenario, some people advise to try hooking into the WM_HIBERNATE/WM_CLOSE windows msg; I advise you to revisit your architecture and not consume so much memory in the first place. Measure and set the expected memory your app requires to run smoothly, and if it doesn't get that on a device, it simply means the environment does not meet your criteria. You should, of course, be cleaning up resources in the Form.Closing events in any case. For more on memory problems see Memory Problems FAQ

8. Deployment
Deployment is quite different on devices than to the PC and all links you need on this topic are already provided here

9. Question: "How do I take advantage of my existing desktop .NET code?"
Answer: Share the code

If you are using the NETCF for targetting a device other than PPC (like me), you cannot make any of the above statements without knowing the specifics of the device (all custom CE-based devices are different). In this MSDN article, you can see some of the differences between PPC projects and WinCE projects in VS.NET 2003. I may do an entry on the topic too, at some point in the future.

MSN Messenger

Tue, January 25, 2005, 02:59 AM under Random
I haven't gone off topic in a while and today this pushed me to do so. The moral of Ian's story (although he doesn't state it like that) is do not change your main email account in Passport if you are using messenger. Reason I found the post interesting is because I was considering doing exactly that and now I am put off for good. Maybe it will be fixed in Messenger 7.0

You are using the BETA of 7.0, right? If you are not here are two reasons to do so (apart from the fact that it has been very stable for me in the past week):
1. Ability to sign in invisible
2. In addition to typing messages you can also handwrite them

Desktop to PPC (Part A)

Mon, January 24, 2005, 03:16 PM under MobileAndEmbedded
With the Compact Framework making programming for devices so easy, there is an increasing number of desktop developers making the move to CF development (or at least getting their feet wet). They face the challenges of a .NET Framework that is missing whole areas (e.g. Remoting, COM Interop, ASP.NET) and has every interface trimmed down (e.g. the Thread has only 2 public instance members) - it is not called the *Compact* Framework for nothing. Many of my blog entries focus on exactly that: the differences between the full and compact frameworks and sometimes how to bridge the gap.

However, another difference is the actual operating system or platform. This bites the developer even more if they are not daily users of a Pocket PC (which is the target of 95% of the NETCF developers). The situation described has as a consequence a lot of questions in the CF newsgroup, so I will try to address some of these in this entry and point to it in the future (as an FAQ).

1. Input methods
PPCs do not have a mouse or a keyboard (for the few devices that have, keyboard events are supported by some NETCF controls since Service Pack 2). The lack of a mouse is catered by a touch screen and the use of a stylus (mouse events are not supported in most controls and you may need to create your own control; help for custom controls is here, here and here). Right-click context menus are simulated by tap-and-hold (made possible by the aygshell.dll that is part of the PPC platform). There is a Soft Input Panel (SIP), which is a software keyboard that can pop up on the screen. To interact with it, you must reference Microsoft.WindowsCE.Forms.dll and drag the InputPanel control onto your form. To show it, you call InputPanel1.Enabled = true, typically in the GotFocus event of a TextBox (and set it to false in the LostFocus). To detect when it is up or down, you can track the InputPanel.EnabledChanged event. Note that hand-in-hand with the InputPanel is the MainMenu control that your form must have - even if it doesn't use it (!)

2. Form/Dialog size
Forms and dialogs on the PPC are always full screen (the only exception to that rule is the built-in MessageBox). There are known workarounds, but it seems that they hurt more than they help, so my advice is to stick with full screen dialogs and design for that approach from day 1. Try to design the UI so the user never gets the impression they are interacting with more than one screen; use multiple hidden panels on one form and swap them in/out as appropriate.

3. App/Form closing
The design guidelines for the PPC are clear: Applications do not exit/close, instead they minimise. This aids in the concept of a device that is always on (and the apps are always available, without waiting for them to load each time). For NETCF apps, setting the Form1.MinimizeBox to true will display the X button in the top right, whereas MinimizeBox=false will instead show a little OK button in the top right. Clicking an X minimizes the form, whereas clicking an OK closes the form and by extension the application if the form is the application's main form. Note that minimising is not identical to the desktop, i.e. all that happens to the window is that it is pushed to the back of the stack of open windows on the PPC. To programmatically know when a smart minimize occurs, you should hook into the Form1.Deactivate event (which is supported even though designer support is missing).

4. Moving between applications
Following from points 2 & 3 above, you might wonder how you switch between applications. There are various ways: By closing (minimising really) windows, you can reach the desired one OR you can use the top-right Start menu (Windows icon) OR open the Start->Settings->System->Memory->Running Programs screen. The "Running Programs List" displays all the open windows (minimised or not) and allows you to switch between them. This presents a problem in a scenario where your app has Form_A opening Form_B and you only expect the user to get back to Form_A after closing Form_B; they can also go to Form_A by using the "Running Programs List"! The workaround is to only show in the list the active form and to do that you must set the caption (Form1.Text) of other forms to String.Empty (""). By the way, if you are having trouble bringing your application to the front programmatically, read that.

In my opinion, these are the top 4 gotchas for desktop devs moving to the PPC platform. Look forward to the next 4 or 5 in part B.

Blog link of the week 03

Sun, January 23, 2005, 01:20 PM under Links
By now you know about the yesfollow OR the chance to bid for an hour's consultancy with payment going to the victims... I will also remind you that the next installment of the training we mentioned last week is out - of particular interest the talk about progressive API...

Instead, go give a piece of your mind about default Form instances in VB (why would they listen now when they didn't before is a different matter)

I've already given a piece of my mind on the Class Designer in the past but I am still interested in new Beta 2 features.

Semaphore

Sat, January 22, 2005, 10:34 AM under MobileAndEmbedded
We looked at the implementation of EventWaitHandle for the NETCF 1.0 & 2.0

Here, I offer an implementation of Semaphore (another new Whidbey class inheriting from WaitHandle). If you are looking for it (e.g. in your Object Browser), note that unlike every other System.Threading class, it is in System.dll (and not mscorlib) (!)

Get the C# version from OpenNETCF (like most of my other contributions, in 1.3), and the VB version is available right now: Semaphore.vb

EventWaitHandle

Wed, January 19, 2005, 02:39 PM under MobileAndEmbedded
We looked at the absense of a nice class from NETCF (today & tomorrow). Here I will offer an implementation of the .NET 2.0 EventWaitHandle for the NETCF.

The C# version is over at the SDF, and the VB version is right here

Take note of inheritance limitations as described before, and obviously I have omitted parts of the interface that do not apply on WinCE. Finally, if you only wanted the class for CF 1.0 or just for CF 2.0, there are changes you can apply to the implementation - as it stands, it works on both :-)

WaitHandle

Tue, January 18, 2005, 02:21 PM under MobileAndEmbedded
As part of some restructuring for my app, I had to dig into the abstract System.Threading.WaitHandle class. As you'd expect, this is different on NETCF to the Full Fx, and both have changed with Whidbey (based on November CTP).

NETCF 1.0 vs .NET 1.1
The CF version does not provide the WaitAll or WaitAny methods; it only provides the basic parameterless overload of WaitOne. Comparing the total number of members (fields, properties, methods) regardless of scope, we find the CF version having half the members than the Full Fx (13 vs 26).

.NET 1.1 vs .NET 2.0
The main addition we'll get is the public static SignalAndWait methods (3 overloads). The class grows by 9 members in total. The other change is the replacement of the Handle type. Instead of using an IntPtr, it is now of the newly introduced SafeWaitHandle (of the new Microsoft.Win32.SafeHandles namespace)

NETCF 1.0 vs NETCF 2.0The WaitHandle in CF 2.0 brings no changes compared to CF 1.0 apart from implementing the IDisposable.Dispose method (that the Full Fx classes do in all versions).

Getting to the point
So why am I looking at this class? Well actually, I am not interested in the class itself; it is the derived classes that are interesting, and to understand an object's behaviour you must understand its parents. In .NET 1.1 and NETCF 1.0 the public inheritance relationship is:
Figure A
WaitHandle : MarshalByRefObject
|-> Mutex
|-> AutoResetEvent
|-> ManualResetEvent

In .NET 2.0 this changes with the introduction of a new class (and the one that interests me) EventWaitHandle:
Figure B
WaitHandle : MarshalByRefObject
|-> Mutex
|-> EventWaitHandle
|-> AutoResetEvent
|-> ManualResetEvent
|->Semaphore

EventWaitHandle is not supported in CF 2.0 and, in fact, the whole inheritance hierarchy remains the same in CF 2.0 as it is today (i.e. Figure A). Ignoring Semaphore for the time being (maybe a subject of a future post), I would have urged you to go vote but the inclusion of EventWaitHandle to NETCF has already been postponed.

The main use of this class would be for creating named events which play a prominent role in Inter-Process Communication on WinCE.

Next time we'll look at wrapping the pinvokes required to offer a class that exposes the same interface as EventWaitHandle (unfortunately, though, it cannot fit in the same inheritance hierarchy as the desktop, i.e. we cannot change the existing Compact Framework XXXXResetEvent classes to inherit from the EventWaitHandle we introduce, rather than the WaitHandle that they do).

ObfuscationAttribute

Mon, January 17, 2005, 10:11 AM under Whidbey | VisualStudio
This is the title of a blog post that immediately got my attention. I had to dig further, so here is the process.

Look at the attribute with a decompiler:
[AttributeUsage(AttributeTargets.Delegate | (AttributeTargets.Parameter | 

(AttributeTargets.Interface | (AttributeTargets.Event |
(AttributeTargets.Field | (AttributeTargets.Property |
(AttributeTargets.Method | (AttributeTargets.Enum |
(AttributeTargets.Struct | (AttributeTargets.Class |
AttributeTargets.Assembly))))))))),
AllowMultiple=true, Inherited=false), ComVisible(true)]
public sealed class ObfuscationAttribute : Attribute {
// Constructor
public ObfuscationAttribute();

// Properties
public bool ApplyToMembers;
public bool Excludet
public string Feature;
public bool StripAfterObfuscation;

// Fields
private bool mApplyToMembers;
private bool mExclude;
private string mFeature;
private bool mStripAfterObfuscation;
}

If you think drilling deeper will tell you anything, don't hold your breath; the properties are plain accessors for the fields and this is the ctor:
public ObfuscationAttribute(){

mStrip = true;
mExclude = true;
mApplyToMembers = true;
mFeature = "all";
}

OK, so the class itself doesn't unveil the mystery, but maybe applying it to one of our methods and then examining that will:
[System.Reflection.Obfuscation()]

public int ObfuscateThisPlease() {
int j = 6;
int i = 5 + j;
return (j - i);
}

.method public hidebysig instance int32 ObfuscateThisPlease() cil managed
{
.custom instance void [mscorlib]ObfuscationAttribute::.ctor()=(01 00 00 00)
// Code size 10 (0xa)
.maxstack 2
.locals init ([0] int32 j,
[1] int32 i)
IL_0000: ldc.i4.6
IL_0001: stloc.0
IL_0002: ldc.i4.5
IL_0003: ldloc.0
IL_0004: add
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: sub
IL_0009: ret
} // end of method Program::ObfuscateThisPlease

Nada. Tzifos. Nothing. At this point there is only one thing left to do: RTFM, and all is revealed:
"Instructs obfuscation tools to take the specified actions for an assembly, type, or member."

Well I bet, like me, you guys (and gals) were hoping System.Reflection.ObfuscationAttribute would be a pseudo-custom attribute rather than just a marker for 3rd party tools, but not every journey leads to a treasure :-(

I guess I could be applying it to all my privates automatically since, as we know, custom attributes cost absolutely nothing, until you explicitly reflect on them.

(Just to get this out of my system: I think the term Attribute is an unfortunate choice by the .NET designers. "Annotation", "decoration", "declaration", “metadata” or anything else would have not only conveyed the purpose better, but would also not clash with the UML's existing use of the keyword "attribute" to mean fields/data_members of a class)

Blog link of the week 02

Sun, January 16, 2005, 12:00 PM under Links
On Friday (I almost broke my pattern and posted BLOTW then), Brad Adams announced a free .NET training series on Class Library design, kicking off with "Setting the Stage". I must admit it really does set the scene and there isn't any technical info in this one, but it does make me unable to wait for the next ones (make sure you read slides 11-14 for MSFT's business model as per BillG)! Definitely one for your bookmarks.

If you are after a quick WinForms tip, Cathi Gero has a cool one. Not only I've always liked the AutoTab feature as an end user, but as a developer I was not aware before of the highly configurable Control.SelectNextControl method.

And the lighter side of Project Management

Call .NET from VB6

Wed, January 12, 2005, 01:52 PM under dotNET
This is a repost. The content appeared orginaly here, but I thought it deserved a post on its own rather than being at the bottom of an off (the main) topic entry.

[..] a demo I saw Don Box deliver at Tech Ed 2001 (in VB6) and TechEd 2004 (in Word Macro). So, in case you aren't aware of it, here is some VB6 code that always gets a nice reaction:
1. New VB6 "Standard EXE"
2. Project->References. Add:
Common Language Runtime Execuion Engine (mscoree)
Common Language Runtime Library (mscorlib)
3. Double-click on the form to get the Form_Load method (event handler)
4. Type in there the following 5 lines of code
Dim crh As CorRuntimeHost

Dim ad As AppDomain
Dim oh As ObjectHandle
Dim o As Object
Stop

5. Run->Start. The IDE breaks so you are in the debugger. View->Immediate Window
6. In the Immediate Window, type the following (line by line hitting return, don't just copy/paste)
Set crh = New CorRuntimeHost

crh.Start
crh.CurrentDomain ad
Set oh = ad.CreateInstance("mscorlib", "System.Collections.Stack")
Set o = oh.Unwrap
o.Push "Rocks"
o.Push "NET "
o.Push "."
MsgBox o.Pop & o.Pop & o.Pop

That's it! You've just used a .NET Stack class in VB6 by hosting the runtime.

Memory Problems FAQ

Tue, January 11, 2005, 11:34 AM under MobileAndEmbedded
A great number of posts in the NETCF newsgroup are memory related. This is no surprise, given the constraints of devices (as opposed to the PC), and most posts somehow end with a variation on this tail question: "[...] is this a known memory leak with the CF?"

Given that there are plenty of CF resources to help you in this area, I thought I'd gather them up in a single place for future reference.

1. The first thing to do is make sure you are running the latest released CF version. Contrary to popular misconception, this is (today) CF 1.0 SP3. For CF version info (numbers, how to determine it, where to get it etc) please go here.

2. Doing the above is good regardless of anything else; the second thing to address is "Are you really having memory troubles?” Can you reproduce a sample where you get an OutOfMemoryException? If not, why do you think there is a memory leak! This is common to devs still new to the managed world, where resources are not reclaimed immediately after they have been used. A rule of thumb applies here: if an object you are using offers the Dispose method, call it when you have finished using the object.

3. So we've now reached the case where you can reproduce a sample that throws the OutOfMemoryException (or at the very least that is what your main app does). Before you start pointing fingers at the Garbage Collector, please understand how the GC works (note the significant differences compared to the Full Fx version i.e. not generational, code pitching etc). Once you've done that, understand some v1.0 issues and workarounds, including when to call GC.Collect

4. "Fine with all the theory, but how do I measure?" You have a number of options available (please use them):
- Call GC.GetTotalMemory(false)
- PInvoke GlobalMemoryStatus (FAQ 6.5)
- Monitor Perf Statistics/Counters (do follow the links from that blog entry)
- Device's control panel applet e.g. on WinCE emulator, Start->Settings->System look under the Memory tab for memory info and how to change the memory distribution (check out the FAQ on the WinCE memory division between Storage and Program memory)

5. For completeness, here is a link to an in-depth article on WinCE memory management. The main takeaway, if you are coming from a desktop background, is that each process in CE has a limit of 32MB virtual address space; so forget loading all those massive bitmaps in memory.

6. On very extremely rare occasions you may possibly observe a "Low Memory Dialog" rather than an OutOfMemoryException. This is the OOM dialog which shouldn't, but may, pop-up before a managed exception is thrown. That is an indication that you are stressing the system but, if you really want to, you can remove the OOM component from your device - assuming you have control of the image with Platform Builder (if you are in that situation, check out the SetOomEvent and registry entries).

7. Finally, if none of the links above take you to long documents with many numbers, go read Advanced Memory article on CF 2.0

Blog link of the week 01

Sun, January 9, 2005, 03:59 PM under Links
I will not flood you with links like last time, but I must tell you that last week's winners have come back with killer posts; so revisit their blogs if you haven't already subscribed.

At the end of the first calendar week of 2005, why not download some tools (that I must admit not having played with yet)
-Check it out if you are working with process in WinCE and NETCF

-VS2005 Device Command Shell (a new tool that I bet will become very popular)

-Finally, subtle but important points about mixing operator overloading and inheritance.

Deploy to My Computer

Fri, January 7, 2005, 11:28 AM under MobileAndEmbedded
Regular readers will recall the deployment feature for Smart Device projects that was cut after Beta 1. It has now been confirmed that the "Deploy to My Computer" feature will not be supported for RTM. However, there are some steps you can follow to get it working (it just won't be supported) and it is likely that in the future there will be a powertoy to do the steps for you.

If you want more details on the feature I am talking about, and more importantly want to follow the steps to get "Deploy to My Computer" working today with the November CTP, please visit ladybug.

Below is a copy of the steps (which I can confirm work... on my setup anyway:-).

This is courtesy of Kei Amos:
Enabling deployment of managed applications to the desktop rather than a device:

This is a great productivity enhancement for application development, when you deploy often.
Note: Applications that use device-specific apps will not run properly on the desktop, and controls will render as desktop controls.

INSTRUCTIONS
1. In Visual Studio select Tools/Options, and then select Device Tools/Devices from the tree.
2. In the top combo box, select the platform that you want to add desktop deployment to. You’ll need to do this for each platform you want to use.
3. Select one of the devices, (it doesn’t matter which one) and click the Save As… button. Save as “My Computer”. If you’ve already done this for a platform, you’ll need to save subsequent devices with slightly different names (like “My Computer2”)
4. Close VS and open your %USERPROFILE%\Local Settings\Application Data\Microsoft\CoreCon\1.0\conman_ds_platform.xsl file in a text editor.
5. Find the <DEVICE …> element corresponding to the device you created and add the node (i.e. search for “My Computer” to find the correct node.)
<PROPERTY ID="IsDesktopDevice" Name="IsDesktopDevice">true</PROPERTY>
Place it right after the first <PROPERTYCONTAINER> tag.
6. Save conman_ds_platform.xsl and restart VS.

Now when you deploy, you can select “My Computer” from the deploy dialog.


UPDATE: For Beta 2, also see this thread

DV Sample

Thu, January 6, 2005, 02:16 AM under Whidbey | VisualStudio
As the sample I promised, I have written a visualizer for System.String. Given a string variable, it will show the bytes corresponding to that string based on the various encodings. The inspiration for it was the cry that a friend of mine got from their QA team recently regarding an app they have that "Doesn't work on a Chinese OS!".

To create it, we need a class library project that references Microsoft.VisualStudio.DebuggerVisualizers.dll and we add the following code:

1. Declare the attribute:
[assembly: System.Diagnostics.DebuggerVisualizer(

typeof(EncodingVisualizer.StringBytes),
Target = typeof(System.String),
Description = "Encoding Viewer")]

The above is all you need to enable the new menu item when you hover over a string variable (or in the Autos window). In the IDE, the menu looks something like this. Note how VS2005 gives us out of the box the HTML, XML and TEXT visualisers.

2. The code that runs when the "Encoding Viewer" menuitem is clicked, is in your class:
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace EncodingVisualizer {
public class StringBytes : DialogDebuggerVisualizer {
protected override void Show(IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider) {
string s = (string)objectProvider.GetObject();
frmStringBytes f = new frmStringBytes(s);
f.ShowDialog();
}
}
}
Naturally, you need a form frmStringBytes whose visual design looks like this; the constructor of the form does the work and is straightforward:
public frmStringBytes(string aString)

: this() {
txtExpression.Text = aString;

string s;
byte[] arr;
arr = System.Text.Encoding.ASCII.GetBytes(aString);
s = "ASCII = " + BitConverter.ToString(arr);
s += "\r\n\r\n";

arr = System.Text.Encoding.Unicode.GetBytes(aString);
s += "Unicode = " + BitConverter.ToString(arr);
s += "\r\n\r\n";

arr = System.Text.Encoding.Default.GetBytes(aString);
s += "Default = " + BitConverter.ToString(arr) + "\r\n";

// Do other encodings here e.g UTF7, UTF8, UTF32 etc

txtValue.Text = s;
}
You may download the dll and place it in the right place as discussed before.

NETCF SP3 RTM

Wed, January 5, 2005, 03:07 PM under MobileAndEmbedded
The latest Service Pack 3 for the .NET Compact Framework is now released as an MSI (via Tom Krueger). It was previously available as a QFE only.

For version number and full fix list please visit my previous announcement of the QFE release.

For history of NETCF version numbers and how to determine what version you are running see the wiki page.

Debugger Visualizers in Nov CTP

Tue, January 4, 2005, 05:26 PM under Whidbey | VisualStudio
Apart from Tracepoints (as hinted at the last sentence of that post), the most exciting debugging enhancement in Whidbey is the Debugger Visualizer support. If you are already familiar with VS2005 Debugger Visualizers, here you'll find what has changed with the latest Community Technology Preview (btw, the Dec is not the latest CTP from a framework version perspective, the Nov one is). If you are not familiar with the feature, I suggest you follow these links [ 1 , 2 , 3 , 4 ] and note the changes from previous versions detailed below:
1. The assembly reference must be to: Microsoft.VisualStudio.DebuggerVisualizers
2. The DebuggerVisualizer attribute ctor doesn't need the 3rd param i.e. delete the VisualizerUIType parameter as all visualizers are modal now.
3. Your class that implemented the Show method of IDebugVisualizer should now inherit from DialogDebugVisualizer and override the Show method; the signature for this now is:
void Show(IDialogVisualizerService, IVisualizerObjectProvider)
Of course, you need to imports/using System.Diagnostics and Microsoft.VisualStudio.DebuggerVisualizers; the location for visualizers (assemblies/dlls) is still the same: "My Documents\Visual Studio\Visualizers" or "[VS8]\Common7\Packages\Debugger\Visualizers"

That's all. If you didn't know about Debugger Visualisers and have downloaded the Nov CTP, follow the links at the top (and below), download their samples, make the appropriate changes and have fun!

Next time I'll implement a DebuggerVisualizer (not an Image Visualizer, which you can get here, here and here) so you have a complete sample to download.

Blog link of the week 53

Sun, January 2, 2005, 03:56 PM under Links
-Like last week, it is a (almost) new blogger that headlines BLOTW, an MSFTie no less, Scott Holden. Read all 5 posts he makes in his first week including the one where we learn that the GC threshold in CF 2.0 changes from 750KB to 1MB.

-Not technical, but it caught my attention (and read it to the end following all links etc). Have a look and decide where you stand. I am not quite so sure...

-Some A-list bloggers claim that if you haven't posted for a month you are worthy of un-subscription, I don't buy that. Steven Pratscner's last post was over 4 months ago; had I unsubscribed I would have missed this most informative entry.

-How do you calculate the size of a directory?

-Not sure how you'll use this knowledge but if you like knowing what goes on under the covers when you set a breakpoint, this entry is for you.

-This BLOTW is the longest I've done, but still, I must point you to a time waster (via Tech Blender). I managed to write "THE MOTH" but the closest I got to my name was "DA IE MO H"

Best of "The Moth" 2004

Sat, January 1, 2005, 03:38 PM under Personal
I don't like “pointing to myself”, but reflection is a good thing I guess. So, in chronological order, here are some of my favorite blog entries that I posted in 2004:

01. If you are changing thread priorities in your NETCF apps without being aware of these facts...good luck!

02. Everything about .NET Global Exception Handling is either in these 3 posts or in the links they point to: .NET 1.1, NETCF 1.0, .NET 2.0 (full & compact)

03. Whidbey's answer to UML class diagrams and where it falls short

04. So you are developing for both full & compact framework; are you doing it like this or like that?

05. Inter-Process Communication options with CF on WinCE; if it's not there, it doesn't exist

06. ALL links about serial comms (RS232) with .NET are here

07. VB2005 along with My brings Application Level events with a custom sub main. Use it *all* from C#

08. Control.Invoke today and tomorrow

09. More of a newsgroup support entry, but who says plain useful posts cannot be on my favorite list :-)

10. Generics in the Compact Framework (and not only)

11. BackgroundWorker today, tomorrow, full and compact frameworks: enough said

Thanks for reading... stay subscribed for an exciting 2005. As an aside, am I the only sad geek who associates the word "2005" with VS2005 ;-)