Wednesday, June 02, 2004

I owe lunch to a great friend of mine for helping my solve this.  Jason Walker (a fellow member of our .NET User Group leadership) was kind enough to research an issue I was having.

The team up at Redmond was kind enough to include a method called EnableVisualStyles() in .NET Framework v1.1.  This method alleviates the need to include .manifest files for each .exe for which you want the sleek, cool Windows XP look and feel.  This method should be called prior to any UI or control being presented so it is routinely the first line of code in your app's entry point.  I suppose (for I haven't looked deeply into it yet) that calling this method internally performs a PostMessage() operation which is an asynchronous, fire and forget method (vs SendMessage() which is synchronous).

Through heartache and pain I have found that if your application displays a modal dialog window an exception will be thrown when the dialog closes down.  Well, I was programming along and all of the sudden I was greeted by a very noxious-looking and uninformative System.Runtime.InteropServices.SEHException when a wizard that I had written (which is displayed as a modal dialog) shut down.  It didn't occur to me that my call to EnableVisualStyles() was the offender of this obscure error.  I was trying to figure out whether it was something to do with some custom non-UI to UI thread marshalling or something of the like.  The stack trace revealed the following:

SEHException at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at
System.Windows.Forms.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(...)
...

I should have read the stack trace more closely before applying my own rationale to solving the problem.

The solution is to call Application.DoEvents() just following the call to Application.EnableVisualStyles() so that the message posted has a chance to complete before proceeding.

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

Today is the first day that I feel I can officially talk about it (except that which I've already done with a few close friends).  I have decided to leave my current employment and persue an independent route.  Having given my company 6 (!) weeks notice, I will be joining a very good and close friend in California.  My last day will be June 23rd - this, giving me enough time to complete my current project and commitments, will mean that I begin anew on June 24th.

This new position is very exciting for me.  For starters I will be able to work from home, which is undoubtedly a perk.  It will be difficult, however, as I must discipline myself not to be distracted in the minutae of everyday life.  Also I will be responsible for bringing an already-written Win32 app over to a web-based platform with the full, rich UI that customers have grown to expect - daunting, but exciting.

I am very much looking forward to this opportunity.

Tuesday, June 01, 2004 2:59:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Friday, May 28, 2004

Arguably, I should learn more about Java.  At times I do feel the need to understand the Java industry, J2EE, EJB, and Sun, and all that goes with it.  I have been bred, indoctrinated, and inculcated if you will in the Microsoft religion.  And believe me, I am very happy as a devoted MS developer.  It goes without saying, however, that as a consultant I should broaden my horizons.  This would empower me in many ways, ways in which I am not yet empowered. ;)  I have written a few small (very small) programs in Java in an effort to become familiar with it but that was several years ago.  And honestly, having a strong background in C#/C++ I found its syntax welcoming and pretty straight forward.

Over the years I have had the opportunity to delve into many Microsoft technologies and feel very much at home writing applications for Windows.  Regardless of whether the apps are of the Managed (.NET) variety or native Win32 applications I'm very much at home.  Whether the apps are your traditional desktop, single-user apps, or multi-user client/server apps, or enterprise-worthy applications that leverage COM+ services I feel comfortable designing and constructing such applications.  I wouldn't have the faintest idea, on the other hand, how to begin to design, architect, program, and deploy such an application using Java and the Java-based tools.

I feel a lot like N. Alex Rupp as he expresses in his blog.  He raises several valid points, focusing on the US vs THEM attitude that developers seem to exhibit.  I have felt the schizm that for some reason exists between Microsoft and non-Microsoft developers (Is it me or is the industry extremely polarized?  Either you hate MS or you love them...there's very little middle ground).  I prefer not to take sides, always attempting to weigh the matter at hand.  When it comes to technology and tools, I have a strong tendency to lean towards MS for the reasons mentioned above.  I also share in their vision and their perception of computing.  I feel that the schizm exists primarily due to a lack of understanding of the other party.  We must all be educated.

Friday, May 28, 2004 3:33:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, May 25, 2004

This week is kind of bittersweet.  On the one hand I'm sad that I'm missing Tech Ed.  I wanted so bad to go.  And on the other hand we're getting a lot done around the house:

1. we've poured a new entryway/patio/porch area
2. we're pouring a new parkstrip
3. we've ripped out our front 'lawn' and grated the front and back
4. we're having landscapers come in and overhaul our sprinkler system and lawn

So it's been an interesting week so far (and it's only Tuesday).

I have been able to keep abreast of the many goings-on by reading other fellow bloggers' posts.  My good friend Aaron Skonnard is updating quite frequently his blog as well as a good friend and colleague Scott Golightly keeps me posted on what's happening.  So in a way I'm sorta vicariously there, but I hope to make it in person in the coming years.  It's pretty exciting to see that WSE 2.0 has been released/unveiled.  Also it appears that there is quite a focus on Web Services (as if that's not big these days) and SO(A) - exciting stuff!

I tend to get a lot from these conferences (I've been to PDC and VBits several times) and am looking forward to participating in the future...here's to next year!

Tuesday, May 25, 2004 2:53:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Friday, May 21, 2004

An interesting discussion was started at the SQL Server Users Group last night.  Basically, the question was whether it was ok to add 26 (!) Text/Image fields to a table.  And if not, what a viable resolution would be.  Now, I've had the opportunity to address a similar issue before and will withhold my solution for the time being from this blog entry so as not to bias the result.

Well, first of all, it seemed like the mandate to include these 26 fields (an arbitrary amount?) came from management which is a glaring red flag to me.  Very rarely (if ever?) does management actually understand database architecture and design and even more rarely how to tune and optimize a database for the applications that use it.  Ok, so management has asked for the ability to store tons of additional (categorized?) information and be able to retrieve it...that's what we need to know, not how they think it should be implemented - that's the responsibility of a knowledgable and creative DBA (more on that another time).

Now the real question: How should the data be stored so that it can be retrieved when needed?  It should be painfully obvious that putting the 26 columns in the table is wrong.  Wrong for a lot of reasons, architecturally and logically.  Some suggestions were:

1.  Create a related table with a foreign key and a single Text field (and possibly other metadata).  When you need the information you join that child table in and return it.

2.  Move the data (if it's file-based) off to a file server with a link in the database back to the actual physical file.

The group (I was a mere observer and didn't venture an opinion) ultimately came to the conclusion that it depends.  It depends on

  • the kind of data being stored (binary, text/comments, files, etc)
  • the amount of information stored (can you use a (N)VARCHAR instead?)
  • does the information need to be queried? (thus possibly requiring Full Text Search capabilities)
  • how is the information to be retrieved? (SQL? FTP? etc)

Anyway, what is your opinion? How would you recommend approaching this problem? 

Friday, May 21, 2004 6:23:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, May 19, 2004

I am reminded by a blog by Brad Abrams of a topic I meant to blog about a few weeks ago but forgot.  A while back I downloaded the free Microsoft tool FxCop.  This was back in the original versions and it was a bit cumbersome to work with.  Now, however, the new version (1.3) is much better!

FxCop performs an introspective analysis of your code, comparing rules that you select against your code and offering suggestions and recommendations.  These rules provide guidance for naming conventions, object design standards and practices, and common performance suggestions.  Additionally, the rule model is extensible - you can create your own sets of rules to apply to your code that help enforce individual or team standards and practices.

If you've not had the opportunity to use FxCop, take the time to do so!  In all honesty, I was a bit disconcerted when I first ran it on my code.  It's analysis is quite thorough and I was quite amazed at all the things (both small and great) that it caught in my code.  I try, now, to make it a habit to always run FxCop against my assemblies and am working on incorporating it into my daily builds of my code.

John Robbins has an excellent introduction into FxCop that you should read, whether you are new to FxCop or old hat.  Kudos to Microsoft for publishing such a great tool.

Wednesday, May 19, 2004 2:53:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Monday, May 17, 2004

Eric Gunnerson brings up an interesting point on which I'd like to elaborate regarding virtual methods.  It has long been a tenet of mine in the realm of object design that the programmer should be in full control of his components and their usage.  The developer of a component knows (or should know) intimately the inner workings of his components.  When an object is designed, the methods thereon should provide the consumer (another developer) with a direction and a usage.  Classes should readily make apparent their intended usage - if it's not really a possibility, then better documentation should be made available.  This helps avoid problems wherein another developer uses the class in an unsupported manner.

I am a strong believer that methods should not be virtual (overridable for the not-so-strong-right-pinkied folk out there).  When a method is marked as virtual it shouts out to the deriver that it was the developers intentions to support scenarios in which the method is overridden.  As EricGu points out, marking everything as virtual to handle the fringe case of 'just in case the developer wants to extend the functionality' is poor design and very non-intuitive.

I take it a step further in all of my design.  I believe that a class should be marked as sealed by default.  By doing so, the developers intentions are clear: You cannot override this class, it will simply not be tolerated!  I make it a practice, in fact, to mark all classes that I create 'internal sealed' to enforce this pattern.  Only in situations in which I am intentionally designing a class to be overridden do I remove the sealed class (e.g. when there is at least one virtual function).  Only when the class is intended to be used externally to my component to I mark them as public.  To help enforce this practice, I've taken the time to edit each of the VS.NET templates if anyone would like them.

This practice has saved me hours of headache and has enforced a logical design and structure to my components.

Thoughts? Comments?

Monday, May 17, 2004 12:43:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Saturday, May 15, 2004

Recently, a client of mine had a need for me to write (largely rewrite) an application for them.  Without getting specific or too detailed, the gist of the matter was that they had an application written and (semi-)working on Windows 95 that they NEEDED to migrate to Windows 2000/XP.  Unfortunately, they couldn't exactly take their existing investment and run it on Win2k due to some weird incompatibilities.

It came down to them needing to rewrite it entirely.  The client (with some guidance and directly from yours truly) opted to go with a .NET solution.  A hiccup was that the application relied very heavily on a third-party suite of tools that provides scientific analysis of images.  This suite was written entirely in C++ and is an MFC application.  Well, I'm not an expert in C++ and despite my experience in C++ it would take me a long time to write a full-blown app in C++, a lot longer than to, say, code the same app in C# or VB.  Well, the route I've decided to take (and one that I feel will provide the best experience going forward) is to design and code a translation layer between what would be considered a '.NET' interface to the backend MFC.

To accomplish this, I created a C++.NET dll that natively talks MFC and exposes the objects out to a .NET/managed client.  This was not a cake walk as it was fraught with gotchas.  These are a few of the caveats that I ran into:

  1. Memory management.  I had to manually control object lifetime of the MFC components.  I did this by designing an object hierarchy wherein each object implemented IDisposable.  Additionally, I supported the Finalize method by creating object destructors.
  2. Documentation.  The documentation for the suite of tools was horrendous.  The example code snippets were riddled with errors and inconsistencies.  The documentation was flat-out wrong in some cases.  Possible exceptions were not documented and identified.  This was one of the biggest hurdles to overcome.  Unfortunately, I really didn't have much of a choice with regards to their documentation - I had to use it.  I could find NOTHING online about this tool and we were stuck using it - no if's, and's or but's about it.
  3. Object interfaces.  The objects against which I was coding had very convoluted and relied on a lot of programmer knowledge of the inner-workings of the objects.  It was expected that to call method B() you already called A().  This particular design wouldn't be so bad except that the documentation never stated that you should have called A() in the first place.
  4. Lack of good customer support.  Emails were not responded to in a timely manner and were often not helpful.  Calls resulted in 'you're already in the queue' answers.
  5. Time Constraits.  The customer needs the app yesterday.

Well, the above list is by no stretch comprehensive, but gives a flavor of what I was up against.  Anyway, push come to shove, I was able to complete my .NET API version of the MFC components which, if I do say so myself, is much more useable and more understandable than the original objects.

This is what I did:

I created a base object (let's call it ObjectBase (names have been changed to protect the innocent)).  ObjectBase implements the IDisposable interface and manages the object's lifetime.  When the .NET object is created, a pointer to the object is acquired in ObjectBase and is then held until the .NET object is destroyed at which point the pointer is deleted.  Each ObjectBase-derived class can and may hold other non-.NET objects in memory.  The Dispose() method in ObjectBase makes a call to a virtual function called releaseUnmanagedMemory() that may be overridden in the derived class.

public __gc __abstract class ObjectBase : public IDisposable
{
   public:
      ObjectBase(void);
      ~ObjectBase(void);
      void Dispose(void);

      __property String* get_Name(void);
      __property void set_Name(String* value);

   protected:
      virtual void releaseUnmanagedMemory(void);

   private:
      mfcObj* _obj;
      bool _dispose;
      void dispose(bool disposing);

   protected public:
      ObjectBase(mfcObj* obj);
      __inline mfcObj* obj() { return _obj; }
}

That's not the whole object, but gives an idea of the direction I was going.  There's a protected public ctor as well that allows the .NET object to be created within my dll given the object pointer.  When I had finished the entire design it turned out that it was very elegant.

I tried to make my objects as self-documentating as I could while retaining all of the capabilities of the underlying third-party components at the same time making the classes have a .NET feel to them.  This required cleaning up object and variable names as well as creating several additional class types that weren't defined in the original API.

If anyone's interested I could probably post my actual implementation with some descriptions and comments.

Saturday, May 15, 2004 5:01:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback