I've been writing a play by text message version of battleships for Windows Mobile 6 using the MessageInterceptor class to receive messages. This works great on my AT&T Tilt but completely fails on my wife's Pantech device. The MessageInterceptor hooks up fine but never fires.
The 2.0 compact framework SmsAccount lets you send messages but unaccountably doesn't let you read them.
I avoided some unpleasant interop by grabbing the MAPIdotnet library. This implements a NewMessage event for MAPI stores, however as with MessageInterceptor the event hooks up OK but never fires on the damned Pantech.
MAPIdotnet does allow you to read the SMS inbox though, so the final answer is to fall back to looking for, processing and then deleting game related text messages on a timer. This is far from ideal as the game messages arrive and vibrate the phone before getting processed but at least it's now possible to play without buying a new phone.
To add to the frustration during development the Visual Studio 2005 toolbox lost all icons except for the pointer and a custom control that was part of the project. Resetting the toolbox didn't help, nor did restarting VS and the computer. The fix was to exit VS and then delete all the .tbd files from Microsoft\VisualStudio\8.0 in local application data. Sigh.
This has bitten me a few times. If you use Process.Start("url") it will work some of the time but you'll see a "The system cannot find the file specified" Win32Exception on some systems. Bummer.
Lots of people suggest looking up the HTTP handler in HKEY_CLASSES_ROOT but this is flawed as well - on my system for instance HTTP is registered to Firefox even though I'm actually using Chrome and I'd be unhappy waiting half an hour for Firefox to wake up and show the requested web page.
From XP there are a couple of registry settings tied to the current user's preferred browser.
First check HKEY_CURRENT_USER\Software\Clients\StartMenuInternet. This key will only exist if the user has overridden the system default browser - the default value is used to access the details (for me, it's chrome.exe).
If the user hasn't set a default then check HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet. The default value here is the system default browser (on my system it's FIREFOX.EXE).
There is a set of subkeys under HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet that contain details about each registered browser. The default value from StartMenuInternet (either HKCU or HKLM) is the subkey to look for. The path to my default browser is in this key:
Now I can Process.Start(path, url) to safely launch the default browser. You can fall back to Process.Start(url) if registry access fails for some reason, but be prepared for that Win32 exception.
I've been migrating my installers over to WiX. My only complaint with the WiX toolkit is that there's no bootstrapper included. This is important for installing any pre-requisites before passing control over to Windows Installer. Hopefully this will come after WiX 3.0 is released. For now, I've rolled my own bootstrapper to install .NET 2.0 if needed.
A couple of tips for screen savers. You can bring up the Windows screen saver settings using the following custom action. This is the same command that is launched when you right-click a screen saver (.scr) file and pick Install:
ExeCommand='rundll32.exe desk.cpl,InstallScreenSaver the.scr'
Sequence this in InstallExecuteSequence after InstallFinalize:
<Custom Action="InstallSS" After="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
You can also add a shortcut to your Program Files folder to configure the screen saver. This is really helpful for people who aren't sure how to get to the screen saver dialog from Control Panel or right-clicking the Desktop:
LongName='Screen Saver Settings'
Unlike a shortcut to a file that you install you need to specify the Target. The example above assumes that ProgramMenuDir is the Id of your Start Menu folder. The shortcut should be in a Directory but not as a child of a File node.
I started using bDule today after reading about it on Techcrunch. It seems to be very nearly the perfect twitter client for me - decent multi-account support, Facebook integration and reasonably snappy. Also, and this is really important for me, it's not oppressively black.
The group feature isn't quite there yet, it doesn't list all my friends and there's no way to edit a group after you create it. There's also no spell checker and getting the right layout is unnecessarily awkward. It's still in alpha so there's good reason to hope that these problems will be addressed soon.
I wonder where the name comes from. It makes me think of a certain casual game where you swap gemstones around until you're ready to chew your eyeballs out. I'm the last person to talk about puzzling software names though.
bDule is WPF/.NET3.5 so only runs on Windows XP or better. It also seems to suffer from the same creeping memory usage that plagues other desktop Twitter clients. I really wish someone would start offloading the stream into a database. I've got nearly frustrated enough with this to write my own Twitter client a couple of times, but it's not exactly an uncrowded market.
If you're a Windows tweeter give bDule a try.
I'm updating a screensaver so that it stops work once the monitor switches off. This seemed like a really simple requirement but it took some time to find an API that works on both XP and Vista.
My first attempt was ReadPwrScheme(). The documentation suggests using a different method on Vista - it should say so more strongly because on Vista you get back some default information that bears no relationship to reality.
Next I tried CallNtPowerInformation(). This doesn't mention any alternatives but also doesn't work on Vista. I've added comments on both MSDN pages pointing to the answer.
GetCurrentPowerPolicies() is just the ticket - it returns a wealth of information including the video timeout on AC and battery power and works on both XP and Vista.
Pinvoke.net has all the structures required but not the actual function. I've just added the C# interop signature for GetCurrentPowerPolicies().
I can't believe how frustrating finding this information has been. If you've found this post I hope it saves you a couple of hours :).