Rolling back to NETCF v1.0 from 2.0+
So on a little side project I am working on, I realized that I needed to roll back to .NET Compact Framework (NETCF) v1.0 from a newer version. Why, you might ask? Well, it seems that even on my fairly recent Windows Mobile 5 XV6700 HTC Apache/Mogul whatever (only 2 years old, hey now), that not even NETCF v2 is available. Now you can always just install NETCF 2 or 3.5, but those take up 5+ MB of precious space on your device. Even worse, when you start even the simplest app, your RAM usage can balloon to 3-4 MB with just a few simple controls.
Using the built-in NETCF (v1.0-ish) can help reduce those issues dramatically.
I was never able to figure out how to create a new NETCF v1.0 project in Visual Studio 2005, so I went back and installed VS 2003. Created the project, then opened it in VS2005 and added all of my old files. I need to use VS2005 because I am using Vista x64 and the device emulator in VS2003 doesn’t work in that environment it seems (drivers wouldn’t load). It is also my understanding that you can’t move forward to VS2008 either, that you are forced to upgrade the framework version.
So once I got my files included, I tried to compile. Ooops! Quite a few problems I had to fix popped up.
- The shorthand for property get/set (get; set;) didn’t work. I had to go back and redo all of my properties that used this. There is still a ‘prop<tab><tab>’ helper though.
- My resources were all messed up. I had to basically rebuild my forms from scratch, then copy in all of the stuff from the newer NETCF versions. I took the opportunity to simply move a lot of my resources into a skin folder and just load them at runtime with FileStream and Bitmap.
- I had a splash page that was just another form, and used TopMost to make sure it was on top. This isn’t available in NETCF v1, and it really isn’t clear to me at all how control paint ordering occurs by default. BringToFront/SendToBack didn’t really do much for me, and the order of creation of the controls didn’t help either. There is supposed to be a way to do this with SetWindowPos.
- List<string>-style templates aren’t available, or anything from System.Collections.Generic. You need to use ArrayList or similar instead, and some occasional casting from object.
- The MenuItem.Tag(and Tag from other controls) is missing, which is where you store your user data for menu controls. For instance you might create a list view of files, and each file would have a Tag object containing its FileInfo object. You have to come up with another solution here, like keeping track of the order/array of MenuItems, unless I figure something else out.
- Enum.Parse isn’t available.
It seems a lot of these problems can be solved by using the OpenNETCF Smartphone Device Framework v1.4. For instance EnumEx.Parse is available in that framework addition.
Static Events for Decoupling Communication Between Classes/Forms/Controls in C#
So I’m new to C#, but I have to admit that the ‘simple’ examples out there really aren’t simple and they really don’t cover what I would consider to be the most common use for events: Communication between forms and controls without having to resort to directly linking one class to another. I’ve been using Cairngorn Events/Delegates for awhile now in Flex/ActionScript3, so I’m not coming at it from a complete novice standpoint. But it seems every example I could find only showed how to raise and use events within the creator of the event. None of them showed how to use events to decouple, or reduce the linkage and increase the usability of your code.
So here goes: Imagine if you will, that you have several forms on your application and you want to allow the user to exit from any of them, while still doing that last minute clean up like saving any data or config, etc. ( I realize there is a way to do this using the Application event handler, but this technique applies all over the place, and this example is easy to understand.)
So first you want to create your event class. I put mine in a handy folder called Events in my C# project.
using System;
namespace Demo.Events
{
// Declare a delegate for an event.
public delegate void ExitAppHandler(object sender);
// Declare an event class.
class AppExitEvent
{
public static event ExitAppHandler evtExitApp;
// This is called to fire the event.
public static void OnExitEvent()
{
// ok so this calls the handlers we have +='d to listen the event
if (evtExitApp != null)
evtExitApp(null);
}
}
}OK, so this sets up a separate event class that has a static handler variable and a static method. This is the glue between our classes. Now we can reuse a form that calls this event, without having to worry about any other code.
Now we want to listen to this in our forms that want to do something when this event is triggered.
namespace Demo {
public partial class Demo : Form
{
public Demo()
{
Events.AppExitEvent.evtExitApp += new Events.ExitAppHandler(this.ExitEventHandler);
InitializeComponent();
}
// An event handler.
private void ExitEventHandler(object sender)
{
// TODO: Do cleanup/save/etc
this.Close();
}
}
}This could be your main application form for instance, with a lot of other stuff going on in this class, like adding controls, etc. Multiple forms that need to respond to the exit event would simply do the same thing: Add Events.AppExitEvent.evtExitApp += new Events.ExitAppHandler(this.ExitEventHandler); to their class/form, along with an ExitEventHandler method.
Now all we need to do is show another form/control/class calling this as well. In my case, this is a custom toolbar, or a sub form’s right click menu:
namespace Demo
{
public partial class Caller : UserControl
{
public Caller()
{
// If you wanted to have this form respond to the exit event as well, you could simply uncomment this
// Events.AppExitEvent.evtExitApp += new Events.ExitAppHandler(this.ExitEventHandler);
InitializeComponent();
}
// this is in response to a button click NOT SHOWN
private void pbExit_Click(object sender, EventArgs e)
{
Events.AppExitEvent.OnExitEvent();
}
}
}
And finally, we show how to call this static event:
Events.AppExitEvent.OnExitEvent();
This is called in response to a button click, that button not shown in this example, but you should hopefully get the idea. I’ve also shown commented out, that this other form could also be a consumer of the same exit event if you wanted.
That does it! I needed another similar event to occur when I minimized the app, and when I wanted to open a popup form from a number of different locations, so this technique is very useful.
Obviously, the above example doesn’t really show how to pass additional info with the event, like mouse coordinates or other data.
To do that you would need to create a class derived from EventArgs (CustomEventArgs let’s say) that held your custom data, and change the declarations to add in your custom event args. The existing examples out there show this aspect pretty well.
Why the iPhone is Destroying Windows Mobile in the Market
Ok, so this post is a little premature, but it just has to be said. The reason the Windows Mobile (WM) is dying on the vine lies firmly on the shoulders of the .Net Compact Framework( the C# library used for many application ) and the main WIN32 CE API in general. Now this is a little unfair of a characterization, because Apple has yet to release its SDK for the iPhone, but it is obvious that it is running a real OS. So many things have been stripped out of the Windows Mobile OS, that it is an effort in frustration to do even the simplest things. The documentation is a nightmare as well, with everything from the full .Net Framework listed with the Compact stuff, and there are no/few examples. To be fair also, as with all Microsoft products, backwards compatibility is always one of the main skeletons in the closet. WM has been around for 10 years now, and that legacy, along with the WIN32 legacy in general, has really held it back. But there is also this sense that they said: “This is what we think you should do, so we won’t give you any other way.”
Here is a hit list of issues that I’ve come across:
- There is no Rich Edit control, only a RichInk control. And for some retarded reason they decided not to support full justification in the RichInk control, so almost no WM apps do either, from PocketWord on. This means if you want justified text (like for an eBook reader), you have to roll your own. It would have taken maybe another 100-200 bytes to support it.
- Little transparency support. Any decent design takes advantage of transparency these days, and I am spending an hour googling trying to figure out why my toolbar buttons look like shit.
- No animation support. Think Flash here (move button A to X,Y over 1 second and add a drop shadow) . I imagine that Vista Aero has some better animation now, but WM has none.
- Just plain missing API calls, like OemToChar, and some other Unicode/Wide character support. I’m trying to compile an unrar DLL for WM and it just isn’t pretty, even though unrar doesn’t use much craziness.
- The WebBrowser control is completely crippled.
- And because it is all closed source you can’t see a damned thing about how it is done. This would solve almost any problem out, there, making the Compact Framework source viewable so you could make your own versions without having to start from scratch. [Updated: I have since discovered that you can look at a lot of the underlying NETCF (and .NET Framework in general) source code using .NET Decompilers like Reflector.
I have a C/Win32 API app I need to modify, and I would like to port it to C# but it is turning into a nightmare. And of course I would even consider getting an iPhone once the SDK comes out if they had a Verizon version, but I get no GSM reception in my apartment in NYC. I’ll keep you posted.
UPDATED: So I’ve gone ahead and just started from scratch with my project (an eBook reader), in C# NETCF v1.0. I’ve got pagination down within 30 seconds for a 300 page paperback on a mobile device, and it now does full expand/squeeze justification of the text.
Put Your Monitor To Sleep at the Press of a Button (Windows)
Here is a little AutoIt script I found while trolling their forums that will put your monitor into sleep mode at the push of a button. Both the script and a compiled EXE version are included, so you don’t have to install AutoIt to use. I put a shortcut to the script into my QuickLaunch bar, then changed the icon to the power button icon, and now whenever I am done with my computer for the time being I can press this button and my monitor goes off right away! There are plenty of other shareware, etc. tools out there to do this, but this one is so simple, it’s basically a single line of code. I grabbed this off of the AutoIt forums, and commented out some of the existing code. That code originally would turn off the monitor after 10 seconds of non-use (which is usually useful in a Network Operations Center but not much else).
Why I Still Use Windows
So I’ve thought more and more in recent months about why I still use Windows, as opposed to Mac OSX or Linux.
In my grand tradition of bulleted lists, here are the main reasons I am sticking with Windows currently:
- Newsleecher: Best USENET client period. I could give 2 shakes about the Supersearch feature, but for raw indexing speed, download speed, unRAR and PAR checking, etc., Newsleecher has no competitors.
- uTorrent: Best BitTorrent client period, though I could probably find a suitable replacement on OSX if necessary.
- mIRC: Best IRC Chat client out there, though I could probably find a suitable replacement on OSX if necessary.
- Microsoft Office VBA (Visual Basic for Applications): I have a number of VBA macros/forms for Word I’ve created over the years that I use. I believe that some older versions of Mac Office may have VBA support, but have never looked into it. I’ve tried out Open Office, and it just doesn’t have everything I need or look as nice as Office 2k7. I know a lot of people hate the new Ribbon interface, but I actually like it. With just a couple of customizations, I rarely have to leave the ‘Home’ ribbon now to do anything.
- Abbyy FineReader OCR/Omnipage Pro: Still the best platform for OCR period.
- HP Scanjet Drivers: For some reason my ADF scanners drivers cost $10 to get a CD from HP for OSX. Retarded.
- Directory Opus: The best file manager on the planet. Hands down.
- G-Force Visualization Software: The best audio visualization (trippy lights) software on the planet.
- Hardware selection: I build my own systems from the various parts suppliers out there for cool and quiet yet powerful systems, such as custom cases, top of the line motherboards, good memory, etc.
- Occasional gameplay: Windows is still king when it comes to games. Wine/Cedega may be usable, but that isn’t enough for me.
- Overall familiarity: I just have a lot more experience solving problems on Windows than on Linux/OSX.
- No official support for my Logitech diNovo Edge. Supposedly most features can be made to work in OSX using ControllerMate, but I haven’t seen mention of the scrolling features, which would be a deal breaker.
- It is nice that TV Guide data is built-in to the Media Center (though obviously it is also theoretically built-in to the price of the Windows).
Updated:
- AutoIt automation script language: a great way to do some things people never intended you to do with their programs…I’m sure there are others out there that do the same, but AutoIt is a great piece of software that can do almost anything, even if the code is a little ugly at times.
I would like to get off of Windows for a number of reasons:
- Tabbed consoles/command lines: Windows doesn’t support tabbed command line prompts properly
- Cost/DRM: Windows is getting more and more expensive and paying for a product laden with restrictive DRM is counterintuitive. I don’t trust Trusted Computing initiatives.
- Virus whoring: Windows just has more security issues than I would like. I haven’t had too many problems personally, but the way things work on Windows, it is too easy for garbage to get into the registry/startup folder/services that you don’t want or need.
It is possible to run OSX on typical Windows hardware if you are resourceful. This would almost certainly be more palatable to me than Linux:
- Nicer interface than say Ubuntu, although the gap is narrowing.
- All of the benefits of Linux software generally (through MacPorts).
- Adobe CS3 Products: Flash, Photoshop mainly… It might be possible to use these with Wine on Linux but I just couldn’t trust critical developer apps to Wine at this stage.
- True Microsoft Office, although the latest Mac Office gets rid of VBA support, so there is a limited timeframe of say a couple of years before the one with VBA becomes completely outdated. Again, MS Office is supposed to work in Wine, just not sure I would trust it completely.
- Non-alpha version of Adobe Flex Builder (though this will obviously get better once it reaches full release build, but I’m just not sure how committed they are to a Linux Flex Builder).
- Safari: I use Firefox almost exclusively because of Firebug, but being able to test on Safari is helpful as a developer.
- G-force Visualizer: Apparently there is a Mac version.
- Drivers are at least available for my HP Scanjet scanner, even if they do cost $10.
In either OSX or Linux, I could set up my system to be Dual bootable, meaning I could say put aside 20-30GB of harddsisk drive space just for installing Windows and a couple of apps or games that I needed to use occasionally. Or I could look further into Parallels/VMWare on OSX which let you run full Windows applications inside a ‘virtual machine’, typically with better compatibility than Wine, though with lower performance historically. I have a dual boot MacBook now, and it spends about half its time in Windows XP simply because my Vista x64 doesn’t support my HP Scanner.
Maybe when I get a free weekend, I will look at putting OSX on my Windows hardware, just to try it out. And I do have multiple systems, so I could leave one as Windows and move the others as needed.