Wednesday, October 25, 2006

I had the distinct privilege of presenting on Refactoring at the Utah County .NET User Group tonight.  We had a great turnout and I'm fairly pleased with the presentation as a whole - I feel it went quite smoothly.  In past months the group had met at UVSC, but they're now in the process of moving to another location: NuSkin in Provo.  We met at their office off of EastBay.

The atmosphere was fantastic and there was great feedback and I believe that it worked out being beneficial for all in attendance (myself included).

I gleaned some talking points from an MSDN WebCast on Refactoring (as well as some demonstrations), but I believe it was all for the better.  Additionally, I used the Movie Rentals example from Martin Fowler's book to drive home the points made throughout the talk.

I've made the files (the PPT, the 'before refactoring' code, and 'after refactoring' code) available for download if you'd like to play with them.

Thanks to all that attended and for your feedback.  I look forward to the next time I have the opportunity!

Wednesday, October 25, 2006 2:53:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, October 24, 2006

Please join me tomorrow evening (Wednesday, October 25th, 2006) at 6:00 PM with the Utah County .NET User Group.  I have the privilege of speaking and sharing my thoughts on Refactoring.

In the event that you've been to the UCNUG meetings in the past, be forewarned that the meeting location has moved.  No longer at UVSC, the meetings will now be hosted by NuSkin (which makes the drive a little longer for me) at

NuSkin Network Operations Center (NOC)
1175 South 350 East
Provo, Utah 84606

Note, this is NOT the large building in downtown Provo but is rather in EastBay.  You can get to it by going to the south most Universty Avenue exit in Provo.

Hope to see you there!

Tuesday, October 24, 2006 3:03:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, October 23, 2006

This might be useful to someone out there.  I had had this issue many months ago, but had to resolve it again today because I hadn't jotted down the solution - fortunately it only took about 2 minutes.

I am making use of the FolderBrowserDialog class in the .NET 2.0 Framework.  This class, as it's name implies, provides a graphical interface for browsing and selecting folders.

The issue was that when i made my call to .ShowDialog(), the dialog would appear but it was blank - only the 'Make New Folder', 'OK', and 'Cancel' buttons along with the description were visible, but the folder TreeView was not.  This would have worked from the get-go had a created my project as a Windows Forms project but I didn't; it's a Console application.

To solve the problem, I simply had to add the [STAThread()] to my Main() method - now it works like a charm.

[STAThread()]
public static void Main() {
   Application.EnableVisualStyles();
   Application.SetCompatibleTextRenderingDefault(false);
   Application.Run(new TestForm());
}

// ...then on the TestForm class

private void btnBrowseForFolder_Click(object sender, EventArgs e) {
   string folderPath = browseForFolder();
   // do something with the result
}

private string browseForFolder() {
   using ( FolderBrowserDialog dlg = new FolderBrowserDialog() ) {
      dlg.Description = "Select a folder";
      dlg.ShowNewFolderButton = true;
      dlg.RootFolder = Environment.SpecialFolder.MyComputer;
      return ( DialogResult.OK == dlg.ShowDialog(this) )
         ? dlg.SelectedPath
         : null;
   }
}

Monday, October 23, 2006 5:50:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [8]  |  Trackback
 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