Monday, September 12, 2005

Today I am excited to have received a copy of the Carcassonne Almanac from www.spielbox-online.de which I ordered way back in April for 8 EURO (the actual product link is here)  I preordered the product (which just recently became available mid August).  The product (which is essentially just a glorified newsletter) contains a copy of the expansion Carcassonne - Die Katharer (The Cathars).  That was, in fact, the primary reason I made the order in the first place.  Previously, the expansion was only made available to a select few subscribers to a game magazine in Europe.

Carcassonne is an awesome tile-based board game and I look forward to trying out this expansion!

Monday, September 12, 2005 7:30:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, September 09, 2005

Last night we had the opportunity to attend the Utah .NET User Group at which a local developer by the name of Josh Perry provided a presentation on the topic of Mono.  We had a pretty good turn-out, too which was very exciting, as well.  Josh demonstrated creating an application in a text editor (e.g. Visual Studio), compiling it using Mono and running it on Linux and Mac OS X.  All in all, it was pretty enlightening to see all of the advancements that have been made by the open source community around the .NET framework.

Very cool!

Friday, September 09, 2005 3:16:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, September 08, 2005

It appears that I'm all switched over to my new ISP and things are going pretty well.  I got so fed up with my last provider and their constant drops.  You may recall that I was completely down for 11 days last month.  I've dropped a few other times since then as well for 1+ days.  Invariably, it seems that my old ISP knew when I was out of town and needed remote access because that's when it would go down.

Now, I'm on Comcast with a business account.  My download perf is pretty good (better than before) but ironically my upload speed is a little slower (though I think it's more consistent as well, so you might see better results anyway).  However, I'm very excited to have transitioned so smoothly and things seem to be on the up and up.

Hopefully these reliability issues are now a thing of the past.

Thursday, September 08, 2005 6:42:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, September 06, 2005

This occurred to me the moment I heard about it, but I'm just now putting my thought down to virtual paper.  Microsoft recently announced the official renamings of various code-named products; code names that had become pretty popular.  Sometimes, however, you've gotta wonder how sane their decisions were.

Code Name New Name Acronym
Indigo Windows Communication Foundation WCF
Avalon Windows Presentation Foundation WPF

What's next? are they going to rename Team Foundation Server "Windows Team Foundation Server"? There sure would be a bunch of WTFs flying around!

Tuesday, September 06, 2005 4:42:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
I had the opportunity tonight, along with a few of my fellow affiliates from the Utah .NET User Group, to attend a presentation given by Aaron Skonnard to the Northern Utah .NET User Group.  He covered the topic of Indigo (Windows Communication Foundation).  Wow, what a cool presentation!  I'm very glad I went and was able to participate.  Aaron talked about the history of Indigo, it's Borg-like effect (though he didn't use those words) of assimilating the various teams and technologies within Microsoft such as ASMX, COM+, MSMQ, Remoting, Messaging, Biztalk.  He had some pretty cool demos too.  All in all, it was a great event!
Tuesday, September 06, 2005 4:27:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, September 03, 2005

A buddy of mine pointed me to this blog post today.  He had the need to pull a single random record from a database table.  Traditionally, this has not been a completely trivial task, but not unattainable either.  Well, the technique employed here is pretty cool.  All you need to do is leverage the NewID() function in SQL Server 2000+.

SELECT TOP 1 * FROM tblSomeTable ORDER BY NEWID()

Pretty slick, eh?

Saturday, September 03, 2005 1:58:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, August 29, 2005

Well, now that I'm back from my usual Santa Barbara trip, life is getting back to its usual frenetic, over-extended form.  I had the opportunity this morning to attend the morning segment of what will be a two-day lecture/demo course on VS.NET 2005.  The course is presented by my good friend Scott Golightly (our local Microsoft Regional Director) and our new Microsoft Developer Evangelist, Ani Babaian.  Unfortunately, I had to leave early in order to be able to meet some deliverables this week, but I wanted to show up and show my support.

This evening, I had the opportunity to have a special Microsoft Insider's community leadership roundtable with Ani Babaian, Ashwin Karuhatty (our departing DE), Aaron Skonnard, Scott Golightly, Pat Wright, Robert Love, T.J. Belt, Jason Walker, Justin Long, Ben Galbraith (of our local Java User Group).  Others were invited as well, but apparently were unable to make it.  It was a fun time catching up with my long-time friends and associates and discussing the community and what we can do to help bolster enthusiasm.

All in all, it was a pretty good day.  Now onward for another 8 hrs or so (and yes, it's already 9:30 PM).  Se la vi.

Monday, August 29, 2005 2:33:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, August 25, 2005

I've been working pretty intensively with COM Interop lately - especially in conjunction with an add-in that I've written that integrates with Outlook.  This particular add-in has the need to run asynchronously and multi-threaded within Outlook, while at the same time interacting with COM components.  For those uninitiated, COM components have several threading models, single threaded, free threaded, both threaded, neutral threaded, etc.  Each of these apartment models has different characteristics and advantages and disadvanges, a topic I won't be covering to any appreciable depth here.  Suffice it to say, when interacting with COM components from .NET, you have to be sure that the thread is running in the appropriate apartment state in order to interact with the component.

The two threading apartment states for .NET components are STA (Single Threaded Apartment) and MTA (Multi Threaded Apartment).  Many components (especially those targeted to be consumed by VB.NOT (e.g. VB 6.0 and prior)) are intended to be run in a single-threaded apartment.

As it turns out, you can only set the ApartmentState property of a thread once (thereafter the property is readonly).  Therefore, care must be taken when calling STA components from an MTA thread.

My solution below, basically creates a new thread (if necessary) to run an STA component.  The calling thread effectively waits for the component to finish before continuing.

internal void DoWork() {
   if ( ApartmentState.STA != Thread.CurrentThread.ApartmentState ) {
      Thread staThread = new Thread(new ThreadStart(doActualWork));
      staThread.ApartmentState = ApartmentState.STA;
      staThread.Start();
      staThread.Join();
   }
   else {
      // we're already running in an STA apartment so it's ok to call the method as-is
      doActualWork();
   }
}

private void doActualWork() {
}

Thursday, August 25, 2005 7:22:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, August 20, 2005

I had this interesting problem the other day when creating an add-in for Office (Outlook specifically), but I believe it would apply to any Office add-in.  The problem goes as follows:

I would create a CommandBar and embed controls on it.  I would then wire up an event procedure for each control to fire accordingly.  The events would run properly once.  After that they wouldn't run.  Upon loading the first time, the add-in would create the CommandBar, and that's the only time it would work.  If I closed Outlook and reloaded it, the events would not get raised.  This was a tad frustrating.

So how did I solve it?  Well, to solve it, I had to dig a bit lower than the actual appearances and try to figure out what is really going on.  First of all, this is managed code (that is, the add-in is written in C#).  On the other hand, add-ins are COM components.  So there's this inherent COM-Interop layer between my add-in and the Office environment.  When an event gets wired up, you're really establishing a delegate instance (which is a managed component).  So this is what happened:

  1. call procedure to create CommandBar and constituent controls
  2. COM component CommandBar created via RCW (Runtime Callable Wrapper)
  3. COM components for each CommandBarControl created and each one added to the CommandBar via RCW (Runtime Callable Wrapper)
  4. .NET managed delegate wired up for each event
  5. procedure ends, local variables for each COM component goes out of scope
  6. Garbage collector (GC) determines that RCWs are no longer used so .NET references to COM components deleted (along with delegates)

So the solution was, effectively, to create a container of some sort simply to persist the references to the COM components beyond the creation procedure for the duration the add-in is loaded.  I opted for an ArrayList for ease and simplicity.

private outlook.Application _app;
private ArrayList           _controls = new ArrayList();

private void createControls() {
   CommandBar bar = _app.ActiveExplorer().CommandBars.Add(“Test CommandBar“, MsoBarPosition.msoBarTop, Type.Missing, true);
   CommandBarButton btn = (CommandBarButton)bar.Controls.Add(MsoControlType.msoControlButton, Type.Missing, “Test“, Type.Missing, true);
   btn.Tag = “TestButton“;
   btn.Caption = “Click Me“;
   btn.Click += new _CommandBarButtonEvents_ClickEventHandler(btn_Click);
   btn.Visible = true;
   // add the control to the collection so its reference persists
   _controls.Add(btn);
   bar.Visible = true;
}

private void btn_Click(CommandBarButton Ctrl, ref bool CancelDefault) {
   MessageBox.Show(“You clicked the button!“);
}

All in all, it's a pretty simple solution, but without knowing what's going on (or just a lucky guess), it's not the most straightforward problem to solve.  Hope this comes back to help someone who may be experiencing a similar problem.

Saturday, August 20, 2005 5:30:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [5]  |  Trackback