September, 2003

  • Eric Gunnerson's Compendium

    Splash Screens and non-rectangular windows


    I needed a splash screen for my music player app. I tried a couple of ideas that didn't work very well, but then I hit on the idea of using the image of a CD as the background of the splash screen - and doing a non-rectangular window. I'll start with the splash screen...

    Conceptually, a splash screen is pretty simple - it's just a form that you bring up at the start of the program. The code is something like this:

    SplashForm splashForm;
    public MyForm()
        splashForm = new SplashForm();

    and we'll hook the Activated event to hide the form.

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

    When we run this, however, something strange happens. The form comes up, but it never renders - there's just a black background. This is because we need the windows messages to be processed to get the form to paint. There are several ways to do this, but my choice is to simply call Application.DoEvents() after the form is shown. This processes any messages that have yet to be processed, showing the form.

    Next, we need to make a non-rectangular form. This is done by setting the region on the form. This is surprisingly easy to do. Here's the code I used for the CD:

    public SplashForm()
        GraphicsPath p = new GraphicsPath();
        p.AddEllipse(2, 4, 340, 341);
        p.AddEllipse(150, 153, 43, 43);
        this.Region = new Region(p);


    The first ellipse defines the outside of the picture, and then the second one this inside. This gives me a round window with a hole in the center.

    Pretty cool!

  • Eric Gunnerson's Compendium

    Question: Renaming windows forms?


    I'm working on resolving an issue, and the way that we decide depends upon the prevalence of a specific scenario. I'd like to know your opinion on the following Windows Forms scenario.

    How often do you rename the form class without renaming the file that holds the form class? ie how often do you change "class EmployeeForm" to "class AddressForm" without also renaming the form file?



  • Eric Gunnerson's Compendium

    The solution explorer and windows forms


    I have a design question for you. Yes, I don't own the project system anymore, but I started this particular issue, and I want to follow up on it:

    In VS 2002, whenever you double-click on a form file in solution explorer, the project system always opens the form designer on that file.

    We are considering modifying the behavior in Whidbey so that the project system will track the most-recently-viewed state for the file. If you had most recently looked at the code view, double-clicking would take you to the code view. If you had most recently looked at the design view, double-clicking would take you to the design view. This state would not be persisted across closing and reopening the project.

    What do you think? Should we stick with the current behavior, or should we change to the new behavior? And why?

  • Eric Gunnerson's Compendium

    My latest column is live


    My latest column is live on MSDN. This one shows the socket-based peer-to-peer system that I built for my ongoing music scheduling project. As you may or may not know, there is no support for serialization on the compact framework, so I had to build my own. It ended being pretty cool.

    In other news, last week one of my previous column made the from page on First time for that.

  • Eric Gunnerson's Compendium

    Creating a great presentation


    With PDC coming up, there have been lots of Microsoft entries about what makes a good presentation, and I'd like to throw my 35 cents into the discussion. Here are three things I like to keep in mind.

    Why is always more important than what

    Technical people are smart and used to figuring out things on their own. They can figure out the C# property syntax in their sleep. What they can't figure out is what was going on in your mind when you wrote a feature, and knowing that is the most important part.

    This is also critical for connecting with your audience. Showing some code and saying, "have you ever had to write ugly code like this?", and then showing the improvement will always garner a good response (assuming that the feature is actually useful). It's your job to provide the connection between the feature and the problem it solves.

    What you don't talk about is more important than what you do talk about

    Technical topics always have lots of subtle and interesting points that you could talk about. Understand the difference between what you could talk about and what the audience needs to know, and stick with the simplest scenario to start with. I've seen lots of presentations where the speaker throws in "interesting" asides that merely confuse the attendee.

    To put it another way, your job as a speaker is to filter the important information out of all the possible information. If you don't filter out the irrelevant details, your attendees won't know whether they should understand that information. That will 1) leave them thinking about your previous aside when you want them thinking about the topic you're now discussion and 2) make them feel stupid.

    Your job is not to display your technical mastery of the subject. I don't, for example, talk about the advanced events syntax when I talk about C# events. It's not relevant information.

    Get concrete fast

    Real world examples always beat abstract ones. Don't spend time on introductions when you could explain it as part of a real-world example, or show as part of a demo

    Iterate and embellish

    Most topics have several layers to them, either layers of complexity or ordered layers of discussion. In properties, for example, I would first show the world without properties, discuss the problems, and then show the world with properties. A building-block approach is easier for people to understand, and it builds the progression into the presentation so you can't forget it.

    I once came across a presentation guide that suggested not using revelation in presentations (revelation is when points are gradually revealed). If you're going to present effectively, you need to be able to focus the discussion on a specific point, and you do this through revelation. If you have three main points on a slide, and you show them all at once, your audience will be reading the second and third points while you're talking about the first. You want them listening to you instead.

    Revelation combined with diagrams can be a tremendous learning aid. A good diagram is worth at least 2^10 words. Consider whether you can express points graphically.

    Finally, I have a personal reason for liking revelation. One of the reason I emjoy presentating is the comedic potential, and an essential element of humor is timing. The funny part of the slide usually isn't the first part, and if you don't use revelation, everybody gets to it at different points - if they notice it at all. You want the impact to hit them all at once, and that's why you use revelation.

    Final Thoughts

    You should also read Conference Presentation Judo by Mark-Jason Dominus. If you presented before, this is a phenomenally useful presentation. Make sure you read the notes along with the slides.

    And if you're a Microsoft person who wants somebody to comment on your slides, I might be amenable.


  • Eric Gunnerson's Compendium

    I'm in need of ideas


    I've been cleaning my office today, and I need some help on a problem I have.

    Back when I wrote my C# book (A Programmer's Introduction to C# (still available at better booksellers everywhere (Eric needs to pay for his season's pass at Stevens Pass (where it snowed this week (view the webcam))))), I was lucky enough to have the first edition translated into a number of different languages. Whenever a publisher would finish a translation, my publisher (Apress, new owner of most of the Wrox titles) would send me a box of books. I always put one on the bookshelf, and when I had one that I thought somebody would be interested in, I'd give it to them. For example, I gave my Czech mother-in-law a copy of Začínáme programovat v C# , and Anders got a copy of

    C# introduktion for programmører

    But after a while, I exhausted the humorous potential of giving relatives copies of books that not only covered topics they didn't understand, but were written in languages they didn't speak, and I'm left with a number of copies that I don't know what to do with. Most are the first edition of the book, which is nowhere near as good as the second edition.

    So I'm looking for ideas of what to do. I currently have:

    7 Danish
    1 Italian
    4 Dutch
    4 Korean
    2 Korean (2nd edition)
    2 Chinese
    2 Polish
    4 Czech


  • Eric Gunnerson's Compendium

    PM: A new email record


    Today I set a new record in the amount of time I spent on a single email.

    I've been trying to coordinate a change in how generics work. Ultimately, this will involve coordinating with about 10 teams to figure out how to make a breaking change without breaking the build (which is a pretty big in in the VS team), but for now, I'm just working to get the process started. To do that, I need to write an email that explains what problem we're trying to solve and how to solve it.

    I wrote the first verison of the email at about 9 in the morning, and then got some advice on whether I was taking the rigth approach. I repeated this process throughout the day, interrupted by about 2 hours of meetings.

    The final version was written just after 5PM, and sent right before I left. 3 hours spent on the email, and another hour or so working on the same issue.

    I sent the mail, went down to the garage, got into the car and start to drive home. As I pulled out of the garage, The Cars "Let the Good Times Roll" came on radio. I turned it up.

    "Let them leave you up in the air"
    "Let them brush your rock and roll hair"

    While it's no longer cool to drive around in your car with the windows open listening to "The Cars" and 1978 was a long time ago, you can still sit in the leather seats of you 328, turn up the air conditioning, and cruise home. I've probably listened to this album as much as any in my collection, but it remains on of my favorites.

    Have a great weekend.

  • Eric Gunnerson's Compendium

    Why does C# have ? Why doesn't it have ?


    Over the past few years, we've gotten lots of suggestions and questions about the C# language, and we haven't done a very good job responding to them, for a variety of reasons.  

    The first reason is that we haven't devoted as much time as we probably should have to interacting with customers on the subject of language design. That's something I'll be trying to improve in the next few months. You can expect to see some more information about new language features before we give out bits at PDC.

    The second is a bit harder to explain. Basically, it revolves around whether a feature fits into what I'll call, for want of a better term, "The C# Philosophy". Some of the philosophy can be reduced to guidelines or rules, such as "Simplicity is also a feature", but there remains a fair portion that is really just based on the informed judgement of those on the design team. On some issues, that can make it really hard to communicate why we made a specific decision, as it's hard to put into words how we make our choices.. In the words of one of the design team members, "it took me 6 months of design meetings before I stopped making a fool of myself". For me, I think it was close to a year.

    So I don't expect the communication to be perfect. But it should be a lot better.

    I'm hoping to devote a number of entries to some of the guidelines we use. Note that this is really on my view of the philosophy of the design team, so don't view this as the definitive view. Guidelines I hope to cover:

    • Simplicity is also a feature
    • Magic only when justified
    • Serve the target audience
    • Tread lightly on unproven features
    • Remember that you aren't the customer
    • Solve real problems

    I'll try to do one of these each week.

  • Eric Gunnerson's Compendium

    C# Design Principle: Know what you're trying to build


    (The opinions expressed herein reflect my opinion about the principles we used in designing C#, and do not necessarily reflect the opinions of the C# design team).

    Know what you're trying to build

    Over the past few years, I've answered a lot of questions about language design rationale. Most questions have straightforward answers. For example, if somebody asks "Why doesn't C# have macros?", that's easy to answer.

    Other questions require a bit more work, and/or may be religious discussions. "Why are methods non-virtual by default?" takes more time to answer.

    The toughest ones to answer aren't tough because they're technically hard - they're tough because it's hard to give a nice answer to. This is usually because doing what the person requests would require changing one of the basic tenets of the language.

    Our goal in C# was to create a modern, real-world managed language that would be comfortable to developers used to the C family of languages (C, C++, Java, etc.). So, when I get questions like, "Why is C# case-sensitive?", they're really hard to answer. The real answer is that our target users would think we were crazy if we made a language that wasn't case-sensitive. You can say this in a polite way, but the person who asked the question is usually confused by your response. Their perspective is often "of course a language should be case-insensitive", which is diametricly opposed to the C# view.

    Similarly, I've been asked why C# doesn't allow you to define your own operators. There are some languages that allow you to do that, but that's very much not what we're after.

    Re-reading this, I'm not sure it's terribly insightful, so I'll try to summarize. When you're designing a language, you need to be clear up front what you're trying to build, and who is going to want to use that. Those early decisions are going to have a huge impact on the design of the language, and once you've made them, you can't really go back.

  • Eric Gunnerson's Compendium

    Generics and object collections


    In VS2003, since we don't have generics, we have lots of strongly-typed collections. For example, there's the LinkCollection class, which holds objects of type Link.

    Now that we have generics, we could replace such collections with:


    (well, actually, we couldn't replace them, as that would break existing code, but we could do that for new collections). That seems like a simple solution, but it isn't optimal, for a couple of reasons:

    1. Sometimes the type in the collection isn't sufficiently distinctive, especially if it's a built-in type. You'd like to see something like EmployeeIDCollection rather than List<int>
    2. It's often useful to add additional functionality to the collection beyond what you get from the built-in collection class.

    The better solution is to define your own collection class. Nicely, you can base it off of the collection class:

    class EmployeeIDCollection: List<int>

    The design guideline is not to expose collection classes, but rather to expose custom collection classes (I really need a better name for those) instead.




  • Eric Gunnerson's Compendium

    If you want to buy a used car...


    I have a couple of recommendations to make, from my experience buying a used BMW 328i

    The first is for my broker, Darrel Kempf. Darrel ended up owning a very small car lot (4 cars) when he bought some property a number of years ago, and that somehow turned into a business selling, renting, and brokering cars.

    Darrel was recommended to us by a friend that bought a 530 though him. For a flat rate ($600 in my case, IIRC), he will find a used car for you and transport it back to his lot, where you pick it up. In my case, he ended up travelling to a BMW auction in California and then talking to me about the cars that were available on his cell phone as he walked through the car lot. Overall, a very pleasurable experience, and I figure we saved at least $4000 on the car over what it would have cost in Bellevue. He deals in all makes and models of cars.

    My second recommendation is for Carfax. After Darrel had bought the car and before I paid for it, I ordered a Carfax vehicle history report for $19.99. It told me that there had been no severe accidents reported, that the odomenter was likely correct, and that it had only had one owner. It also gives the history of when it entered the US, when it was licensed and emission tested, etc. Easily worth the money for the peace of mind.

  • Eric Gunnerson's Compendium

    Part II: The solution explorer and windows forms


    Thanks for all your comments. On the basis of those comments, we've decided not to change the current behavior. There are two things I'd like to bring out.

    First, thanks to Jacob for mentioning that you can set the default behavior. One of the problems we have with VS is that there is lots of functionality that people don't know about. I've added this to my "Things that people don't know about list". So, if you want to change the default, right click and choose "open with". This works for both Windows forms and ASP projects.

    The second concerns options. There were several comments that say, "make it an option, so people can choose", and then Monte Hansen said, "I think there needs to be a gatekeeper for project-level options and if it were me, this one wouldn't make it".

    I agree with that sentiment. In some cases, you have to provide flexibility - for example, if you had a feature that said "braces must go on the line after the if statement", you would make lots of people unhappy. That would be a Bad Thing.

    But there are other cases where adding an option is is the simple way out - either because a team can't agree on what should or shouldn't be there, or because the team hasn't worked hard enough on what the customer wants (these may really be the same thing - not knowing your customers well enough). It's easy to say "let's make it an option", but in a product like Visual Studio, there are already too many opaque options. There may be some interesting ways of fixing this - like making the options that pertain to a window actually be accessible from that window - but in the category of options, fewer is already better.

    I was looking through the options in VS2003 for one where I could say, "Does anybody ever set this option". I had just read Mark's comment:

    One feature that disappeared between 2002 and 2003 that really drives me nuts, was that when you changed between document tabs the project tree view would update to select the current page you are viewing

    and what do I find? Under "Projects and Solutions", there's an option named "Track active item in solution explorer" that I think does what Mark wants. We didn't take the feature away, but we did do a good enough job of hiding it that it appeared that it was missing. That's a good indication of why "make it an option" can be a bad choice - we put effort both into coding something, making it an option, and then testing it, but we hide it so that our users get little benefit from it. Many times the effort to do this just isn't worth the return, as an unfound option is no different than a feature that doesn't exist.

    We had a similar situation back when I was on the C++ compiler team. User asked us for more information to help them find problems in their code, and there were a number of situations that the compiler could identify. Unfortunately, in many cases, the compiler would warn on perfectly reasonable code, and since many people compile with "warn as error" on, we couldn't make them level 2 warnings, as it would break lots of existing code.

    So we made them level 4 warnings, but the result was that since the default was level 2, almost nobody got any benefit out of the work that we did, so we stopped adding new ones.

    Thanks again for your comments

  • Eric Gunnerson's Compendium

    C# Pro Magazine

    C# Pro is coming soon from Informat
  • Eric Gunnerson's Compendium

    Versioning, Virtual, and Override

    Part IV of Anders' interview is up.
  • Eric Gunnerson's Compendium

    A long ride


    Today, I participated in the Tacoma Wheelmen's Heritage Century, a ride through the picturesque Enumclaw valley. Normally, I would have added "in the shadow of Mt. Rainier", but since it was overcast, the mountain was hidden.

    I had hoped to do the whole century (100 miles), but because I got sick a couple of times this summer and injured recently, it wasn't going to happen. I settled for a shorter version. Overall, a pretty good ride. It was much hillier than I had expected. Luckily, I've been suffering on hills for weeks. At one point, I was following a guy up a steep hill - so steep that I had to stand up even though I was in my lowest gear, and during the highest part of the power stroke, my back wheel was spinning up. I put that in the "not fun" category, because if it slips hard, I'm probably going down.

    When I got to the top, I realized I was following a guy with an artificial leg from the knee down on the right side. I'm used to being passed, but usually the people I'm passed by have all their parts. Pretty amazing.

    After I finished that section, I caught up with my wife and daughter, who were doing the 45 mile route with my daughter on her Burley Trailercycle. I hooked her onto my bike for the next 9 miles, and then when we switched back, I found a nice slight downhill and cranked it up to 20-23 MPH for a few miles, and then cruised across the flats to the finish.

    Overall, I'm pretty happy. My legs hurt but never got to the cramp stage, I had enough energy for the whole ride, and my butt didn't start hurting until I'd been riding 3.5 hours. Next year my target is RSVP.

    Vital Stats:

    Distance: 63.5 miles
    Time: 4:36
    Average speed: 13.9 MPH
    Pedal Revolutions: 22,100
    Horses: 155
    Cows: N (where N >> 1000)
    Food: 3 Power bar balance (600 calories), 3 fig newtons (165 calories), 2 energy gell packets (200 calories), 1 1/2 bananas (150 calories), 32 oz gatorade (240 calories). Total = 1355 calories
    Calories used: Approximately 600 cal/hour ~~ 3000 calories used.



  • Eric Gunnerson's Compendium

    Shiver me timbers!


    I've been home sick today, so I didn't get to post this until now.

    Today is "Talk like a Pirate" day

  • Eric Gunnerson's Compendium

    Going to PDC...


    The C# team has finally decided who is going to PDC, and I'm going to California, though I am not going to make a new start, nor do I current have an "achin'" in my heart. (1)

    (1) Too lazy to do a google search, huh? Too young to know better. Okay, just this once: Answer.

  • Eric Gunnerson's Compendium

    A few generics terms


    I've been diving into generics a bit more deeply, and I'd like to share some of the new terminology that will be floating around.

    Open Type

    An open type is a generic type that you've defined. List<T> is a good example. It's called "open" because it's not fully defined without knowing what T is, and therefore you can never have an instance of this type.

    Type Parameter

    The type placeholder that you use when writing a generic type. In List<T>, T is the type parameter.

    Constructed Type

    A constructed type is what you get when you specify a type for a type parameter. List<int> is a constructed type, and you can create instances of it.

    Type Argument

    The actual type you use instead of the type parameter when creating a construct type . In List<int>, int is the type argument.

    Generic Method

    A method that has a type parameter on it.

    static int Process<T>(T t);

    is an example


    Strictly speaking, the number of parameters to a method. In generic terms, it's the number of type parameters on a generic type or method. ArrayList has an arity of zero, while List<T> has an arity of one.

  • Eric Gunnerson's Compendium

    What PMs do for fun...


    Last week, I made a bad joke (I'm the owner of bad jokes for the Visual C# PM team), related to the the concept of arity in generics. I regret that I don't remember the exact joke I made, but we riffed a bit on different permutations (popul-arity, singul-arity, disp-arity). That went on for a few minutes, but we realized that it ws a tough joke to communicate.

    Then Julian (one of our IDE PMs) suggested that we could communicate it better through code. Here's what he suggested:

    class Hil<T>
        // Implementation

    class Jocul<T>


    Once you've done this, then people can discuss the Hil-arity and Jocul-arity of this implementation.

    You may have noticed that we often don't aspire to particularly high standards of comedic expression.

    If you ever want to find words that contain a certain string of letters, I suggest OneLook.

  • Eric Gunnerson's Compendium

    XBox tip of the day...


    Today, I accidentally figured out that the "off" button on my XBox isn't just an off button. It's also an on button, and it's one that doesn't eject the disc first, so you don't have to wait for the tray to come out and push it back in.

  • Eric Gunnerson's Compendium

    Signs you've been playing too much MechAssault...


    You drive into work in the morning, and as you drive around the garage, you see some green objects blocking a stall at the other end of a row of cars. Your first thought is, "Cool! Health!"

    (They were egg crates, but the color match was pretty close)

  • Eric Gunnerson's Compendium

    Visual Studio linked to "lousy problem-solving skills"

    Eric Sink presents an insightful analysis
  • Eric Gunnerson's Compendium

    A story...


    My daughter just started a new science unit in her 4th grade class. After she explained it at dinner tonight, I told her a story that I thought I'd share with you.

    One day, a farmer got up, got dressed and went outside to the barn. He got out his tractor and took it out to his alfalfa field, which he needed to plow under after harvest.

    He spent the whole day plowing, and finished the field. He turned his tractor around at headed for home, but as he reached the edge of the field, it mysteriously stopped. He backed up, and tried again. And again. No matter what he tried, he could not get out of the field. He left the tractor and walked home.

    The next morning, he got up, called the John Deere repair service, and sat down to wait. At 10AM, the mechanic arrived, and they walked out to the field. The mechanic patiently listened to the farmer's story, shook his head, and started walking away from the field.

    "What are you leaving for?", said the farmer. "You haven't fixed it".

    "There's nothing wrong with the tractor", the mechanic replied. "You've got a magnetic field there".


    After I told that, my daughter rolled her eyes and went back to eating. She does that a lot.

  • Eric Gunnerson's Compendium

    Part III of Anders' interview is up

    Delegates, Components, and Simplexity
  • Eric Gunnerson's Compendium

    Very interesting.


    Roy Osherove writes of some very interesting research in his blog.

    I've always found research about how we read to be fascinating

Page 1 of 1 (25 items)