Sunday, October 22, 2006

I was reminded at the Code Camp that I hadn't posted a little application that I wrote to facilitate the creation and testing of regular expressions.  There are many tools out there that are downloadable that provide this functionality, but I found it easier to talk about regular expressions from an instructional standpoint with my own tool and demonstrations.

I therefore set out to create such an application and it's freely downloadable here.  Essentially, the program allows you to create regular expressions and test them against some text/file of your choosing.  You can also save off a collection of regular expressions to file so that you can create your own library of expressions.  If you attended the User Group meeting you'll find that I've enhanced the UI slightly to make it more useful and instructional.

NOTE: The download is the source code and requires the .NET Framework 2.0 to work properly.

Enjoy!

Sunday, October 22, 2006 8:29:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

For those interested, I've cleaned up and posted the code that I created that Utah Code Camp 2006 as a download right off of the blog.  Feel free to get it and enjoy!  I had a good time creating it.

So there you go!

Sunday, October 22, 2006 3:29:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

At the code camp yesterday I was approached with a PInvoke question on how to handle a cross-unmanaged/managed function callback.  Back in my Win32 days (which is now some years on the past of doing native Win32 programming on a daily basis) this was common place, but I've not had this need in the .NET world - though the need does exist, as demonstrated by this gentleman's circumstances.

I took the task of figuring it out right there and quickly came up with this example that illustrates the technique that I took.

This example uses the frequently illustrated Win32 function EnumChildWindows to enumerate the child windows of a given window (e.g. controls on a form).  Sure, you can accomplish this by simply enumerating the .Controls collection on the form, but that's not what we're illustrating here - we want to do it via Win32 and a function callback.

The EnumChildWindows function accepts as a parameter a function pointer which will be called-back by the Win32 function once for each window found.  Once the callback returns FALSE (i.e. zero) the enumeration stops.

Setting up this function in managed code is trivial:

[SuppressUnmanagedCodeSecurity()]
private static class NativeMethods {
   internal delegate int EnumChildProc(IntPtr hWnd, IntPtr lParam);

   [DllImport("user32.dll")]
   internal static extern int EnumChildWindows(
         IntPtr hWnd,
         [MarshalAs(UnmanagedType.FunctionPtr)] EnumChildProc fn,
         IntPtr lParam);
}

Notice that in order to make the callback work I have to decorate the function callback parameter with the [MarshalAsAttribute] designating that as a FunctionPtr.

To test this functionality I created a simple form, added some controls (including a ListBox and Button).  I then named the button btnEnum and the ListBox lstOutput.  Then I wrote a little code in the Click event handler to call the unmanaged function, providing it with a callback function (via my delegate instance).  The callback function resolves the hWnd (window handle) of the window to the control and outputs the control name to the list box as follows:

private void btnEnum_Click(object sender, EventArgs e) {
   lstOutput.Items.Clear();
   NativeMethods.EnumChildWindows(this.Handle, enumChildren, IntPtr.Zero);
}

private int enumChildren(IntPtr hWnd, IntPtr lParam) {
   Control ctrl = Control.FromChildHandle(hWnd);
   lstOutput.Items.Add(ctrl.Name);
   return 1;   // indicate that we want to continue enumerating until we reach the end
}

That's about it...there's not much to it :)

Sunday, October 22, 2006 2:53:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, October 21, 2006

Today marked the day of the inaugural Utah Code Camp.  Brainchild of Pat Wright, the event was a great success.  From the beginning our goal was to have about 100 people in attendance, but despite having just around 90 registrants, only about 40-45 showed (I don't know the number accurately and am only guessing here).  Regardless, we all had a great time.

We had three tracks resulting in 15 presentations throughout the day from various volunteers and participants.  For instance, I had the opportunity to provide the keynote presentation (which in reality was little more than a 'welcome, this is how you get to the bathrooms when you need to go' presentation) and a talk on developing custom WinForms components.  We delved into the innards of using Designers, Editors, and Extenders and (I believe) everyone had a great time.

Other presentations included topics on SQL Server Worst Practices, some XNA stuff, a presentation on DirectX, Test Driven Development using NUnit, NHibernate 1.2.0, Client/Server application development, and more.

I haven't had a chance to see the results of the reviews but it sure seemed like everyone had a great time; it was very well received.  We're working on putting another one together in 6-8 months again and will undoubtedly be looking for speakers - we'd love to have more!

A fun way to spend a Saturday!

Saturday, October 21, 2006 4:50:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Friday, October 20, 2006

As a last minute reminder, the Utah Code Camp is tomorrow at Neumont University (10701 South River Front Parkway, South Jordan, Utah).  The event starts at 8:00 AM and runs to 5:00 PM.  This should be a fantastic event!  If you have not registered, please do and show up - you'll not want to miss it.

Friday, October 20, 2006 3:08:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, October 19, 2006

I have a web application that for one reason or another I'm currently unable to utilize AJAX to enable a nice, seamless, and seemingly postbackless experience.  I've maintained this particular application for several years now and it has a lot of AJAX-y like behaviors, but much of it feels like a hack and is somewhat unwieldy.  This particular application is (currently) specific to IE 6.0+.

I'm not going to wax too technical here since I want to keep this really light, but since IE 5.0 Microsoft has made a nice little COM object called Microsoft.XMLHTTP that allows a developer to submit http requests to a server and act on the results.  This is quite easily accomplished via Javascript on the client, as the following code demonstrates:

var http = new ActiveXObject("Microsoft.XMLHTTP");
http.onreadystatechange = function() {
   if ( 4 == http.readyState ) {
      // process the resulting response
      alert(http.responseText);
   }
};
http.open("POST", "http://someurl/here", true);
http.send("");

There's really nothing too it - and there's tons out there online that illustrate how to do this and I'll leave it to you to research it if you need to.  The above code, however, leaves something to be desired:  the way it's structured, I cannot reuse the XMLHTTP object - well, technically, I can, but my onreadystatechange event won't fire the second time.  I don't want to have to recreate an XMLHTTP instance for each and every request - I want to reuse the instance I already have.

This is easily solved by setting the onreadystatechange event after the call to the .open() method as such:

var http = new ActiveXObject("Microsoft.XMLHTTP");

function post(request) {
   http.open("POST", "http://someurl/here", true);
   http.onreadystatechange = function() {
      if ( 4 == http.readyState ) {
         // process the resulting response
         alert(http.responseText);
      }
   };
   http.send(request);
}

Now I've isolated the request portion into a method that I can call repeatedly and act on the results accordingly.

Simple.

Thursday, October 19, 2006 7:54:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, October 16, 2006

I'm back now from a small and much needed hiatus.  We've been cranking on getting the next version of our product configurator code complete for the next version.  It's gonna rock and knock people's socks off - and it's only getting better.

I've been out of email/cell phone contact since Wednesday afternoon last week except intermittently having taken the family to Disneyland.  Oh what fun that was.  It actually felt good to completely take my mind off of things and not focus.  Now that I'm back I feel completely rejuvenated (despite being a little tired) and ready to rock.

I'll be posting more soon.

Monday, October 16, 2006 4:58:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, October 11, 2006

I would be remiss were I to not post this announcement:

Join us on Saturday, October 21st for Utah Code Camp!

The local .NET Users Group and SQL Server Users Group is conducting a "Code Camp" for local software programmers next month at Neumont University.  The code camp follows the Code Camp manifesto that it is for the community by the community and always free.  We are looking forward to excellent sessions on lots of different topics.

The event is scheduled from 8:00 AM to 5:00 PM. The conference is free, however we request that you please register at www.msutahevents.com and enroll for the event so that we can get as accurate a head count as possible.

We will have sessions for both Developers and DBA's. We will also have a Sponsors area with lots of giveaways!

If you would like to speak or are interested in speaking, please email Pat Wright at pat_wright@sqlpass.org - visit www.msutahevents.com for more information.

Please register and join us for what should be an exciting and fun day!

Wednesday, October 11, 2006 1:43:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, October 04, 2006

The PropertyGrid control that is provided with Visual Studio, while not the most powerful of controls, provides some pretty awesome functionality.  In a nutshell it permits you to bind an object to it via a .SelectedObject property.  The PropertyGrid will then, via reflection, discover properties on your object and display them for your viewing/editing pleasure.  In doing so, you can provide users of your applications with a UX (user experience) similar to what you would receive within Visual Studio's design time.

Doing this binding is trivial and quite enjoyable actually.

The PropertyGrid also allows you to further extend the design experience with UITypeEditor-derived types.  These types can provide custom dropdowns or popup dialogs that give you the ability to offer the user a rich experience in setting property values.  Often times these are used when a property value is more complex than a simple value (e.g. collection management, graphical color selections, etc).  These, too, are a lot of fun and quite easy to create.

If a property on your bound object is another non-simple type (such as a Customer), the PropertyGrid won't know how to represent the data and will simply call .ToString() on the property, thereby returning the class name.  This is usually not the desired behavior.  Perhaps you want to display some more palatable text or a particular property of the object.  This can easily be accomplished through a mechanism known as a TypeConverter.

A TypeConverter-based class provides a consistent manner of converting an object of one type to another.  Via the TypeConverterAttribute class, you can designate the TypeConverter-type to use to represent your property as in the following example.  Suppose that a Customer object is a property on some other object (such as an Order) that is bound to the PropertyGrid.

namespace Devstone.Samples.Objects {

   public sealed class Order {
      private Customer _customer;

      public Customer Customer {
         get { return _customer; }
         set { _customer = value; }
      }
   }


   [TypeConverter(typeof(CustomerConverter)]
   public sealed class Customer {
      //... additional code here
   }


   internal sealed class CustomerConverter : TypeConverter {
      public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
         if ( destinationType == typeof(string) && value is Customer ) {
            // NOTE: we could simply cast value to Customer and return a string consisting
            // of property values if we chose to do so.
            // for simplicity sake, however, we'll return just some basic text.

            return "(Customer)";
         }
         else {
            return base.ConvertTo(context, culture, value, destinationType);
         }
      }
   }

}

Now, rather than 'Devstone.Samples.Objects.Customer' showing up as the value for the Customer property, we have the nicer '(Customer)' value.

This particular example is very straightforward and simple.  Tomorrow, I'll follow up with a more complex and robust example that takes the PropertyGrid and extends it further by dynamically creating properties on the fly that represent actual properties on the constituent objects.  This gives us the ability to view and edit hierarchical information directly within the PropertyGrid. :)  It's cool stuff.

Wednesday, October 04, 2006 6:13:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback