September 2010 Blog Posts

Android, Google Calendar, BlackBerry, and Sending Appointments

My wife has a BlackBerry and I used to as well until I switched to a Droid X. One of the things we used to do to help each other remember stuff or get things onto the other person's calendar (when using BlackBerry) was to send an appointment via MMS to the other person. You could add an appointment to your BlackBerry calendar, select it, and send it to someone else. Really easy.

Problem is, that's not how Google Calendar works, which means when I switched to Android, all hell broke loose. You can't export an event as an iCal (.ics) or vCal (.vcs) file, which is basically what the BlackBerry was doing. However, there is a way to do this, it's just not... intuitive. At least not to me since I'm so used to shipping .ics files around.

Getting an Appointment from BlackBerry to Android/Google Calendar

  1. Open the appointment on the BlackBerry.
  2. Send the appointment to the Google user's Gmail address (the account the calendar is hooked up to).
  3. When the Gmail user opens the appointment the BlackBerry user sent, Gmail displays it as a meeting invite and asks you if you'll be attending. Click the "Yes" link  in the email and it gets added to your calendar.

There's an alternate way to do this, too, but it involves saving the .ics file that's attached to that incoming Gmail and going to Google Calendar and running an import... but that's painful and not necessary. Just click "yes" and call it good.

UPDATE 12/22/2010: Opening an appointment in Gmail appears to only work if you do it from a desktop computer, and from the full view - not just the basic HTML view. You can't open the appointment and accept it right on the Android phone because the Gmail client on Android will simply show the appointment as an attachment and not an invitation.

Getting an Appointment from Android/Google Calendar to BlackBerry

For this one, you need to have the email address attached to the BlackBerry. Some people set up their Gmail or Hotmail or whatever so the BlackBerry automatically picks it up, and if so, that'll work; other people (like my wife) have a special email provided by the service provider like phonenumber@vzw.blackberry.net that goes to the BlackBerry. You'll need that address so you can get the email to the BlackBerry's native email client, not, say, the Google Mail app installed on the BlackBerry.

  1. Open the appointment in Google Calendar.
  2. Add a guest to the appointment and use the BlackBerry's email address (as discussed above) as the guest email.
  3. When Google Calendar asks you if you want to send a notification to the guest, say yes. This automatically sends the .ics file to the BlackBerry user on their phone.
  4. The BlackBerry user can open that email and add the appointment to their calendar using the attached .ics. Done.

Tips for a New Droid X Owner from a New Droid X Owner

A few weeks ago I got a Motorola Droid X. It didn't start out as well as I'd like.

The first phone I got had a bad pixel on the camera's CMOS sensor that caused a big pink blotch in the middle of any pictures or video I took. I returned that one and got a second phone, which had a perfect camera sensor but a bad pixel on the screen. Third time was the charm, as I returned the bad screen phone for another that has both a good camera and a good screen.

Hardware problems aside, I also had a bit of a learning curve to get over, moving off a BlackBerry Curve, and I ran into some trouble with connecting to wireless networks reliably. All of this left me a little disillusioned but I've gotten to a point now where I'm really liking it again.

If you're a new Droid X owner, I thought I'd offer you some tips to help you skip over the whole disillusioned state. (In some cases, these are good for any Android-based phone owner, but I can't really speak to anything but my Droid X experience.)

  • Test your screen and your camera. This is pretty easy to do in one go. Switch to the camera app and then point the camera at a white wall. Look to see if any of the pixels on the screen aren't white. Do the same thing against a black surface (or just cover up the camera with your finger). If you see an odd pixel (it'll be pretty obvious if it's there), then push the volume button on the camera to zoom in. If the pixel moves, then the bad pixel is on the camera sensor. If the pixel doesn't move, the bad pixel is on the screen. If you find a bad pixel, test it a few times to be sure before taking it in to the Verizon store. Reboot the phone a couple of times and potentially reset the phone to factory defaults and try it. (If you don't try the reset, the Verizon store will before they let you return it anyway, so save yourself a trip.)
  • Update to the latest Android version. They released Android 2.2 for the Droid X a few days ago but they haven't yet turned on the auto-update for it so you have to manually get the latest version. Go to Settings -> About Phone -> System Updates and you can get the update. The Android update fixed all the reliability issues I was seeing connecting to wireless networks and such. A lot of the features are updated and better, too. (After you update, go to the Android Market and update your Google Mail app because it's an app now, not just a feature of the Android OS.)
  • Experiment with the power management settings. Go to Settings -> Battery Manager and play around with the different settings in there. Pending on how much you use your phone, you can get some pretty horrible battery life if you don't fix things up from the defaults. I'm still playing with the settings myself or I'd give you a recommendation.
  • Switch to Swype. The Swype keyboard is way, way, way better than the default hunt-and-peck keyboard. Swype lets you basically just drag your finger around on the screen keyboard without having to push each letter and it magically knows what you were typing. Plus, it's free and already installed. Start to create a new text message (you won't actually be sending it) and hold down your finger in the text field. In the list of options that come up, select "Input Method" and then choose "Swype." You won't regret it.
  • Enable haptic feedback. With my BlackBerry I had a physical keyboard. With an on-screen keyboard you miss the physical feedback of a button press. To make up for that, the phone can do a tiny vibration when you press an on-screen key on the keyboard. That's "haptic feedback" and it's disabled by default because technically it eats your battery. It's worth turning on, though - go to Settings -> Sound and check the "Haptic feedback" box to get it.
  • Don't bother with Task Killers. In earlier Android phones there seemed to be a need to manually kill tasks running on the phone. This has hung in the air for a while, but basically the current thought is that you shouldn't be using these because it messes with the way Android deals with its own task management and can make your phone unstable. If you want more detailed information, this is a good article.
  • The Motorola widgets will make it look like your Google account is being hacked when it's not. The phone ships with a nice set of widgets you can use on your home screen to display things like your calendar or tasks. The problem is that the widgets don't talk directly to Google - instead, they ask for the calendar data (or whatever) from Motorola and then Motorola talks to Google. Next time you log into your Google Mail account through a computer, you'll get this awesome red bar at the top warning you that some unauthorized behavior has been detected. The address will be something like 69.10.176.0 (but it may not be exactly that - use your judgment). That's the calendar widget doing its thing. You can see more about it on the Motorola Owner's Forum.
  • You may have to reboot. With my BlackBerry Curve, I really never turned it off. Occasionally it would get something weird going on and I'd have to do a battery pull. With the Droid X, it's more like a computer - if I find something weird is going on or something isn't working right, I turn it off and turn it back on again. (After the Android update I've not really had to do this, but just be aware. No need to reset or battery pull or anything, just turn off and on again.)
  • Get a screen protector. I've actually had two different ones and they both have good and bad aspects. I tried the Verizon one and I liked the texture and the fact that it kept fingerprints off the screen pretty well, but it was a matte antiglare finish and reduced the sharpness of the screen. I'm currently using a Martin Fields protector (which also has a camera protector that comes with it) and it is crystal clear, covers more of the phone's face than the Verizon one... but is a little harder to slide your finger across due to the glossy finish and definitely fingerprints up more. Either way, get a protector, especially if you thrown your phone in your bag/pocket/purse or whatever. (Right now if I had to choose, I'd go Martin Fields. It's the clearest screen and with the nice screen the Droid X has, it's a shame to mute it with antiglare. UPDATE 10/4/2010: After using the Martin Fields protector for a while, I found that the difficulty in sliding my finger caused all nature of problems including a few accidentally sent messages and emails as my finger stuck at one point on the screen and then sort of "hopped" and bumped the "send" button. The Verizon screen protectors, while antiglare, allow your finger to slide nicely on the screen, so that's what I'm using now.)
  • Pick either a phone case or the car dock, but you don't get both. They don't tell you this in the store, but it turns out the "official" car dock for the Droid X from Motorola won't work with any phone cases on the phone. Even the side of the dock box says it will, but it won't. This is a well-known issue if you troll the forums. Some people were able to get the dock to work with a case/cover on the phone by using a Dremel tool in creative ways, but I'm not into that. So decide which is worth more to you and go that way. (Note the screen protectors mentioned above won't interfere with the dock - it's only if you put a case on the phone when you'll have problems.) I went with a case since I put the phone in my pocket.
  • Don't set up all of your social media accounts through the "My Accounts" app. Or, at least, be very aware of what you're doing when you do this. If you set up, for example, Facebook through "My Accounts" rather than just installing the Facebook app from the Android Market, it starts trying to synchronize your contacts with Facebook and such. At least, it did for me. All hell breaks loose if you're trying to manage a clean list of contacts on Google and Facebook has incomplete/incorrect/unwanted information in it. Ugh.
  • Be aware of what permissions applications are asking for when you download them. When you get an app from the Android Market or wherever, it'll put up a screen telling you what permissions the app is looking for. Read that screen. If a card game is trying to get access to your contacts or make phone calls, ask yourself why it'd need that. Most apps are harmless, but there have been a few out there that have been Bad News.
  • Turn on assisted location. By default, only the GPS can provide your location but the GPS doesn't work indoors well. Go to Settings -> Location and Security and enable "Use wireless networks" and "Enable Assisted GPS" so if GPS can't locate you or isn't on, you can still get location from network triangulation. (This lets Google Maps and stuff work inside when you can't get a GPS signal.) Note that the camera app will still complain sometimes that it can't locate you. Not sure why this is.
  • Fix your notification settings. By default, just about everything notifies you of something. When GMail gets a new email it sounds a ringtone. New chat message, ringtone. Each app generally has the ability to specify how you want to be notified. I turned off ringtones and vibration when emails come in but I left the little notification icon that appears at the top of the screen. For text messages I left the default notification ringtone running, but for calendar notifications I made the ringtone something shorter and quieter like a little gong because I want to be alerted, but it doesn't have to be a fanfare. Your preferences will probably differ, just be aware that they exist.
  • Understand the different volume settings. There are different volumes for incoming calls, notifications, media, in-call voice, and... I think that's it. I think. Anyway, just because you turned up the volume for one thing doesn't mean all the volumes turned up (or down). Go to Settings -> Sound and check out your volume settings.
  • Figure out how to arrange your home screens. This is actually a two-part thing. First, figure out how to add stuff to a home screen. What widgets do you have? What do they look like? How do you add a shortcut to an application so you can get to it easier? To get going, just hold your finger down on a home screen for a couple of seconds and watch what happens. There's a lot of cool stuff hidden in there that you wouldn't otherwise discover. Second, you have seven total home screens you can set up. Think of a plan for each, like a "theme" or something. For me, I made them (from left to right):
    • Settings: Settings-related shortcuts, widgets to toggle things on and off, and testing applications (GPS Test Plus and Wifi Analyzer).
    • Social and Navigation: Twitter, Facebook, Maps, Navigation, Places, and the GPS toggle widget.
    • Entertainment and Common: Games, the IMDb app, Bluetooth toggle widget (so it doesn't have to be on all the time to connect to my hands-free set), Wifi toggle widget, and detailed battery monitor widget.
    • Main Home: Calendar widget, Weather Channel widget following current location, text message shortcut, browser shortcut, GMail shortcut, GTasks shortcut.
    • Media: Slideshow widget, Camera/Camcorder app shortcuts, Pandora, Gallery, GPS toggle (camera apps use GPS for location tagging).
    • Contacts: Quick Contact widgets for people I call/mail/text the most. Like speed dial, but better.
    • Shopping: Barcode Scanner, Amazon app, Android Marketplace, etc.
  • Learn what's up in the Android world. There are some great web sites I follow that provide good information about helpful Android apps and other goings-on in the Android world. This is how I learned about the Android upgrade being available early.

From there, it's just figuring out apps, widgets, and what you want to do. It's worth taking the time to explore things. There's a lot of cool stuff the phone can do, but it's not all immediately obvious, especially if you've never had an Android phone.

Creating Playlists in Asset UPnP

I use Asset UPnP on my Windows Home Server to get my music streaming to my Xbox 360 and PS3. It's pretty sweet, it's free, and it's easy to set up. The only thing missing from it is the various playlists I have in iTunes - Asset UPnP indexes your music, but it doesn't go through iTunes or Windows Media Player, so your playlists don't come along.

I did some searching and found a forum post that addresses how to get iTunes playlists into Asset UPnP, but I figured I'd expand on it a bit and give a better walkthrough.

Two important notes before we start:

  • I was only able to get playlists to work using Asset UPnP version 3, which is currently in beta but should be released imminently. If you are trying this in version 2 or earlier, I can't guarantee it works.
  • As of version 3, playlists are a paid feature in Asset UPnP. If you want to do this, you need to register your copy of Asset for, at the time of this article, $26. I've definitely gotten my $26 worth of use out of it, so it was a no-brainer for me.

Now...

Asset UPnP understands playlists in the .M3U format. In its simplest form, that means each playlist is a text file where the path to the songs are each on one line.

Given that, there are basically two things you have to do:

  1. Get your playlists in .M3U format.
  2. Put them in a place where Asset UPnP can index them.

So let's do the first thing - get the playlists in .M3U format.

In Windows Media Player playlists are saved as .WPL files. You'll find them in your "My Music" folder. To export the playlist as .M3U...

  1. Select the playlist in Windows Media Player.
  2. Double-click that playlist so it starts playing. You need it to be the "Now Playing" list.
  3. Select File -> Save Now Playing list as...
  4. Select a location to save the playlist. If you happen to save the .M3U playlist in the same folder as the original, Windows Media Player will end up showing you two copies of the same playlist - the original .WPL list and the .M3U list. You should save it somewhere you can find later but not right in your "My Music" folder or anywhere WMP indexes.
  5. In the "Save As Type" dropdown, select "M3U Playlist."
    Save as type: M3U
  6. Click OK to save the playlist.

Now, here's the pain in the rear part of dealing with it in Windows Media Player: When WMP saves the playlist, all of the file paths in the playlist are relative to the playlist. If you look in there, you'll see a lot of stuff like "..\Aerosmith\Dude Looks Like a Lady.mp3" style paths. Unfortunately, the paths need to be absolute paths and point to the music on your Windows Home Server (or at least be relative to the Asset installation). On Windows Home Server, Asset UPnP indexes the music share at D:\shares\Music by default, so if that's where your music is, it means "..\Aerosmith\Dude Looks Like a Lady.mp3" needs to be "D:\shares\Music\Aerosmith\Dude Looks Like a Lady.mp3" - absolute paths that Asset UPnP can understand.

The lame thing is there's no way to magically do that. You're going to need to open up a text editor like Notepad2 and do some search-and-replace action. I'll not get into how to search-and-replace here; if you can't figure that out, setting up playlists is definitely beyond your capacity.

Also, if you're exporting from Windows Media Player and you have music files that have names with international characters in them, you may need to manually rename the file to have the extension ".m3u8" rather than just ".m3u" - this tells Asset to look for international characters.

In iTunes playlists are saved internally to the database, so you have to use a script to get them out. Fortunately, there's a great iTunes Export program that will do the heavy lifting.

  1. Go to the iTunes Export web site and install the application. It's very easy and takes just a few minutes.
  2. Close iTunes if you have it open. The exporter uses the XML version of the library and you want to make sure both that iTunes isn't locking that file and that the very latest has been written to disk so the exporter gets the right data.
  3. Run the iTunes exporter.
  4. Select the iTunes library XML file location.
    Select the library XML file.
  5. Wait while the application loads the iTunes library and discovers your playlists.
  6. Select the playlists that you want to export, then click "Next." (The selected playlists will turn blue.)
    Select the playlists to export.
  7. Select your various export options and click "Next." Make sure you...
    • Choose "M3U" as the playlist format.
    • Check the "Include UTF-8 BOM" and "Use Intl Extension (M3U8)" boxes. This allows you to have artist or track names that have international characters in them.
    • For "File Types" choose "All Files" since Asset UPnP will be transcoding things so they can all be understood by the target client.
    • In the "Music Folder (Prefix)" field, put the file path (relative to the Asset UPnP installation) where the music is stored on your server (this will most likely be d:\Shares\Music\) and don't forget the trailing slash. Setting that "Music Folder (Prefix)" field makes it so you don't have to do any search-and-replace later.
    • Make a note of the "Output Directory" setting because this is where the playlists will end up.
      Select export options in iTunes Export
  8. The exporter will finish and you can close it.
  9. Find the playlists you just exported and...
    1. Name the .M3U8 files the way you want to see them listed in Asset. For example, a playlist in iTunes called "I Love The 80's" will be exported as "I Love The 80_s.m3u" by the exporter and Asset will show that as "I Love The 80_s" - the filename, not the original title.
    2. Open each file and remove the comment line from the top (the line that starts with a "#").

By now you should have:

  • Your playlists in .M3U (.M3U8) format.
  • File paths in the playlists so Asset UPnP can find the music.

Now you need to put your playlists somewhere Asset can find them. I put mine in the Public share on my Windows Home Server under a folder called "Playlists" (e.g., \\myhomeserver\Public\Playlists). (Note: If you are using iTunes Export, you can make your life a lot easier by mapping a network drive to this location so you can export your playlists directly to the shared destination.)

Finally, you need to configure Asset UPnP to find the playlists you just put on the server.

  1. Open the Windows Home Server console and click "Settings."
  2. Select "Asset UPnP."
  3. In the Asset UPnP settings dialog, click the "Edit" button next to "Advanced Settings" - this will open the advanced settings dialog for Asset.
  4. In the top right corner you'll see a box marked "Audio Library." In it you should see the folder "D:\Shares\Music" listed - this is how Asset knows which folders to scan for contents. You should also see that "D:\Shares\Music" is listed as "Contains: Audio Tracks."
  5. In the "Audio Library" box, click the "[Add Folder]" link.
  6. Browse to and select the location you placed your playlists. In my case, I placed them in the Public share in a "Playlists" folder, so I selected to "D:\Shares\Public\Playlists"
  7. By default, Asset sets the folder to contain music. Click the "Contains: Audio Tracks" text next to the playlist folder and a dropdown will appear. Select "Contains: Playlists" from there.
  8. Click OK. Asset will tell you it needs to restart. That's OK. It will then rescan the library and your playlists will be included.

You now should be able to access your playlists through a suitable DLNA client. As it turns out, Xbox 360 does not support playlists, but Playstation 3 does. That's not a problem with Asset UPnP; it's a problem with the client.

Make Your DXCore Plugin Official with a ProductModule

As of 2012.1.4, the DXCore "About" box no longer displays ProductModule contents. If you're working with that version or later, don't bother with this. You won't see the results of your efforts.

Have you ever looked at the DevExpress menu in Visual Studio and selected the "About" option? There's a list in there of all the installed "products" with associated version information, a textual description, and even a graphic with the product logo:

DXCore "About" box

If you have the CR_Documentor plugin installed, you'll notice it also shows up in that box:

DXCore "About" box showing the CR_Documentor information

If you want to "make your plugin an official product" and show up in the "About" box, the way to do that is to implement a ProductModule.

Before we get into this, something to consider: You probably don't need or want to implement a ProductModule for every plugin you write. Doing this is something for larger plugins or, better still, suites of multiple plugins that get distributed as a single product. If every plugin did this, that "About" box would get pretty noisy really quick... and does everyone need to see that little hotkey plugin in the "About" box? That said, if you have a sizable plugin or a plugin suite, here's how you get into the "About" box...

This tutorial assumes your plugin(s) are all in one assembly. You may need to tweak a few things to get it to work for a multi-assembly suite, but the general principles should remain the same.

First, make sure your assembly is marked with title, version, copyright, and description attributes. We'll use these attributes to generate the text that shows up in the "About" box.

[assembly: AssemblyTitle("Product Module Demo")]
[assembly: AssemblyCopyright("Copyright © 2010 Travis Illig")]
[assembly: AssemblyDescription("Demonstration that shows how the ProductModule works to get a plugin into the About box.")]
[assembly: AssemblyVersion("1.0.0.0")]

Next, create your logo graphic. The image should be a 536 x 201 PNG image and should have your product logo as well as the name of your product. If you look at the above "About" box images, you'll see a blue gradient that has the logo and product name on top - that's what you'll be creating. Your image should include the gradient and everything - that doesn't get put in for you. To make it good, you'll probably need to take a little time with a paint program of your choice. Just put your logo on the background; the little "version" information in the top right corner gets inserted for you by the "About" box.

For convenience, here's a PNG image of the gradient background that I created and you can use to start with:

Gradient for "About" box logos

Add your logo image to your plugin project as an embedded resource. Drag it into your plugin project so it gets added in there and make sure in the properties the image is set as "Embedded Resource."

Embedded resource properties

Add a class to your project that derives from DevExpress.CodeRush.Common.ProductModule. This is where all the information for the "About" box comes from.

In your derived ProductModule, you need to define some constants:

  • The path to the embedded resource that is your product logo graphic.
  • A GUID that uniquely identifies your product. Note that there is ONE product GUID, but there may be many plugins in that product. This GUID is not the same as the plugin IDs.
  • The minimum DXCore version that your product works with. This will be used to help DXCore determine if your product is compatible with the user's installation.
  • A string with the short name of your plugin assembly ("MyPlugin.dll"). You could technically calculate this on the fly, but chances are it's not going to change much (or ever) so it's fairly safe to just hardcode it.

This will end up looking something like the following:

private const string LogoPath = "ProductModuleDemo.ProductModuleLogo.png";
private static readonly Guid ProductId = new Guid("0CB93ADC-7188-4632-B469-98D161074E48");
private static DevExpress.CodeRush.Common.Version MinEngineVersion = new DevExpress.CodeRush.Common.Version(10, 1, 6, 0);
private const string PluginAssemblyName = "ProductModuleDemo.dll";

Add a static constructor to your ProductModule to calculate some values based on the assembly. You need to calculate and store:

  • The assembly title.
  • The assembly copyright information.
  • The assembly description.
  • The assembly version, converted to a DXCore version value.

Get that information from the attributes you added to the assembly. For a ProductModule class called "About," that'll look like:

private static readonly string AssemblyTitle;
private static readonly string AssemblyCopyright;
private static readonly string AssemblyDescription;
private static readonly DevExpress.CodeRush.Common.Version AssemblyVersion;

static About()
{
  var assembly = typeof(About).Assembly;
  var version = assembly.GetName().Version;
  AssemblyVersion = new DevExpress.CodeRush.Common.Version(
    version.Major,
    version.Minor,
    version.Build,
    version.Revision,
    DevExpress.CodeRush.Common.ReleaseType.Release);
  AssemblyTitle = GetCustomAttribute<AssemblyTitleAttribute>(assembly).Title;
  AssemblyCopyright = GetCustomAttribute<AssemblyCopyrightAttribute>(assembly).Copyright;
  AssemblyDescription = GetCustomAttribute<AssemblyDescriptionAttribute>(assembly).Description;
}

private static T GetCustomAttribute<T>(Assembly asm) where T : Attribute
{
  var attributes = (T[])asm.GetCustomAttributes(typeof(T), true);
  return attributes[0];
}

In your ProductModule, override and implement the following:

  • Copyright1 property: Return the assembly copyright information.
  • Description property: Return the assembly description information.
  • ID property: Return the Product ID GUID you created.
  • MinimumEngineVersion property: Return the minimum engine version value you created.
  • ModuleType property: This indicates what kind of product you have. If it's a community/free plugin, return ModuleTypes.Free; if it's a paid product, return ModuleTypes.Full.
  • Name property: Return the assembly title information.
  • SupportedLanguages property: This property returns an array of language strings that indicate what languages your plugin is valid for. You can find these values in the "Language" dropdown on the DevExpress options menu. At the time of this writing, they are: Basic, C/C++, CSharp, HTML, JavaScript, Plain Text, and XML. 
  • Version property: Return the assembly version information.

There are other properties you can override to return additional information, but these pretty much handle the stuff that shows up in the "About" box.

Override the BuildDefenition method. The "BuildDefenition" method (yes, it is misspelled) is responsible for defining which assemblies make up your complete product. For the purposes of this tutorial it's just the one assembly, which makes it easy. For each assembly, you call the "DefinePlugIn" method and pass in the string name of the assembly (the constant string you defined earlier):

protected override void BuildDefenition()
{
  this.DefinePlugIn(PluginAssemblyName);
}

Override the GetImage method. This is the method that grabs the embedded logo image and returns it for display in the "About" box. It's a pretty simple two-line implementation where you get the embedded resource stream from your assembly and convert it to a bitmap, like this:

public override System.Drawing.Image GetImage()
{
  Assembly current = typeof(About).Assembly;
  return new System.Drawing.Bitmap(current.GetManifestResourceStream(LogoPath));
}

That's all you have to do for the ProductModule. The last thing you have to do is mark your assembly so DXCore knows to look for your ProductModule.

Add a DXCoreProductAttribute to your assembly. The DXCoreProductAttribute points to your ProductModule so the "About" box knows what to look for. Really simple:

[assembly: DXCoreProduct(typeof(ProductModuleDemo.About))]

That's it! Now fire up Visual Studio with your plugin in place and you should see your product information - with your logo, version, description, etc. - all in the DevExpress "About" box.

I've got a solution you can download with a working demo in it so you can see what the complete package looks like:

[ProductModuleDemo.zip (11KB)]

Hopefully this will help you larger plugin developers to make some really cool "official" DXCore products!

CR_Documentor 2.5.0.0 Released

It's been a while in the making, but the new version of CR_Documentor is out.

It took a while because I did two pretty major updates to it.

First, I totally overhauled the syntax preview generation so each preview style (NDoc or Sandcastle) uses the same syntax preview engine. As part of that, I added a bunch more testing and support for complex syntax like multiple type parameters with multiple type constraints per parameter. What? What does that mean? It means you can see stuff like this in your preview:

And, of course, it works in VB, too (which, based on the way Sandcastle does it, actually all ends up on one line...):

The other thing I did was add support for serving images and other files, so now when you look at the preview for a class and see all the members listed, you see the associated icons, too. Not a huge deal, but it does make the preview more authentic.

Hopefully that adds to you documentation preview enjoyment.

As always, it's free. Go get it!

Saturday at the Aquarium

Every year for Jenn's birthday we take a trip to the beach with some friends of ours. This year we decided to go down to the Oregon Coast Aquarium in Newport.

I took several pictures that I'll have to post later, but I did get a nice video of the Passages of the Deep exhibit where you walk under the various fish. This particular video shows the sharks in the exhibit.

Technology Trust Issues

I know technology is fallible and I know my standards are probably far too high for things, but I find that once a technology or gadget has shown its imperfections to me by way of failing or misbehaving, I have a really difficult time being excited about it or trusting it again.

For quite some time I was absolutely addicted to playing drums on Rock Band. I've always thought I would be a decent drummer and while I know it's not "real drums" it's fun and fulfills that tiny dream. I bought the Ion Drum Rocker kit and totally rocked out. Until, of course, I found a problem during practice mode where hitting the yellow cymbal changes the tempo on you. After switching out the drum kit controller like three times with Ion Support (which, by the way, sucks), it turns out the problem is software-based. I also started noticing things start randomly misbehaving, like the kick pedal not registering (or going off by itself), hits not registering on the pads... and that turns out to be a funky combination of static buildup, needing to unplug the drum controller for a few seconds, and bad luck.

During the course of solving that problem, I honestly lost my feel for it. I don't play nearly as often now, and it's because I don't trust the technology to behave. To do what it's intended to do. Playing it has become a bit less fun and a bit more worry and stress over why it's not working.

Last week I got a Droid X. Love it. Had a bit of a weird issue where the speakers suddenly lost volume but fixed it by a simple power cycle. Then we went to the Oregon Coast Aquarium this past weekend and I noticed that there's a flaw with the camera CMOS censor such that in darker shots there's a noticeable magenta spot, like there's something on the lens. Suddenly, I'm slightly less trusting, and slightly less enamored with it. I still like the phone, but I find I'm not tinkering with it or messing around with it as much since I saw that.

I stopped at the Verizon store and I'm getting a replacement unit, so it should be fixed when the new unit arrives in a day or two. It's just... I hope I don't lose my passion for it. My enthusiasm. It's shown me weakness, fallibility, and it's going to take some time for me to trust it again.

I am, admittedly, a perfectionist. I hold myself to very high standards and "it works" is generally not good enough. I'm thinking, though, that even if "it works" is good enough, there's another question to be asked: is it trustworthy? Can I trust a product or service not to break in the middle of an operation? Even if a product isn't super-feature-rich, if it does one thing and one thing really well, I'm fine with that.

Reliability is high on my priority list. Is it high on yours?