Latest Posts
It's now easier than ever to evaluate Padarn,
our ASP.NET Web Server for Windows CE. We now have available an Evaluation Kit
that comes with:
-
A 600MHz fanless Windows CE 6.0 device
-
13 hands-on labs with full source code
-
A full sample Padarn web site with source code
-
Fully-functional Padarn evaluation binaries
The kit is being offered at an introductory price of $300.00, and if that isn't enough
to convince you, we'll even credit that against any purchase of Padarn you make.
For more information, see the Padarn
web site.
Managed Code in the Embedded World
The latest version of our Padarn Mobile
Server supports VirtualPathProviders. This means that now it is easy
to create REST
Web Services that run on your Windows CE or Windows Mobile device. Download
the latest hands-on lab "HOL P303 - Using VirtualPathProviders in Padarn
to provide REST Web Services" from
the web site here.
Managed Code in the Embedded World
As you may have guessed from some of my recent blog entries, we're making a push to
get a lot of our shared source code out to the Codeplex servers. Our serial
library is the latest one to make the move. It's now available at http://serial.codeplex.com.
As with all of these libraries, if you have the desire to contribute, fix, extend,
or whatever just let us know and we'll add you as a developer.
Managed Code in the Embedded World
In an effort to clean up our servers, to make code easier to find, and to hopefully
make it easier for the community at-large to contribute, we've moved our popular Desktop
Communication library over to the Codeplex servers.
Visit the project at rapi.codeplex.com.
Managed Code in the Embedded World
Over the past few months we've been working hard to consolidate the products we at
OpenNETCF offer. What this means is that products that didn't sell well or that
had high support loads compared to sales got dropped. Our Telephony library
is one of those that we decided to discontinue. But that's good news for all!
Instead of just letting it wither and die in the depths of our own source control
server, we figure it might as well be thrown out to the community to see if it will
flourish.
SO with that, we give you the OpenNETCF.Telephony Library, hosted
over at Codeplex as tapi.codeplex.com. Enjoy.
Managed Code in the Embedded World
In my last
blog entry, I showed a workaround for getting mouse events for the CF ListView.
Since I can't leave well enough alone, I decided I'd actually try implementing the
HitTest method (now that we have a valid x,y click coordinate). Here's the result:
namespace OpenNETCF.Windows.Forms
{
[Flags]
public enum ListViewHitTestLocations
{
None = 0x01,
Image = 0x02,
Label = 0x04,
StateImage = 0x08,
AboveClientArea = 0x08,
BelowClientArea = 0x10,
RightOfClientArea = 0x20,
LeftOfClientArea = 0x40,
}
public class ListViewHitTestInfo
{
public ListViewItem
Item { get; set; }
public ListViewHitTestLocations
Location { get; set; }
public ListViewItem.ListViewSubItem
SubItem { get; set; }
}
}
namespace OpenNETCF.Core
{
using OpenNETCF.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
public static partial class Extensions
{
private const int LVM_FIRST = 0x1000;
private const int LVM_GETCOUNTPERPAGE = LVM_FIRST + 40;
private const int LVM_SUBITEMHITTEST = LVM_FIRST + 57;
private struct LVHITTESTINFO
{
public int x;
public int y;
public ListViewHitTestLocations
flags;
public int iItem;
public int iSubItem;
}
public static int GetVisibleRowCount(this ListView
lv)
{
return Win32Window.SendMessage(lv.Handle,
LVM_GETCOUNTPERPAGE, 0, 0).ToInt32();
}
public static ListViewHitTestInfo
HitTest(this ListView
lv, int x, int y)
{
LVHITTESTINFO info = new LVHITTESTINFO();
info.x = x;
info.y = y;
GCHandle pInfo = GCHandle.Alloc(info,
GCHandleType.Pinned);
try
{
Win32Window.SendMessage(lv.Handle, LVM_SUBITEMHITTEST,
0, pInfo.AddrOfPinnedObject());
LVHITTESTINFO result = (LVHITTESTINFO)pInfo.Target;
ListViewHitTestInfo lvhti = new ListViewHitTestInfo();
lvhti.Location = result.flags;
switch (lvhti.Location)
{
case ListViewHitTestLocations.Image:
case ListViewHitTestLocations.Label:
case ListViewHitTestLocations.StateImage:
lvhti.Item = lv.Items[result.iItem];
lvhti.SubItem = lvhti.Item.SubItems[result.iSubItem];
break;
}
return lvhti;
}
finally
{
pInfo.Free();
}
}
public static ListViewHitTestInfo
HitTest(this ListView
lv, Point point)
{
return lv.HitTest(point.X, point.Y);
}
}
}
And usage looks like this:
public partial class Foo
: Form
{
public Foo()
{
InitializeComponent();
listView.Items.Add(new ListViewItem(new string[]
{ "Item
A", "Sub
A1", "Sub
A2", "Sub
A3" }));
listView.Items.Add(new ListViewItem(new string[]
{ "Item
B", "Sub
B1", "Sub
B2", "Sub
B3" }));
listView.Items.Add(new ListViewItem(new string[]
{ "Item
C", "Sub
C1", "Sub
C2", "Sub
C3" }));
listView.Items.Add(new ListViewItem(new string[]
{ "Item
D", "Sub
D1", "Sub
D2", "Sub
D3" }));
listView.Items.Add(new ListViewItem(new string[]
{ "Item
E", "Sub
E1", "Sub
E2", "Sub
E3" }));
ClickFilter filter = new ClickFilter(listView);
Application2.AddMessageFilter(filter);
filter.MouseDown += new MouseEventHandler(filter_MouseDown);
}
void filter_MouseDown(object sender,
MouseEventArgs e)
{
ListView lv = sender as ListView;
ListViewHitTestInfo hti = lv.HitTest(e.X,
e.Y);
if (hti.Item
!= null)
{
Debug.WriteLine(string.Format("Item:
{0}, SubItem: {1}", hti.Item.Text, hti.SubItem.Text));
}
}
}
All of this will end up in SDF v. Next, but why do we have to implement fundamental
things like this that should already be there? It was excusable to be missing
in v 1.0. Maybe even in v 2.0, but in 3.5? Really?
Managed Code in the Embedded World
We're going to be adding a full set of custom-drawn and owner-drawn controls in the
next version of the SDF. These are not "new" controls, but wrappers around the
existing native control, but we're adding the custom and owner draw hooks that the
OS already provides (and that, honestly, the CF team should have given us by version
3.5).
In testing them out, I wanted to dogfood the custom-drawn ListView in an application,
but I needed to know when a user clicked on an item in the ListView. Simple.
Or so I thought. It turns out that the style bits that get set to make a ListView
really usable means that the ListView's *parent* gets it's click actions, and to turn
those into Click events in the managed control is a *lot* of work, and would likely
have some performance penalty.
So that got me to wondering how the existing CF ListView deals with it. Well
after a very quick test it seems that the CF team made the same decision - they
didn't support the Click event either.
Well my application requires that I know the difference between when the selected
index changes (that's about the only useful event you do get) due a click and and
when it changes dues to a keyboard action like an up or down arrow. Being me, I refuse
to change the way I want my application will work just becasue of some stupid limitation
of a framework. The OS knows when I click on that damned thing - after all,
it changes the selected item - so it *will* tell my application when it happens.
The key here is pretty simple. We know that the click event does come in, and
it comes in as a Windows message. Our application message pump routes it to
the parent of the ListView - so we have two point at which we can try to get it.
Getting it from the parent would entail subclassing the parent Form, and that just
does seem like fun, nor is it really extensible if I ever have another app where I
want to get ListView item clicks.
So that leaves looking at the application message pump. Unfortunately the CF
team has again not seen fit in any version to provide us the ability to add an IMessageFilter,
but this was something we overcame long ago in the
SDF. If you use the Application2.Run method, you can then add IMessageFilters.
So what I did here is created an IMessageFilter that looks for messages
whose hWnd matches the ListView I'm interested in, and then looks for the WM_LBUTTONDOWN
message:
internal class ClickFilter
: IMessageFilter
{
private Control m_control;
public event EventHandler
Click;
public event MouseEventHandler
MouseDown;
public ClickFilter(Control
control)
{
m_control = control;
}
private int LoWord(IntPtr
param)
{
return (ushort)(param.ToInt32()
& ushort.MaxValue);
}
private int HiWord(IntPtr
param)
{
return (ushort)(param.ToInt32()
>> 16);
}
public bool PreFilterMessage(ref Microsoft.WindowsCE.Forms.Message
m)
{
if (m_control.IsDisposed) return false;
if ((m.HWnd
== m_control.Handle) && (m.Msg == (int)Microsoft.Controls.WM.WM_LMOUSEDOWN))
{
MouseEventArgs
args = new MouseEventArgs(MouseButtons.Left,
1, LoWord(m.LParam), HiWord(m.LParam), 0);
ThreadPool.QueueUserWorkItem(ButtonInvoker,
args);
}
return false;
}
void ButtonInvoker(object o)
{
// let
the system select the clicked listview item
Thread.Sleep(10);
Application2.DoEvents();
if (m_control.IsDisposed) return;
if (m_control.InvokeRequired)
{
m_control.Invoke(new WaitCallback(ButtonInvoker), new object[]
{ o });
return;
}
//
not truly a click, since it's not a down/up pair. Fix this later if we feel like it
if(Click
!= null)
Click(m_control, null);
if (MouseDown
!= null)
MouseDown(m_control, o as MouseEventArgs);
}
}
Take note of the slight kludge in there though with the ThreadPool. The reason
for this is that if you just raise the event immediately on getting the mouse down
event, the ListViewItem selection won't have happened yet, so if your handler looks
at the SelectedItem, it would get the item that was selected before the click, not
the one that the was clicked.
Sure, maybe that's what your app wants, but in my case I wanted to know which item
is actually clicked. The ListView doesn't support a HitTest method (again, why
don't we have this yet?), so knowing the x,y coordinates of the click is still a long
way from giving us the ListViewItem. This was a kludge to easily get me the
info I wanted.
So using this filter in my application was as easy as adding this to the
Form that contains the ListView:
InitializeComponent();
ClickFilter filter = new ClickFilter(listView);
filter.Click += new EventHandler(filter_Click);
Application2.AddMessageFilter(filter);
No, it shouldn't be this hard. I wish the CF team would spend more time fixing
fundamental stuff like this instead of tilting at the Silverlight windmill, but it
is what it is, and as developers we still have to ship solutions.
Managed Code in the Embedded World
It took a long time to get here, but we've finally release what I'm calling the version
1.0 (pervious version were 0.9.x) release of the OpenNETCF.IoC
Framework. In case you've not been tracking this project, it is a public-domain-licensed
(you can't get any more free and unencumbered than that) framework that provides both inversion
of control and dependency
injection for .NET
Compact Framework applications (it can be used on the desktop as well).
It's roughly modelled after Microsoft's
SCSF and CAB frameworks, but it's scaled down and optimized for running on mobile
and embedded devices, plus I "fixed" stuff that I think the SCSF got wrong (like having
a static, globally available RootWorkItem and
the ability to insert IMessageFilters into
the application's message pump).
This framework is in use in a couple of commercial applications already, so it's been
pretty heavily tested and vetted. I still want to add a few more features as
well and go back through it looking for performance optimizations, but it certainly
has enough features to be used in applications today.
This release also ships with a full-blown, real-world sample application, not just
the typical "Northwind" type of application. The sample is called WiFiSurvey
and it can be used to survey WiFi AP coverage of a site and to monitor associated
AP changes as well as network addressability of a device.
WiFiSurvey has a Configuration service, a SQL
CE 3.5-backed Data Access
Layer, an Infrastructure module and a an application shell all of which are fully
decoupled from one another and that are all loaded dynamically using an XML definition
file. The shell makes use of both a DeckWorkspace and a TabWorkspace, showing
you not just how to use them, but also how to create your own workspaces if need be.
The WiFiSurvey application has a single source base for all target platforms and has
been tested on the following platforms:
-
ARM-based CE 6.0 with a 320x240 (landscape) display.
-
Pocket PC 2003 240x320 (portrait)
-
WinMo 5.0 240x320 (portrait and landscape)
The IoC framework has additionally been tested on x86-based CE 5.0 and CE 6.0 devices.
As a side note, the WiFiSurvey sample application is also a good example of using
the OpenNETCF Smart
Device Framework for getting wireless information.
Managed Code in the Embedded World
So it seems that something has changed in CE 6.0 in the way that user inactivity is
detected by the OS. In CE 5.0 and before, if we wanted to keep the backlight
on we could periodically call SystemIdleTimerReset and
all would be well. In CE 6.0, this no longer works. Now we have to set
a named event that GWE is waiting on. Here's what it looks like (this code uses
the SDF for the named
EventWaitHandle - the CF doesn't provide one).
private EventWaitHandle
m_activityEvent;
[DllImport("coredll",
SetLastError=true)]
private static extern void SystemIdleTimerReset();
private void ResetBacklightTimer()
{
if (Environment.OSVersion.Version.Major <= 5)
{
SystemIdleTimerReset();
}
else
{
if (m_activityEvent == null)
{
using (var key = Registry.LocalMachine.OpenSubKey("System\\GWE"))
{
object value = key.GetValue("ActivityEvent");
key.Close();
if (value == null) return;
string activityEventName = (string)value;
m_activityEvent = new EventWaitHandle(false,
EventResetMode.AutoReset, activityEventName);
}
}
m_activityEvent.Set();
}
}
>
Managed Code in the Embedded World
I've released yet another version of the OpenNETCF.IoC
Framework. This release has a few minor fixes over what I shipped last week,
but more important is that it includes the start for a more complete example.
The new sample shows how to dynamically load modules based on a configuration XML
document and how to use the DeckWorkspace.
If you're using the framework, please let me know. I see that it's been downloaded
and we're getting some questions and bug reports, so I know that people are at least
testing it out, but I've gotten no feedback as to whether anyone finds it useful of
not.
Managed Code in the Embedded World
The new Demo
showing XAML for Windows CE is really, really impressive. This is non-WinMo,
meaning CE no longer is a second-class citizen in the device market. If
only I knew how to do design work....
Managed Code in the Embedded World
I've pushed up a new set of features and fixes for the OpenNETCF.
IoC Framework
as well as rolled a new release. See the
Project Site for
full details on what changed, but the general feature additions are that the framework
now supports loading modules from configuration XML (you can now really decouple your
app modules) and I added support for a DeckWorkspace and all the trappings around
starting your app from a workspace.
Managed Code in the Embedded World
Detecting if your application has been idle (i.e. no user mouse or keyboard actions)
for a certain period of time is straightforward using an IMessageFilter implementation.
The filter would look like this:
using System;
using System.Collections.Generic;
using System.Text;
using OpenNETCF.Win32;
using System.Windows.Forms;
using OpenNETCF.Windows.Forms;
namespace MessageFilterSample
{
public class InactivityFilter
: IMessageFilter
{
public event MethodInvoker
InactivityElapsed;
private Timer
m_inactivityTimer;
public InactivityFilter(int timeoutMilliseconds)
{
m_inactivityTimer = new Timer();
m_inactivityTimer.Interval = timeoutMilliseconds;
m_inactivityTimer.Tick += new EventHandler(m_inactivityTimer_Tick);
Reset();
}
void m_inactivityTimer_Tick(object sender,
EventArgs e)
{
m_inactivityTimer.Enabled = false;
Elapsed = true;
if (InactivityElapsed
!= null)
InactivityElapsed();
}
public bool PreFilterMessage(ref Microsoft.WindowsCE.Forms.Message
m)
{
switch ((WM)m.Msg)
{
case WM.KEYUP:
case WM.LBUTTONUP:
case WM.MOUSEMOVE:
//
reset the timer
m_inactivityTimer.Enabled = false;
m_inactivityTimer.Enabled = true;
break;
}
return false;
}
public int Timeout
{ get; set; }
public bool Elapsed
{ get; private set;
}
public void Reset()
{
Elapsed = false;
m_inactivityTimer.Enabled = true;
}
}
}
To use it, you must use one of the Run overloads in Application2 to start your application,
then you can add your filter like this:
InactivityFilter
m_filter = new InactivityFilter(5000);
m_filter.InactivityElapsed += new MethodInvoker(m_filter_InactivityElapsed);
Application2.AddMessageFilter(m_filter);
...
void m_filter_InactivityElapsed()
{
MessageBox.Show("Inactivity
timer fired");
}
Download the sample here:
MessageFilterSample.zip
(3.92 KB)
Managed Code in the Embedded World
We've been doing a ton of internal work lately on our Padarn
ASP.NET Web Server for Windows CE - both on features as well as just the general
stuff you have to do to have a product. Part of this work was to create a series
of hands-on labs to demonstrate how to use Padarn effectively. The PDFs (a dozen in
all so far), along with the latest Developer's Guide are available for public
viewing on the Padarn Downloads
page.
Managed Code in the Embedded World
Admittedly this isn't really mobile related, but the guys over at CI
Advantage are giving
away T-Shirts with every download of the eval version of Deploy
Now (which we do use and love here). If you have desktop installations
of anything, including mobile software or tools (we use it for testing the SDF
installer scenarios, among other things) - it's a major time saver.
Managed Code in the Embedded World
Back in May 2008, I wrote a blog post about checking
for Win32 methods. I was recently reminded of this when a customer emailed us
about a scenario that exactly matched the intended use case.
The customer was using the Smart Device
Framework with a Windows CE 5.0 device and was receiving a MissingMethodException
"Can't find an Entry Point 'xxx' in a PInvoke DLL 'yyy'". The exception message
is detailed enough to explain the situation -- since Windows CE is modular, whoever
created the OS image had not added a required component, resulting in the native functions
to be missing from coredll.dll. This is not an uncommon scenario in the Windows CE
world.
Below is an example of how you can gracefully handle calling the PlaySound function
from coredll.dll even on devices that don't support the function. The important
part is the call to Device.Win32Library("coredll").HasMethod("PlaySound").
This is return false if coredll.dll does not exist or if coredll.dll does not export
the PlaySound function. Of course, you could raise a PlatformNotSupportedException or
try another mechanism for playing the sound file instead of just returning without
calling the native PlaySound function. The important point is that you should code
in a way that can handle scenarios where the native function is not available and
adapt accordingly.
Imports System.Runtime.InteropServices
Imports OpenNETCF.Reflection
Partial Public Class MainForm
Friend Class NativeMethods
Private Const SND_ASYNC As Integer = &H1
Private Const SND_FILENAME As Integer = &H20000
Public Shared Sub SafelyPlaySound(ByVal soundFile As String)
If Not Device.Win32Library("coredll").HasMethod("PlaySound") Then
Exit Sub ' Function is not exported so we silently return
End If
' Coredll exists and the PlaySound function has been exported
' so we can safely make the P/Invoke call
PlaySound(soundFile, IntPtr.Zero, SND_ASYNC And SND_FILENAME)
End Sub
<DllImport("coredll.dll", EntryPoint:="PlaySound", SetLastError:=True)> _
Private Shared Function PlaySound(ByVal szSound As String, _
ByVal hMod As IntPtr, _
ByVal flags As Integer) As Integer
End Function
End Class
End Class


Last week we quietly launched a fantastic new promotion for our Padarn
Web Server product:
Padarn is a lightweight, single-purpose web server that supports a growing subset
of ASP.NET. It is written entirely in C# and can be used as stand-alone web server,
or embedded into an existing application. Padarn can be used to create elegant, data-driven
web sites using SQL Server Compact Edition, or interface with a whole myriad of hardware
peripherals, such as web cams, sensors, controllers, etc.
If you would like more information on Padarn, please send an email to padarn@opennetcf.com.

Note: This blog post only applies to Smart Device Framework Standard or Professional
Edition customers.
>
If you open the SDF Public Source solution that ships with Smart Device Framework
2.3 and then build the source, you'll come across the following error:
Friend access was granted to 'OpenNETCF,PublicKey=...', but the output assembly is
named 'OpenNETCF, Version=2.3.0.21, Culture=neutral, PublicKeyToken=null'. Try
adding a reference to 'OpenNETCF,PublicKey=...' or changing the output assembly name
to match.
(Note that I've replaced the actual public key with ellipses in the above. You will
see an extraordinarily long hexadecimal number in your errors list in Visual Studio.)
The easiest way to remedy this is through a quick search & replace. Hit Ctrl-H to
bring up the Find & Replace window. In the Find what text box, enter
the following:
,PublicKey=00240000048000009400000006020000002400005253413100040000010001002beeba3
bfe7c548e085cffb8c2b6fd61ddd02b06d70864bb7de8bb22473edf5ab4b2196ff98e232c3e87f11fd
7986b743d5d3fdd6ecaf624bacfed116e1cefa50cd652365371d0ebd2702eb1084fed46df79ac0f59f4
d66c547918613d56dcf106843f3458516d3cd26f057a346d9f645fc24a7410a095c754835916e13cdbe
Make sure the Replace with text box is empty and the Look in combobox
is showing Entire Solution. Click the Replace All button. When the search
& replace has completed, build the solution again and it will succeed.
If you wish to do this manually (you may only want to use 1 or 2 of the 16 projects),
you will need to modify the AssemblyInfo.cs file for the following projects:
-
OpenNETCF
-
OpenNETCF.Configuration
-
OpenNETCF.Net
-
OpenNETCF.Windows.Forms
>

Today, we released Smart Device Framework
2.3. This is the long awaited release of the Smart Device Framework for Visual
Studio 2008.
It's been a painful path to get to this point, what with contending with frustrating
bugs in Visual Studio 2008 forms designer and all, but we finally got there. Thanks
for you patience and understanding.
Along with the new version is a new naming convention. We've dropped the name Smart
Device Framework Extensions for Visual Studio with its Standard and Premium editions.
Instead, say hello to Smart Device Framework Standard Edition and Professional
Edition. Be sure to check out the new feature
matrix to find out how each edition differs.
We've got some pretty cool stuff features in the libraries, notably OpenNETCF.Core which
contains a dozen or so extension methods for common scenarios, as well as OpenNETCF.Net.Mail,
for sending mail via SMTP directly from the device -- this eliminates the need to
configure a mail account on the device.

When you reference an assembly compiled against .NET Compact Framework 2.0 in a project
targeting .NET Compact Framework, it's quite likely you will receive a number of ResolveAssemblyReferences warnings,
similar to this:
ResolveAssemblyReferences:
Consider app.config remapping of assembly "System.Windows.Forms, Culture=neutral,
PublicKeyToken=969db8053d3322ac, Retargetable=Yes" from Version "2.0.0.0" [] to
Version "3.5.0.0" [C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\
WindowsCE\System.Windows.Forms.dll] to solve conflict and get rid of warning.
This warning occurs when the compiler has loaded the .NET Compact Framework 3.5 base
class libraries (BCLs) and the referenced assembly, but the metadata contained in
the referenced assembly references the .NET Compact Framework 2.0 BCLs.
To remove the warnings you can add an App.Config to your project and redirect the
assembly bindings from the 2.0 versions to the 3.5 equivalents. Below is an example
of the XML required in the App.Config to redirect the 2.0 version of System.dll to
the 3.5 version.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentassembly>
<assemblyidentity name="System" culture="neutral" publickeytoken="969db8053d3322ac" />
<bindingredirect newVersion="3.5.0.0" oldVersion="2.0.0.0" />
</dependentassembly>
</assemblybinding>
</runtime>
</configuration>
You will need to add a dependentassembly element for each of the ResolveAssemblyReferences
warnings that you receive.
Make sure the Build Action property of the App.Config is set to Content and
the Copy To Output Directory property is set to Only if newer. Then,
rebuild your solution and the warnings should not appear.

There's been a lot of internal discussion today on how to leverage C# 3.0 features
without requiring .NET Compact Framework 3.5. Mark has the low down on using extension
methods with a little compiler misdirection hack.
The discussions kicked off because I discovered that you can use lambda
expressions with .NET Compact Framework 2.0 projects in Visual Studio 2008. I
even twittered about it yesterday. (Note: it didn't take me too long to realize it's
not a bug, but due to Visual Studio 2008 using the C# 3.0 compiler.) Code
like the following just works -- no hacks required:
delegate double PowerOf(double x, double y);
static void Main()
{
PowerOf pwr = (x, y) => Math.Pow(x, y);
double result = pwr(2, 3);
}
If you are using Visual Studio 2008 and still need to target .NET Compact Framework
2.0, the little things like this go a long way to creating and maintaining reusable
code.

Over the last few months we've been working hard to attain the Gold Level partner
status in the Microsoft Partner Program and I'm extremely pleased to say that we've
done it! For our customers, this is an assurance that by choosing to work with OpenNETCF
products and our consultants, you really are choosing a high calibre company.
Massive amounts of credit for Mark for
driving this internally. Good job!

The next Smart Device Development Chat will take place on MSDN at 10am PST on Wednesday,
July 16.
Please join experts from the Windows Mobile, Windows CE, SQL Server CE and .NET Compact
Framework communities in a chat around application development for smart devices.
These chats are a great opportunity to have your questions answered by experts from
around the world.
Add
to Calendar
If you cannot attend the MSDN Chat, there is a permanent chat room available on the web and
via IRC (irc://irc.freenode.net/mobiledev).
Engage with your peers online today!

A little later than I intended, but here is the transcript to Smart Device Development
chat from May 13, 2008: Read
it here

I was browsing around over lunch when I came across an upcoming title from Wrox that
I thought might be interesting to someone out there.
The book, being writing by Samuel Phung of ICOP,
is titled Professional
Microsoft Embedded CE 6.0. A book like this is sorely needed as most of the knowledge
exists primarily in the embedded newsgroup or scattered around in a handful of blogs.
The 20-chapter book will cover everything from creating an image to development in
C# and VB.NET, as well as C++ and is scheduled to be released in November. Wrox have
made a number of chapters available through
their Wrox First subscription service.
