/spCf

comment(s) 

SmartPhone 2003 and .NETcf Primer

http://www.brains-N-brawn.com/spCf 9/8/2003 casey chesnut

This article will detail my early observations of managed coding for the SmartPhone.

Emulator

I am an early-adopter that lives in the phone-challenged country of the USA. Because of this I seem to always be waiting for something: people to adopt wireless web usage, networks to be upgraded, SMS messaging to take off, SIM card adoption, e911, decent pocket pc phone edition hardware, and now smartphone hardware (still waiting for a lot of these). Honestly, I dont keep up with the hardware rumor mills at all. I did ask explicitly in the microsoft smartphone newsgroup if there were any 2003 smartphones announced for the US (mid-August 03) ... and the answer was no. NOTE SmartPhone 2003 is important because it has the .NETcf and SP1 in ROM (also CE 4.2), while SP 2002 does not and there is currently not an install (do not know if there will be one either). So the MS SmartPhone-in-a-box is basically a brick for managed developers. Until then, the SmartPhone SDK comes with an emulator that can be used through eVC as well as VS .NET. I recommend installing eVC before installing the SDK for a couple reasons. 1) running the emulator outside of VS.NET with eVC installed adds an option to share a file system folder between your desktop and the emulator as a Storage Card. So if you open up the emulator, you can see the files as if they were on the device. currently we do not get this feature in VS .NET. 2) eVC gives you tools to view the file system, registry, processes, etc on the emulator. This ends up being helpful because there is no File Explorer on the SmartPhone OS which makes it a little more black-box'ish than developing for the Pocket PC. It is also worth noting that the emulator can emulate GAPI commands as well. Finally, the emulator can run with a 'virtual radio' or a 'radio'. My guess is that this means you could somehow hook up a GSM radio to your desktop machine, and the emulator would use that connection to make web service calls and such. This would be very useful for testing your apps ability to work with a slower connection, lost signals, etc...

the actual phones should not be as big as the emulator! would have to beat myself up if i carried a purple phone

PocketPCs are 240x320 while SmartPhones are 176x220

 

this gives an idea of how much text can be displayed

The following is a dump of what the directory structure on the emulator looks like. It is different than the PPC in that SmartPhone RAM is erased whenever the device is turned off. Also, in that the devices have on-board flash which files can be written to through the \Storage directory. PInvoking SHGetSpecialFolderPath with CSIDL_APPDATA (26) will return \Storage\Application Data; you should sub-dir off of this to store your own data. \Storage\Application Data\Volatile sounds like it is a RAM drive (seems like \Temp might be too)? Finally, it is worth noting that you cannot specify how much memory is used for Programs vs RAM as you could on the PPC.

\profiles
\profiles\default 
\Storage
\Storage\Application Data
\Storage\Application Data\Home
\Storage\Application Data\Sounds
\Storage\Application Data\Volatile
\Storage\ConnMgr
\Storage\MAPI 
\Storage\MAPI\ATTACHMENTS
\Storage\My Documents
\Storage\Program Files
\Storage\Program Files\Communication 
\Storage\Program Files\Communication\Mail Attachments
\Storage\Program Files\Connections
\Storage\windows
\Storage\windows\Accessories
\Storage\windows\Activesync
\Storage\windows\AppMgr
\Storage\windows\ConfigMgr
\Storage\windows\Debug Apps
\Storage\windows\Favorites
\Storage\windows\Fonts
\Storage\windows\Help
\Storage\windows\Messaging
\Storage\windows\Messaging\Attachments
\Storage\windows\Profiles
\Storage\windows\Profiles\guest
\Storage\windows\Profiles\guest\Cookies
\Storage\windows\Profiles\guest\History
\Storage\windows\Profiles\guest\History\History.IE5
\Storage\windows\Profiles\guest\Temporary Internet Files
\Storage\windows\Profiles\guest\Temporary Internet Files\Content.IE5
\Storage\windows\registry
\Storage\windows\Start Menu
\Storage\windows\Start Menu\Accessories
\Storage\windows\Start Menu\Games
\Storage\windows\Startup
\Storage\windows\Temporary Internet Files
\Storage Card
\Temp
\Windows

The \Storage Card directory is from the Folder Share between the desktop and the emulator by opening the emulator outside of VS .NET, and with eVC installed. NOTE when switching between running the emulator through VS .NET and eVC, I sometimes have to go and manually kill the Emulator.exe process. 

Projects

When creating a VS .NET SmartPhone project, we get the standard Smart Devices Application Wizard for choosing a platform (Windows CE, Pocket PC, and SmartPhone) and then the project type. The project types differ in that Windows CE can create Console apps, while Pocket PCs call it Non-gui applications, and SmartPhones entirely lack a similar type; allowing you to only choose between a Windows app, Class lib, and an Empty project. The projects do get the familiar .csdproj extension. When coding, you've got the same .NETcf class libs (plus SP1) that you have for CE and PPC. The only parts that are missing are some UI controls and the SqlCe bits (more on these later). In VS .NET the UI device controls are not available for selection, although they do show up in intellisense. If you try to instantiate them (e.g. Button b = new Button();) then you will get a runtime error of NotSupportedException. Since the managed bits are almost the same between all devices, i attempted to port a number of PPC apps to SP (SmartPhone). Basically creating the new project type and including the files was all that was required to get it to build. Then it was a matter of fixing runtime bugs from non supported UI elements and a lack of SqlCe (e.g. the same old write once - test everywhere scenario with diff java runtimes). The recent GoalieGame ported with only a minor menu change!

of course i let the computer win this time

So if you targeting your app for both the PocketPC and SmartPhone you should be able to keep a pretty common codebase. At runtime, you might be able to tell what type of device you are with the following results (else pInvoke GetVersionEx). NOTE these results are from the different emulators.

PlatformID pid = Environment.OSVersion.Platform;
Version v = Environment.OSVersion.Version;
//PID Major.Minor.Build.Revision
//WinCE 4.20.1088.-1 //sp 2003
//WinCE 4.20.1081.-1 //ppcPe 2003
//WinCE 4.20.1081.-1 //ppc 2003
//WinCE 3.0.11171.-1 //ppc 2002

An interesting side item is that I tried to port the PPC SliderPuzzle sample, and it ported easily, but the SP 2003 emulator was not able to open the sample jpg that it included. Also had problems with some other jpgs, but have not followed up on it, although i saw there was a similar newsgroup thread.

Windows.Forms

My first SP app developed from scratch was appropriately Hello World. Was going to have a button that popped up a MessageBox ... except I was quickly reminded that SPs dont have touch screens when the Button control in the Toolbox was grayed out (aka no SIP keyboard). Doh! Instead of Buttons, you can use a Menu. The menu is limited in that you can only have 2 top-level MenuItems, and the 1st top-level MenuItem cannot have any children. The 2 top-level MenuItem restriction is because they map to hardware buttons on the phone. The 1st MenuItem restriction is based on logo requirements, and I dont think it should be enforced by the runtime at all (let me make a non-standard GUI if i want to!). Either way, the VS .NET designer does not enforce these and you will get runtime errors if you dont follow them. Did i mention runtime errors? Other niceties of the menu is that it will map the 1st 10 (1-9, and then 0) MenuItems to the number keypad of the phone for usability sake. It can display 11 items at a time; if you go over 11 items, it will only show 9 with scroll up and scroll down markers to see the rest. The following pic shows a menu selection of 2 -> 2.1 -> 2.1.1 -> 2.1.1.1. You can see the scroll bars as well.

The documentation gives you the list of controls that you do have, but the following table seems more useful by quickly reminding you what you dont have (e.g. we lost 13, maybe 14, controls that we had for the PPC).

.NETcf (SP)

.NETcf (PPC)

.NETfx

  • CheckBox
  • ComboBox
  •  DataGrid (psych)
  • HScrollBar
  • ImageList
  • Label
  • ListView
  • MainMenu
  • Panel
  • PictureBox
  • Pointer
  • ProgressBar
  • TextBox
  • Timer
  • TreeView
  • VSrollBar
  • Button
  • ContextMenu
  • DomainUpDown
  • InputPanel
  • ListBox
  • NumericUpDown
  • OpenFileDialog
  • RadioButton
  • SaveFileDialog
  • StatusBar
  • TabControl
  • ToolBar
  • TrackBar
  • CheckedListBox
  • ColorDialog
  • CrystalReportViewer
  • DateTimePicker
  • ErrorProvider
  • FolderBrowserDialog
  • FontDialog
  • HelpProvider
  • LinkLabel
  • MonthCalendar
  • NotifyIcon
  • PageSetupDialog
  • PrintDialog
  • PrintDocument
  • PrintPreviewControl
  • PrintPreviewDialog
  • RichTextBox
  • Splitter
  • ToolTip

DataGrid shows up in the Device Controls Toolbox, but i dont think it should (it causes a compile-time error for me)? Other differences are that ListViews and TreeViews are supposed to take up an entire Form based on logo requirements. In this case the VS.NET designer defaults to the logo requirement, but you can resize the controls to be different, and it is not enforce by the runtime. The problem then is that once a Panel, ListView, or TreeView has focus; it will not give it up ... so we have to write code to get around that if necessary.

The MessageBox is also worth noting because it is full screen and only supports 2 buttons. If you specify a MessageBox with more then 2 buttons (e.g. MessageBoxButtons.YesNoCancel) then you will get an ArgumentException. From the pics below, you should realize that you should never use the default dialog settings (same as Ok-None below) because they are too plain. The TitleBar 'caption' shows the MessageBoxIcon that was chosen, and the 'text' shows the MessageBoxButtons. Notice how the softkey text changes too.

  

  

  

Debug.Write still doesnt show up, and this is what Trace.Assert messages look like:

  

We still have the Screen object to tell us the bounds and working area. Bounds is reported as 176x220, while WorkingArea returns 172x180 (due to the Title and Menu bar taking up 20 pixels each). If you delete the Menu, WorkingArea still returns 172x180, instead of reclaiming the 20 pixels from the missing Menu. You can also make full screen forms (this.WindowState = FormWindowState.Maximized;) and the WorkingArea still returns 172x180 instead of reclaiming 20 pixels for the missing Title (i consider both of these bugs). Forms can be made to scroll as well. It is a little different than how you could do it in the PPC, because of tab order and control focus differences, due to not having a touch screen. This can be overcome by hooking KeyDown events of the navigation pad, or by hooking OnFocus as different controls receive Focus.

Hooking the hardware buttons is also important on devices. From sample code in the SDK, I was able to hook both soft keys (KeyDown) and the back key (KeyPress). I was not able to hook volume up / down or the record buttons with purely managed code, but I bet it is possible with a MessageWindow for receiving unmanaged Messages.

GAPI

GAPI is still the same, but the difference is that the 2003 emulators for both SP and PPC support it. You have to deploy gx.dll to the device, and then you can directly pInvoke it and run your app on the emulator. Along with the sample by Alex Feinman, there was an article that came out while I was playing around with this, and takes a more performant approach. My code is real simple and just randomly draws black dots to the screen.

i control the horizontal and the vertical

Web.Services

Of course I also went digging for any changes regarding web services support, and found a nice little surprise! For auto-generated web-service proxies, we now can override GetWebRequest() on the SoapHttpClientProtocol to get access to the actual HttpWebRequest object that will be used to send the SoapRequest. I consider this a big deal! It lets us add Headers, set KeepAlive, and so forth. I'm sure this will make a lot of people happy so that they can add Cookies to keep a session between ASP.NET web service requests ... although I promote using a <Session/> SoapHeader instead because SOAP works on other protocols than HTTP. Prior to this change, you had to either do cookieless web services and munge the URLs, or build the SoapMessages manually and use the HttpWebRequest / Response classes.

a session-enabled web service would look like this:

[WebMethod(true)]
public int GetSessionCount()
{
	int iSess = 0;
	object oSess = Session["count"];
	if(oSess == null)
	{
		iSess = 1;
	}
	else
	{
		iSess = (int) oSess;
		iSess = iSess + 1;
	}
	Session["count"] = iSess;
	return iSess;
}

and you have to add the following overrides to the autogen'd proxy. NOTE I recommend creating a new class, inheriting from the autogen'd proxy, and adding the following code there (so you dont lose changes when updating the web ref). Then call the web service as you normally would using the subclass, and the web service will retain state between calls. NOTE PPC 2003 does not have SP1 in ROM, so this will not work without that addition. Not to mention that the current SP1 does not auto integrate with VS .NET

private static string sessCookie = null;

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
	System.Net.HttpWebRequest hwr = (System.Net.HttpWebRequest) base.GetWebRequest (uri);
	if(sessCookie != null)
	{
		hwr.Headers.Add("Cookie", sessCookie);
	}
	return hwr;
}
	
protected override System.Net.WebResponse GetWebResponse(System.Net.WebRequest request)
{
	System.Net.HttpWebResponse hwr = (System.Net.HttpWebResponse) base.GetWebResponse (request);
	if(hwr.Headers["Set-Cookie"] != null)
	{
		sessCookie = hwr.Headers["Set-Cookie"];
		//"ASP.NET_SessionId=g3exyaihxpmbkr55rhfxwq45; path=/"
	}
	return hwr;
}

Now for the bad news. Although WSE (Web Service Enhancements) 2.0 is now a technical preview and Soap 1.2 is now a recommendation, we still have no word on getting a client-side version of the WSE for mobile clients to support WS-Security, DIME, WS-Routing, WS-Policy etc... not to mention WS-Reliablity which should ultimately find its way into the WSE and would make perfect sense for devices that can constantly lose their connection. My only hope is the new Messaging model introduced in WSE 2.0, which decouples it from ASP .NET. With this break, it seems like the best chance we have for ultimately getting it for the .NETcf. My guess is that the decoupling of WSE from ASP .NET will kill off the SoapFormatter in System.Remoting as well? I'm holding my breath to find out what 'Indigo' is ...

Security

I dont have an actual phone, so I do not entirely understand this ... but it is something to be aware of. SmartPhones follow the CE module security scheme. The device can be either a One-Tier or Two-Tier devices. One-Tier devices treat access to all parts of the device as needing the same security, while Two-Tier might provide access to some functions, but restrict others. A privileged certificate would be required to access those restricted Two-Tier functions, and can be obtained through programs such as MS Mobile2Market. As well as being 1 or 2-Tier, the devices can be in a different mode: Open, Locked, Prompt. The apps ability to run will then depend based on:

The emulator is 1-Tier and Open by default ... meaning you dont have to worry about this when using it. NOTE this security model is different than Code Access Security with the full framework, which does not exist for the .NETcf. Also related to Security, the CryptoApi does exist on the SmartPhone and can be pInvoked. NOTE The high encryption pack rsaenh.dll exists on the emulator, but coredll.dll is what should be pInvoked. Did not see rsabase.dll at all.

SqlCe

SqlCe does not exist for the SmartPhone. So I asked on the MS smartphone.developer newsgroup what should be used instead. Peter Foot felt it should be replaced with the built-in XML support (e.g. DataSets and / or WebServices) and / or the CSV lib from opennetcf.org. Another option might be pInvoking the low level CE DB data store. Some combination of the above seems like it will work for a lot of apps. 

APIs

There are some interesting APIs that can be pInvoked as well. The ones I took note of included Bluetooth, Vibrate, Connection Manager, and Speech Recognition. The documentation even explicitly points out 3 that also exist on PocketPC Phone Edition (TAPI, SMS, and SIM).

Errata

These are just random questions that popped into my head and I did not have time to look into.

Source

Had a couple SDE projects that I would test out different stuff in:

Conclusion

The SmartPhone 2003 SDK allows for managed coders to begin developing apps for the SmartPhone. It will be an easy transition for those already familiar with the .NETcf and developing for the PocketPC. Cannot wait for the actual SP 2003 hardware to become readily available to consumers. Later