Monday, June 28, 2004

As a courtesy to developers out there, I'd like to remind all who write and develop Windows applications to take the time to position your windows (forms) properly on the screen.  Not all users have their taskbar on the bottom on the screen.  I am constantly annoyed by applications that assume that 0,0 is the upper left corner of the screen and that it's a safe place to position your windows - especially because I like my task bar along the left side and toolbars across the top.  This configuration is, to me, extremely productive especially with a widescreen monitor.

The list of applications that don't position themselves correctly is too long to mention, but some tools that I quite frequently use (almost daily) are ILDASM and Virtual PC.  ILDASM has the annoying nuance in that it always starts in the upperleft corner of the screen (0,0) so the entire titlebar always appears (or rather doesn't appear) completely obscured beneath the taskbar/toolbars - thank goodness for the ALT key and system menus.  Virtual PC never quite stays in the same place, creeping towards 0,0 each time you open it.

It's not hard to get it right.  If your application requires manual placement of the form you simply need to call Screen.GetWorkingArea([form variable]) to get the screen on which (the majority of) your form is positioned.  Then you can do a little magic otherwise known as basic math and you have it.

The following example identifies how to do this:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WorkingAreaTest {
   public sealed class EntryPoint {

      [STAThread()]
      public static void Main() {
         Form f = new Form();
         f.StartPosition = FormStartPosition.Manual;
         Rectangle rct = Screen.PrimaryScreen.WorkingArea;
         // you could also call Screen.GetWorkingArea(f)
   
         // to center the form on the screen
         // by bitshifting to divide by 2, we get two benefits:
         // 1) improved performance (negligible here)
         // 2) we don't need to cast the result to an int

         f.Location = new Point(
            (rct.Left + (rct.Width >> 1) - (f.Width >> 1)),
            (rct.Top + (rct.Height >> 1) - (f.Height >> 1)));

         // to position the form on the upperleft corner of the screen
         f.Location = new Point(rct.Left, rct.Top);

         // show the form and get the application running
         Application.Run(f);
      }
   }
}

If you're programming a traditional Windows applications (non-.NET), you can use the SystemParametersInfo() function passing in SPI_GETWORKAREA.

RECT rct;
BOOL ret = SystemParametersInfo(SPI_GETWORKAREA, 0, &rct, 0);

Well, there you go, not much too it at all...and your users will thank you for it, or maybe they'll use your program and never notice you did thim this courtesy - and that's the best praise one could receive.  Believe me, they'll notice if you don't.

Monday, June 28, 2004 3:50:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Sunday, June 27, 2004

This is pretty common and straightforward (and quite elementary), but can be a gotcha if you're new to software development so I figured it'd be worth blogging about.

When you're assembling your applications you'll be invariably presented with the quandary of whether you should use a struct or a class to represent your data.  This choice isn't often cut and dry.  While in many respects they are semantically similar, there are some distinctions that should be known.

First and foremost, perhaps, is how they are allocated in memory.  Structs, by nature, are ValueType objects and are loaded onto the application's stack.  Class instances, on the other hand reference types and are heap-allocated.  A nicety of stack-allocated objects is that they are automatically taken care of when a procedure finishes (unless you move the object to the heap).  They are more deterministic in that respect.  Memory, however, is finite, and the stack is much smaller than the heap so you're limited to how many objects you can load onto it.  Stack allocations are faster than heap allocations as well, though the .NET runtime has some advanced memory assignment and allocation algorithms that make heap allocations nearly (almost imperceptively) as fast as stack allocations.  Okay, enough about that.

There are some other marked differences between the two:

Constructors:  In a struct you can define constructors, but the constructors be parameterized; you cannot create a parameterless constructor as you can with a class.

Fields:  Within a struct you can define fields, but initialization of the field's value in the declaration is not acceptable.  An exception to this is that static fields can be initialized.

As a parameter:  Another important distinction between the two is their behavior when passed as a parameter to a method.  When you pass a struct, it is passed by value (that is, it's copied) whereas a class instance is passed by reference (the reference is copied - not the object).  This has some far-reaching implications.  Suppose you have the following scenario, ignoring the fact that a similar struct may already exist in the .NET framework (it's just for illustration purposes):

struct Coords {
   public int x;
   public int y;

   public Coords(int xCoord, int yCoord) {
      x = xCoord;
      y = yCoord;
   }
}

public static void Main() {
   Coords pt = new Coords(10, 10);
   movePt(pt, 5, 3);
   // what is the value of pt.x and pt.y here?
}

private static movePt(Coords pt, int xOffset, int yOffset) {
   pt.x += xOffset;
   pt.y += yOffset;
}

When you call movePt() pt is copied so the method is affecting a different pt than the one passed in (though the values are the same).  Now, this may be exactly the functionality you want, but then again it might not.  Sure you can solve your problem by making the parameter a ref parameter, but that's another story, and it might impose some discipline upon the caller.

Interfaces:  Ok, now this is potentially a bit more confusing for the novice, but here goes.  Structs, just like classes, can implement interfaces.  This adds a twist to the ValueType / reference type relationship.  When you cast a struct to its interface, the struct is boxed; it is copied up to the managed heap.  Changes made to it through the interface affect the boxed copy.  The struct is never unboxed back to the struct (unless you explicitly unbox it).  Let's see this in action (Okay, okay, I know the names are stupid, but hey, it's all off the cuff):

interface IIncrementer {
   void AddValue(int value);
}

struct IntWrapper : IIncrementer {
   private int _value;

   public IntWrapper(int value) {
      _value = value;
   }

   void IIncrementer.AddValue(int value) {
      _value += value;
   }

   public int Value {
      get { return _value; }
   }
}

public sealed class EntryPoint {
   public static void Main() {
      IntWrapper iw = new IntWrapper(5);   // the initial value is 5
      ((IIncrementer)iw).AddValue(3);      // the value of iw is still 5!  the
                                           // change to the value happened on the
                                           // heap copy and was immediately
                                           // discarded!

      // box and unbox example:
      IIncrementer iiw = (IIncrementer)iw; // box it and obtain a reference
      iiw.AddValue(4);                     // increment the boxed copy
      iw = (IntWrapper)iiw;                // unbox it, replacing the stack copy.
                                           // the value is now 9!
   }
}

Personally, I find the class model (vs the struct model) much more intuitive and welcoming, but structs definitely have their place - I use them all the time.  When it comes down to it, though, I think that one of the interesting characteristics of structs is that they have meaning or state in their default, unitialized form.  That is, the default state of a struct must have some intuitiveness upon creation (you can't control it's default constructor, nor can you deny someone from creating an instance without parameters).  You don't want someone creating an instance of your struct and calling a method or referencing a field/property and having it throw.  This is where classes and their constructors come in really handy.

Pretty much everything mentioned above focuses on structs that have ValueType members.  The playing field changes a little if you a struct that has reference types (such as Strings or other objects) internally as those are heap allocated objects maintained within a ValueType - now your struct isn't quite as deterministic.

Enjoy!

Sunday, June 27, 2004 6:33:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [7]  |  Trackback
 Thursday, June 24, 2004

Well, a lot of things have been going on in my life lately, but not much to blog about.  I've been swamped at work and at home, but I hope to be back at the blogging machine from now on.

Over the last several weeks, I have decided to make some changes in my life and career that will have longlasting and (hopefully) beneficial effect on my family.  Yesterday was my last day with my previous employer and I've moved on to be an independent consultant.  This change means that I will be able to spend more time with my family (which is always a bonus) as well as work from home.  I will also be able to spend more time devoted to things that I have been slacking on over the years.

Leaving a steady job and income to the wild unknown is not something that I take lightly.  It was in many respects a very difficult decision to make and I left behind a lot of what I worked for over the years - though it could be said that all that I worked for over the years has led me to this.

Here's to new beginnings and a prosperous future!

Thursday, June 24, 2004 4:38:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, June 18, 2004

As developers we're constantly faced with the need to crank out good quality code.  This isn't often the easiest task, especially with the mounting need to stay at the forefront of technology.  Visual Studio, while a powerhouse development environment, can only offer so much.  Here is a great list of tools that should be a part of every developer's toolkit.  These tools will aid in the generation of good, quality code and keep the productivity high.  Additionally, Scott Hanselman has his Ultimate Developer and Power Users Tools List, a recommended set of tools that all developers must know how to use.

Of these tools, I have loads of firsthand experience with NDoc (love it!) and FxCop (currently version 1.3) and the Regulator.  I've played with several others.

Some other tools that I really find useful and enjoy are:

Aaron Skonnard's XML Tools

The VS.NET Command Prompt (invaluable - I moved this shortcut to my Start Menu for quick access)

ISO Recorder - invaluable tool for creating images of your CDs

Notepad 2 - A very capable replacement for the boring, ordinary Notepad...try it out! it's awesome!

UltraMagnifier - Excellent tool for giving presentations

What tools do you use?

Friday, June 18, 2004 4:06:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, June 17, 2004

Designing applications can be a daunting task.  Even the simplest of utilities can present obstacles and issues unforeseen.  Enterprise-level, distributed applications present problems on a greater scale: security (authentication and authorization), distributed transactional support, object pooling, JIT, just to name a few.  Trying to roll your own infrastructure to support these features reliably is extrememly difficult - go ahead and try.  I think every developer has tried to implement some of these features at least to some degree.  But trying to harness all of these capabilities, especially when they already exist, is asinine and a fool's quest.

Over the past several months, I have been asked repetitively by various individuals (both coworkers as well as friends and associates) whether COM+ is a thing of the past.  I've been told that Microsoft is no longer investing in COM+ services and that it's been deprecated; that Enterprise Services (aka COM+ in the .NET world) is just a COM-interop layer over the actual COM+ implementation provided by the OS.  These statements couldn't be further from the truth.  Enterprise Services is alive and kicking.

As Brian Noyes points out in his blog post, there are a lot of misconceptions about the positioning of Enterprise Services with respect to developing solutions with .NET.  It is frequently viewed as a thing of the past and therefore legacy software that doesn't really have a place in modern software development.  When Microsoft developed COM+ (which, in its inception was Microsoft Transation Server (MTS) and part of the Windows NT 4.0 Option Pack) they were very forward-looking and to their credit succeeded admirably.  If you take the time to read Microsoft's Prescriptive Architecture Guidance (PAG), you'll see that even today in the building of distributed, n-tier applications we are encouraged to use Enterprise Services.

One of the reasons I've heard that discourages its use is the whole COM-interop thing.  There are really two ways in which a COM+ application can run: as a Library application or a Server application.

When a component is a Library application, it runs in-process with the caller.  If you've developed your COM+ component in .NET there is no interop at all.  All calls to your COM+ component are direct, managed C++ calls to the subsystem - this will be very fast, just involving a context switch.

When a component is a Server application, then yes, COM-interop enters the picture.  A Runtime Callable Wrapper (RCW) is created.  It is through this proxy that calls to the object occur.  All in all, this overhead is minimal especially when compared to what the actual function will probably be doing.

With respect to the future, however, is COM+ going away?  Is Microsoft abandoning their flagship component server?  I think not.  When you look at what is up and coming such as Indigo it might appear that COM+ is going by the wayside, in preference to this newer technology.  In fact, COM+ is being enhanced to support calls to an from Indigo for a seamless interoperation in the Longhorn timeframe.

Basically, when it comes down to it, we are still being encouraged to use Enterprise Services in the back-end as the service provider for our applications, inside the service boundaries.  Usually, the recommendation is that the service boundary be actually implemented via another mechanism such as Web Services (eg: ASMX, WSE).

Enterprise Services offer many other benefits that I haven't mentioned here, but I believe that many developers are afraid to embrace the technology for fear of the complexity and breadth of its coverage.  Sure, COM+ can be a bit daunting.  It isn't simple, but as developers it is our responsibility to learn about the various technologies and apply them where they best fit.  I'm convinced that by using COM+ properly our applications will be better prepared for the today as well as for the future.

A few months ago I had the privilege of presenting a talk to our local .NET User Group regarding component development in COM+.  Check out the presentation.

---
Update 06/17/2004:

Some helpful COM+/Enterprise Services links:

GotDotNet COM+ FAQ
DCOM deserves our respect
.NET Enterprise Services Performance
Enterprise Architecturing II

Thursday, June 17, 2004 7:05:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, June 16, 2004

As a seasoned component developer I was a bit disappointed when I first made the move to .NET with respect to (really only) one thing:  the ability to scope the property getters and setters individually.  Back in the good ol' VB 6.0 and C++ days, it was common practice to create a property that was readonly externally and public internally to the application.  This simplified semantics and the programming model was simpler.  However, when I came into .NET I found abruptly that I would have to create a readonly property and then a separate accessor function to set the value of the property internally:

public int Age {
   get { return _age; }
}

internal void setAge(int value) {
   _age = value;
}

I am very excited to learn that in the Whidbey (Visual Studio 5.0) timeframe we'll get scoped property accessors.  Now the syntax would be like the following:

public int Age {
   get { return _age; }
   internal set { _age = value; }
}

As Eric Porter reminds us, this is not just a C# feature, but you'll be able to do the same thing in VB.NET:

Public Property Age() As Integer
   Get
      Return _age
   End Get
   Friend Set(ByVal Value As Integer)
      _age = Value
   End Set
End Property

I can't wait for this enhancement!

Wednesday, June 16, 2004 5:09:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Yesterday I received my new laptop.  It's a new Dell Inspiron 8600.  I must say that so far I am impressed.  It's a blazing Pentium M 755 (2.0 Ghz) with 2GB of RAM.  With the WUXGA (1920x1200 res), 60 GB 7200 RPM hard drive, and the DVD+R/RW I am loving it!  I'm still in the process of setting it up, but I'm very excited.

As a matter of habit, the first thing I do when I get a new computer (PC or otherwise) is blow away the OS (archiving drivers of course) and install anew.  At first I wanted to use Windows Server 2003.  It installed flawlessly; that is, until I got to the video driver.  The video driver installed ok but upon reboot it incessantly blue screened.  It was frustrating to not find a Win2k3-compatible video driver on the Dell site.  I was forced to fall back to Windows XP, which I enjoy as well, but I would have preferred Win2k3...oh well...no worries.

Wednesday, June 16, 2004 3:34:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, June 15, 2004

Sorry for a non-technical post, but I just wanted to get this off my chest.

Being from Salt Lake City, Utah, this may sound like I'm turning on my own family, but believe me I'm not.  Pretty much all of the people I know didn't want the Los Angeles Lakers to win the NBA Championship.  It's not because we're anti-Lakers.  In fact, were it anything else, I wouldn't have minded at all if the Lakers had won - I've always been a fan.  Everyone is anti-Malone (Karl Malone).

Aside from being a constant whiner and complainer, Malone is a lousy human being.  I know - I've met him so my bias isn't all based on second-hand sources.  I think it's hilarious that he left the Utah Jazz for the Lakers (even accepting a cut in pay - amazing!) as a perceived guarantee to winning the championship.  That's pretty selfish if you ask me, especially for man who admittedly has no ego...at least I think that's what he said; it was hard to understand him due to his inability to speak intelligently.  Additionally, after being one of the key reasons that the Jazz didn't win the Championship when they had the chance, he was pretty much a non-factor to the Lakers and didn't help the team at all through the Championship series.

I am so glad he didn't get his championship.  Evil, I know.

Tuesday, June 15, 2004 3:25:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Upon reading this post by Martin Spedding, I got to thinking about where Microsoft Visual Studio fits into the scheme of things.  Martin argues that Visual Studio leads developers down the seductive and misleading path of least resistance in application development.  For instance he mentions that Visual Studio will place the app's public void Main() within the WinForm application's Form1.  I agree that this is a particularly nasty practice and I agree with him that it is poor design, but that is in no way the fault of Visual Studio.

First and foremost, this practice begins to combine application startup code with the WinForm, which may (and arguably should be) completely independent of one another.  This mentality hearkens back to the Visual Basic days in which the app's startup object could be a form vs. a Main() procedure.  This can be pretty nasty because if you remove your form file to create a more appropriately named form (which I am very inclined to do), you lose your application's startup code.

Ok, that aside, I don't believe that it is the role of Visual Studio to enforce a layering separation in our code.  Visual Studio is an editor.  It's an IDE.  It offers functionality as defined and prescribed in the language engines (such as syntax coloring, intellisense, and much more).  It's an immersive experience to work in Visual Studio because it brings so much together, but it shouldn't be telling me how to write my code.  When it comes down to it, the problem with the aforementioned non-separation of code isn't the fault of Visual Studio at all...it's all in the template files that it uses to create a new project.  If anything those should be fixed.

I firmly believe that the layering approach to application development is the right way to design and develop applications for a lot of reasons.  Developers should be taught and nurtured with best practices, but that's not the responsibility of the IDE...fix the templates.

If anyone is interested, I've updated all of the scripts, html files, and template .cs files that VS uses that helps promote best practices and eliminates unnecessary dependencies (such as System.Data and System.Xml which I don't use unless I need to).  Saves a few clicks whenever I start a new project.  Just let me know!

Tuesday, June 15, 2004 8:54:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Monday, June 14, 2004
I'm excited to welcome my good friend Jason Walker into the world of Devstone Software.  Jason brings lots of programming ability to the table and we're excited to have him as a member of the team!  In the coming days/weeks we'll get Jason up to speed on the various Devstone applications, games, utilities, etc and we'll get crankin' on some code.
Monday, June 14, 2004 5:59:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback

Well, I know this might be difficult for some people to hear.  In fact, some might find it appalling.  I like Visual Sourcesafe.  Yes, I have had my issues with it in the past and there are some, ok, many things that beg to be improved, but for the most part it has served me well and has done a fairly good job of maintaining my source code.

Tonight, however, I ran into an issue that was driving me nuts.  I was attempting to add a user to my SS server and it would repeatedly fail with an 'Invalid DOS path: C:\...\users' error.  In fact, it would go so far as to create the user's directory, but that was it.  It was supposed to also create a ss.ini file within the folder.  At first I thought it was a permissions error (but that didn't make sense because it was creating the directory in the first place AND I was logged in as an Administrator on the box).

After a bit of searching online, I found a link to http://support.microsoft.com/?id=149378 wherein I discovered that I was missing a file named 'Template.ini'.  Upon creating this file, everything worked peachy.  The question I have now is this: How did I come to be missing this file when I've created users in the past?

I wish SourceSafe had some built-in mechanisms for recovery and error handling that actually explained the error, it would save us lots of time on the diagnosing the problem.

Monday, June 14, 2004 5:56:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [8]  |  Trackback
 Friday, June 11, 2004

Last night's .NET User Group meeting was pretty awesome.  A great friend of mine from Microsoft, Matt Smith, gave us a presentation on the new and upcoming version of Visual Studio called Visual Studio Team System (VSTS); it is code-named “Burton“.  This product was officially unveiled at TechEd so this was a great presentation for those of us that didn't get a chance to attend TechEd.

VSTS rocks!  What I really liked about VSTS is what it's name implies: Team.  It is very heartening to see that MS is making great strides and in-roads into placing the software development process into its flagship development environment.  VSTS encompasses the entire gamut of application development - from the initial concept and envisioning stages all the way through design, development, and testing, to deployment and maintenance.  One very cool aspect is that you can define an application development methodology (such as MSF) and incorporate that directly into how you interact with Visual Studio.  The methodologies are extensible as well so you can even create your own, in-house methodologies.

VSTS seems to really drive home the concept that the team is an integrated, cohesive unit.  I absolutely loved the integration with SharePoint and I feel this will even further enhance the sharing of information across the team.

The things built into VSTS are not all revolutionary - some have existed in other forms and in other tools, but it does offer them in a completely integrated, end-to-end offering which is very exciting.

These are a few of my favorite capabilities built-in (in no particular order):

  • Integrated Source Control - the new source code control system (written from the ground up) leverages SQL Server as its back-end data store.  This eases backups as well as makes the data universally more accessible.  Plus when creating a new project in VSTS you start out integrated with the source control system with a new branch.
  • SharePoint - when creating a new project you can immediately create a SharePoint team site.  This is fantastic because all team members can automatically see schedules, tasks, and deliverables and share information and documents with each other.  If you haven't had a chance to work with SPS, do!
  • Tasks - members of the team can associate tasks (or be assiged tasks) that must be completed.  This goes further than simple 'fix this bug' tasks.  Policies can enforce rules associated with the tasks so that code must be tested and verified before it gets checked into source control.  Awesome.
  • WhiteHorse - this is fantastic.  This modeling tool enforces that the model is the code is the model.  You have to see it to believe it.
  • FxCop - I am very excited to see FxCop built into VSTS.  Rather than being a separate step in the application development process, you get the warnings to frequent gotchas right in the dev environment.

The list goes on and is not limited to the above, but includes also the built-in performance analysis, stress tests, daily builds, etc.

This is really gonna be a great tool set.  I have a feeling that this package is going to feed coal to the Whidbey freight train.  What is that? Do I see a coffee cup on the train track?

Friday, June 11, 2004 2:45:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback