Friday, March 25, 2005

618.aspx

Skiing trip last weekend

I was hoping to go skiing with my family two weeks ago but had to cancel my plans for work.


Probably just as well, as the weather was just gorgeous when we went to a local ski resort this weekend. The picture below was taken with a phone while I was in the ski lift so it doesn't convey how lovely it was:


A good day became a great day when my oldest daughter started skiing for real. We rented the complete outfit and played around a bit before we took the 4-seat ski lift to the top. The first couple of trips we used a tip lock I bought last year. It makes it a lot easier to learn to ski and keep the skis in a wedge position. After she got the hang of breaking, she decided she wanted try for herself without the tip lock. A couple of falls but it went really well. Well enough to make dad very proud.

Thursday, March 24, 2005

616.aspx

Fastest way to replace contents in a StringBuilder

I was reviewing some .NET code for a new feature when I came across the following piece of code:



_sXML.Replace(_sXML.ToString(), newValue);


It took me a while to understand what the developer wanted to do. It replaces the entire contents of the _sXML StringBuilder with the new value. A creative, but slow way, to do replace the entire contents of a StringBuilder with the a value.


I told the developer that it would be a lot faster to set the length to 0 and then append the new contents but  I was curious to see the performance difference. I compared the following ways to do the same thing:



  1. builder.Replace(buffer.ToString(), newValue);  //1392 ms

  2. builder.Length=0; buffer.Append(newValue);  // 130 ms

  3. builder = new StringBuilder();  // 420 ms

The results make perfect sense. Setting the Length to 0 clears the contents of the StringBuilder but it does not release the buffer. Appending the new value is quick as it does not have to re-allocate a new buffer.

613.aspx

Meet Sydney - our new family member

Our previous dog, a female pastore maremmano, died several years ago. With a baby on the way, we decided to wait for few years until the kids could enjoy a dog as well.


When my wife found a announcement on www.Secondamano.it for someone giving away a 2 month old Australian Shepherd puppy, it only took me a couple of minutes on google to be convinced: Aussies are great with kids, intelligent and I guess I am more a dog person than a cat person.


Only later did I realize what I had gotten myself into. The puppy was in a place called Zocca in the hills "close" to Modena. I got up early Sunday morning to drive down to pick up the surprise for the kids. No traffic and not too much work on the road so I made good time on the way down.


I parked in front of the church and called for further instructions which went something like this: does your car have high clearance? Yes? OK. Go to the next crossing, turn left, take the small road for 2.6 km and wait there. I will come and pick you up by horse.


Yes, by horse. The last piece of road was more like a dried up river than a road, but I made it, following the owner on a horse and 3 dogs the last piece of the way (the mum is the closest dog on the left)


The trip back was, as you could expect, an adventure. The first piece on the dried up river went well as I had to drive at walking speed. But, as soon as the roads got better, I drove a little bit faster. I tried to go easy in the corners and avoid sharp accelerations but it did not help. I got the second gift of the day (the dog being the first) after a km or so. The breakfast came up and we stopped a few minutes to clean up the worst.


I had learned my lesson and went as slow as I could. We stopped every 5 minutes or so for some cuddling and to make sure we didn't have another accident. But, in one particularly long stretch without any place to stop, the last pieces of the breakfast came up as well. Luckily we were almost down on the flatland so there were no more turns. As soon as we hit the highway he fell asleep and slept most of the way home.


The kids were surprised and happy to meet the new family member which we decided to call Sydney:



Sydney stays outside most of the day and naps on the stairs when he gets tired. He still sleeps inside at night which means that I don't get a lot of sleep as I have to get up several times at night to take him outside for his business. Not much time for blogging either but that's life with a new "baby" in the house.

612.aspx

HP worldwide support rocks

I bought a refurbished iPAQ 4150 on eBay last August from the UK. I feared the worst when the speaker broke a few weeks ago. Would my refurbished iPAQ be covered by any guarantee? The Italian support form was broken (server error) so I had to explain my issue a few times via e-mail before I got a case ID and a phone number to call.


HP sent a UPS truck to pick up my iPAQ Thursday 17th just before lunch time. I got the fixed iPAQ back from Amsterdam Tuesday 22nd in the morning. Only 2 1/2 working days to get it fixed.


Impressive!

Wednesday, March 23, 2005

610.aspx

Gmail notifier error: cannot read your messages (bad data; 6)

Gmail Notifier stopped working for me after they  added CAPTCHA based authentication. It always gave me the error: cannot read your messages (bad data; 6)


The fix is to delete the cookies:



  • In Internet Explorer, choose: Tools | Internet Options | General (tab) | Delete Cookies

  • Restart gmail notifier

Works like a charm

Friday, March 18, 2005

605.aspx

Microsoft Architect Day

Microsoft Italy is organizing an Architect Day in Milano 22/3 covering Service-Oriented Architectures, Microsoft Indigo and BizTalk Server 2004. Hope it is as interesting as the Microsoft Visual Studio Team System Day.


See you there.

Thursday, March 17, 2005

602.aspx

Fixing ASP.NET debug error 0x8013134b

I got the following error debugging an ASP.NET project earlier today:



Auto-attach to process '[2440] w3wp.exe' on machine '...' failed. Error code 0x8013134b.


The problem was that I had installed .NET 2.0 which had registered ASP.NET 2.0 on the Web Site I was trying to debug.


Fixing it is simple:



  • Run the IIS Manager

  • Right click on the web site with the problem

  • Click the ASP.NET tab

  • Change the ASP.NET version from 2.something to 1.something in the combo and debugging works again

Monday, March 14, 2005

598.aspx

Living on Pocket Coffee and True Love

This has been one busy weekend. I have been designing a new (and of course very urgent) feature this weekend for a client. I don't know about you; but designing a software architecture for me is a abstract/visual process. I see components and source code interacting in my mind. This is particularly true in the beginning of the design phase while I still have to understand the problem, constraints and possible options. When I have a rough idea of what I want to do, I scribble a lot of notes before I get more concrete and draft charts and UML diagrams. I was present (at least physically) this weekend and have vague memories of going to a park and playing with the kids.


I cannot have been there mentally though as my youngest daughter looked up at me after particularly intense “session“ and said Daddy, where did you go? It didn't go much better yesterday. I was inside documenting the new architecture while the kids where out playing. At once stage I looked at the watch and said to myself; one hour until dinner, plenty of time to finish the sequence diagram. A couple of minutes one hour later the kids were at the door asking for dinner.


I had to be at a clients site at 4 am (i.e. get up at 3 am) to support a release this morning so I went to bed when the kids went to bed yesterday. I got about three hours of sleep before the youngest daughter woke up and ended up in our bed. That was all the sleep I got. She has had a nasty cold for several days so she doesn't sleep well. I fell asleep, she “kicked” me in the back, I fell asleep again and she “hit“ me on the shoulder and so on until I decided I might as well get out of bed and get some work done.


This is where the Pocket Coffee come into the story. I have never seen Jolt Cola in Italy so Pocket Coffee has become a substitute for me. They are chocolates with a liquid coffee center. Sugar for the brain and some caffeine to keep you going through the night.  The release wet well so I managed to leave at a decent time and go to another client before heading home.


When I came back today I was pretty much wrecked and ready to go to bed. That changed as soon as I came in the door. My youngest daughter, that had kept me awake most of the night, came running, jumped up into my arms and shouted "My Daddy!" repeatedly giving me big hugs. This is where True Love come into the story. I don't know what it is; kids can drive you crazy sometimes but five minutes later you love them more than anything else in the world. I melted inside and didn't have the heart to go to bed. After playing for a couple of hours with homemade puzzles (more on that later) and other toys I finally have 1/2 hour for some rest while she picks up her big sister at school.


Feeling tired, more tired, ZZZZZZzzzzzzzzzzz.........

Wednesday, March 9, 2005

590.aspx

Bag Bug

Got a new backpack at work today, and it reminds me a lot of this software engineering cartoon:


Bag engineers apparently face the same problem


The large front pocket of the bag is completely useless as it was sewn shut when they put on the logo…

Monday, March 7, 2005

584.aspx

Microsoft Visual Studio Team System Day

I attended the Microsoft Visual Studio Team System Day in Milano today. They did not put the slides in the goody bag but you can check out the slides from Visual Studio 2005 Team System at DevConnections as they are virtually identical.


I had a rough idea what would be in Team System but I did not imagine how many features they are putting in it. My administrative summary : Team System gives you the core features of Rational Rose for managing the life cycle of a project at a fraction of the cost. I will not cover all the features presented today but mention some of the ones that I like the most.


When you start a new project, you define the "model" you want to use. The bits I saw only supported the "Agile" project model but there will be several project models available by the time it ships late this summer. What really impressed me with the product is that it is highly customizable. So, if you are an Extreme Programming fan you can create your own model by editing the XML files that define the model. You can also tune the built in models to get the behavior you want, for example:



  • All check ins must be tied to a work item

  • All code must have an unit test

  • All code must have passed code coverage testing before being checked in.

Design
Microsoft has finally understood one thing: as enterprise applications get more complex you have to get the systems architects and development architects working together. I share office with the systems architect on my project and I believe it is crucial to developing scalable and robust enterprise solutions. There are obvious benefits like preventing me from design a system that cannot be deployed in production, but there are also more subtle but very important benefits by working closely together with the systems architect. I am a lot more lot more sensitive to IT issues as the IT guys come to our office when there are problems. Knowing what problems they face help me design better systems (so they don't break my balls in the future :-)


Team System allows the software architect to design logical services like "Payment Web Service" and specify the requirements of the service like: requires .NET 1.1, must talk to the DB, etc. It is possible to "drill in" and specify the actual interfaces. Change the interface and the code gets updated and vice versa (cool!). The IT architect works on a logical data system like "hardened front end web server", "database server" etc and the architects can decide where the components should be deployed. The neat feature is that Team System alerts you when you try to "deploy" a component that needs DB access on a DMZ server that does not have data base access.


Rating: Neat but you can accomplish the same with Visio if you work with a skilled IT architect.


Development / Testing
These items speak for themselves, and if you are not impressed you are not a developer



  • Static Code analysis

  • Code profiling

  • Color coded Code Coverage

  • Integrated Unit Testing

  • Load Testing:


    • Graphical configuration by default but you can choose to generate .NET code which you can modify any way you want

    • Load test anything: recorded scripts or the unit tests already implemented by the developer

    • Simplified performance analysis: choose the server "role" (web, db, …) and the tool shows you:


      • Relevant performance counters

      • Warnings if they are outside normal range

Rating: Anything that helps me write better code is a plus.


Version Control
Microsoft did the right choice and threw out Visual Source Safe with the trash. The new version control system is Web Service based which finally makes it possible to work from a remote location with a decent performance. It also means that there will be (3rd party) clients for the most important operating systems. In addition to the tight Visual Studio integration there is also a light web client.


They add one simple feature that is incredibly useful: shelving. I don't know how many times I have been working on a piece of code when something more important comes up that touches the same project. Different people deal with it in different ways; backup to .zip, branch etc. The new version control system allows you to put the code on "the shelf". It does -not- show up in the "official" branch of the code so nobody gets your unfinished code by mistake. Later, when you have finished the urgent issue, you can take the code down from the shelf, check it in or share it with other people on the project.


Other neat features



  • Parallel development

  • Changes encapsulated as a change set

  • Easy roll back/forth

  • e-mail/Instant Messenger notification

Rating: Finally a real version control system!


Management, Work Items and Reporting
The Work Items are at the core of the process. A Work Item can be a new feature requested by marketing, a bug found during a code review or anything that requires "work". The important thing is that the work items are tightly integrated with the whole process. The developers sees the work items allocated to them inside the Visual Studio GUI and associate them with check ins in the version control system. The PMs can finally get an up to date project status by checking the project items.


There are no new tools to learn: the work items can be modified by Visual Studio or accessed and edited from familiar tools like Microsoft Excel and Microsoft Project. There should no more be such a thing as an out of date project plan. The new Work Item system makes it easy to find out what a person is working on an and find out who is working on a particular feature.


Not only does Team System come with its own reports; it comes with its own portal. It uses the SharePoint services (no license required) and SQL Reporting to give anybody instant access to the status of the project. Everything that has some sort of metric associated with it ends up in the portal: code coverage statistics, version control statistics, performance testing results, open bugs etc. One powerful tool for monitoring the status and health of a project.


Rating: The project management bit is not my cup of tea but I like the fact that the Work Items is at the core of the Team System and that all metrics end up in a central Data Warehouse.


Build
This rocks. The build system has several must have features:



  • Builds are reproducible. The system gets the latest version of the code and all configuration settings and makes a build with a specific number so the build can be repeated at any time with the same result.

  • Work Items are automatically update with build number. This means that it is snap to find out which issues are fixed in a build or to find which build an issue was fixed in.

  • Builds can be scheduled or run on demand

  • Loads of reporting and error handling options.

Rating: I want it now! I hope it is scriptable so we can extend the build process to include other environments like Java.


Overall
A very interesting introduction to Team System although a couple of demos has the BillG effect (Virtual PC blue screened at one point). I left the meeting with a feeling that the whole system is well integrated and highly configurable. There are features that will not make it into Visual Studio 2005 like deployment to servers but they are working on that and other cool features for version 2.


Get the latest news from Team Foundation blog

Sunday, March 6, 2005

581.aspx

Getting rid of some hair

Jeff Sandquist cut his mustache and looks 10 years younger. I had my hair cut and end up looking like one of the monks in The name of the Rose



Did I make a mistake when I said short? It saves time and money though as I don't have to cut my hair for the foreseeable future.

Wednesday, March 2, 2005

575.aspx

.NET CF Clipboard support and SP3

In the past I used keyboard emulation to do cut and paste on the Pocket PC. But, after one of the latest .NET Compact Framework service packs (I think it was SP3) it does not work any more. I cannot even use Ctrl+C, Ctrl+V, Ctrl+X with the keyboard :-( Removing functionality with service packs should be banned by law.


I threw out my old code and used the APIs to get full cut and paste support in my .NET Compact Framework applications. I decided to keep it simple and call the APIs passing the currently active text box as an argument instead of inheriting from, and extending, the built in text box.



UI source code


private void menuItemCopy_Click(object sender, System.EventArgs e)


{


      pocketone.UI.Clipboard.Copy(getActiveTextBox());


}


private void menuItemPaste_Click(object sender, System.EventArgs e)


{


      pocketone.UI.Clipboard.Paste(getActiveTextBox());


}


 


private void menuItemUndo_Click(object sender, System.EventArgs e)


{


      pocketone.UI.Clipboard.Copy(getActiveTextBox());


}


 


private void menuItemSelectAll_Click(object sender, System.EventArgs e)


{


      getActiveTextBox().SelectAll();


}


 


private void menuItemCut_Click(object sender, System.EventArgs e)


{


      pocketone.UI.Clipboard.Cut(getActiveTextBox());


}


 


/// <summary>


/// Get the currently active textbox


/// </summary>


/// <returns></returns>


private TextBox getActiveTextBox()


{


      TextBox activeTextBox = null;


      foreach (Control ctrl in this.Controls)


      {


            if (ctrl is TextBox)


            {


                  if (ctrl.Focused)


                  {


                        activeTextBox = (TextBox) ctrl;


                        break;


                  }


            }


      }


 


      return activeTextBox;


}



Note: Make sure you disable the copy/paste etc menus if no TextBox has the focus (or add error handling). Something like this does the trick:


private void menuItemEdit_Popup(object sender, System.EventArgs e)


{


      bool enableOperations = (null != getActiveTextBox());


      this.menuItemCopy.Enabled = enableOperations;


      this.menuItemCut.Enabled = enableOperations;


      this.menuItemPaste.Enabled = enableOperations;


      this.menuItemSelectAll.Enabled = enableOperations;


}



Clipboard class source code


/// <summary>


/// The Clipboard class is based on code from


/// http://www.opennetcf.org/Forums/topic.asp?TOPIC_ID=125


/// </summary>


public class Clipboard


{


     


      #region Win32 API ------------------------------------------------------------


      private const uint CF_UNICODETEXT   = 13;


 


      [DllImport("Coredll.dll")]


      private static extern bool OpenClipboard(IntPtr hWndNewOwner);


 


      [DllImport("Coredll.dll")]


      private static extern bool CloseClipboard();


 


      [DllImport("Coredll.dll")]


      private static extern bool EmptyClipboard();


 


      [DllImport("Coredll.dll")]


      private static extern bool IsClipboardFormatAvailable(uint uFormat);


 


      [DllImport("Coredll.dll")]


      private static extern IntPtr GetClipboardData(uint uFormat);


 


      [DllImport("Coredll.dll")]


      private static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);


 


      [DllImport("Coredll.dll")]


      private static extern IntPtr LocalAlloc(int uFlags, int uBytes);


      #endregion -------------------------------------------------------------------


 


      #region Internal support functions


      private static IntPtr hMem = IntPtr.Zero;      


 


      /// <summary>


      /// Copy data from string to a pointer


      /// </summary>


      /// <param name="dest"></param>


      /// <param name="src"></param>


      private unsafe static void CopyToPointer(IntPtr dest, string src)


      {


            int x;


            char* pDest = (char*) dest.ToPointer();


 


            for (x = 0; x < src.Length; x++)


            {


                  pDest[x] = src[x];


            }


            pDest[x] = '\0';  // Add the null terminator.


      }


 


      /// <summary>


      /// Convert a pointer to string


      /// </summary>


      /// <param name="src"></param>


      /// <returns></returns>


      private unsafe static string ConvertToString(IntPtr src)


      {


            int x;


            char* pSrc = (char*) src.ToPointer();


            StringBuilder sb = new StringBuilder();


 


            for (x = 0; pSrc[x] != '\0'; x++)


            {


                  sb.Append(pSrc[x]);


            }


            return sb.ToString();


      }


      #endregion


 


      #region Public methods


      /// <summary>


      /// Check if data is available on the clipboard


      /// </summary>


      public static bool IsDataAvailable


      {


            get


            {                      


                  return IsClipboardFormatAvailable(CF_UNICODETEXT);


            }


      }


 


      /// <summary>


      /// Set data on the clipboard


      /// </summary>


      /// <param name="strText"></param>


      /// <returns></returns>


      public unsafe static bool SetData(string strText)


      {


            if (OpenClipboard(IntPtr.Zero) == false)


            {


                  return false;


            }


 


            hMem = LocalAlloc(0, ((strText.Length + 1) * sizeof(char)));


            if (hMem.ToInt32() == 0)


            {


                  return false;


            }


 


            CopyToPointer(hMem, strText);


 


            EmptyClipboard();


 


            SetClipboardData(CF_UNICODETEXT, hMem);


 


            CloseClipboard();


 


            return true;


      }


 


      /// <summary>


      /// Get data from the clipboard


      /// </summary>


      /// <returns></returns>


      public static string GetData()


      {


            IntPtr hData;


            string strText;


 


            if (IsDataAvailable == false)


            {


                  return null;


            }


 


            if (OpenClipboard(IntPtr.Zero) == false)


            {


                  return null;


            }


 


            hData = GetClipboardData(CF_UNICODETEXT);


            if (hData.ToInt32() == 0)


            {


                  return null;


            }


 


            strText = ConvertToString(hData);


 


            CloseClipboard();


 


            return strText;


      }


 


      public static void Cut(TextBox txtBox)


      {


            // Copy the data to the clipboard


            SetData(txtBox.SelectedText);


 


            // Remove selected text


            txtBox.SelectedText = "";


           


      }


                 


      public static void Copy(TextBox txtBox)


      {


            // Copy the data to the clipboard


            SetData(txtBox.SelectedText);            


      }


 


      public static void Paste(TextBox txtBox)


      {                


            if (IsDataAvailable)


            {


                  txtBox.SelectedText = GetData();


            }


           


      }


      #endregion
}