Monday, August 3, 2015

Azure Application Insights: Know Your Users

(The layout of this blog post is terrible, I know. Blogger.com just seems not to be suitable for pictured step-by-step guides. Or at least not with the amount of effort that I was willing to spend.)

When I was looking for a way to collect voluntary usage statistics for a desktop App, I stumbled upon Application Insights, which is a Microsoft Azure service that is currently in preview. There is an introduction and further readings on MSDN. However, I will give a short summary of which steps to take to set AppInsights up and what the results will look like so you can get a quick glance at what you can expect.

Feature Summary


FeatureUse cases
Track pagesTrack which pages (web), windows (desktop) or screens (mobile) are visited how often by your users and what they load time was.
Track sessionsTrack all active server sessions (web) or running app instances (desktop and mobile).
Track eventsTrack some meaningful events for you, such as clicking of a certain button, choosing a certain option or executing a certain command.
Track metricsTrack how often something in your app happens, how many datasets your users manage with your app or some other averages.
Track web requestsWeb only: Track requests to other web services and how long they take.
Track crashes and tracesTrack detailed information about crashes, exceptions or some other unexpected situation, including full call stacks and many other properties, such as geographical area, operating system, and more.
Custom propertiesAttach custom properties of any kind either to the context that all metrics are collected in, or for each telemetry item itself.
Time rangeSpecify the time range that should be included in the graphs on the App Insights dashboard.
AlertsSpecify alerts that trigger when certain conditions are met (such as when more than 100 exceptions are logged within 15 minutes). This seems to be useful for web services only.
Data exportYou can download data for any kind of telemetry item as an Excel spreadsheet.
Continuous exportIf the one-time export is not enough, you can continuously export to an Azure storage space. This seems to be possible in JSON format only, so you need some hand-crafted code to process the data any further. See https://azure.microsoft.com/en-us/documentation/articles/app-insights-export-telemetry/ for more details.


Requirements


Application Insights runs on Microsoft Azure, so an Azure subscription is a prerequisite. You can use it either on mobile apps (iOS and Android), web sites and services (ASP.NET, WCF, J2EE) or desktop apps (either Classic or Windows Store Apps - in other words: anything written in .NET). AppInsights is free for a limited number of datasets and will cost about $25,- for standard and $100,- for premium accounts. See the pricing table.

Getting Started


For the impatient, there is a TL;DR version of it at the bottom.

To get started, you need to log into your Azure account at the new Azure Portal or register for a new account, and add Application Insights.
When you first log in, it looks something like this:

An empty Azure Portal start screen

The design of the home screen is kept in the tiled style, just like the Windows 8 start page or Windows Phone home screens. I personally find this pretty neat and clear.

You can add Application Insights by hitting the big fat + in the upper left corner and then browse to [Developer Services > Application Insights].

A shortcut on the "Home Screen" will be created automatically for you. But before, you will have to set up your new instance of Application Insights.
Add Application Insights to your Azure account
First you have to select the Application Type. I think this does not influence the capabilities of the instance at all - instead only a few default settings and pinned elements on the dashboard will differ. I find the names a bit misleading, personally, since there is no clear mapping from the name to the underlying technology. E.g. I use the type "Windows Store Application" for a classic desktop application written in C# and WPF.

I have no idea what a Resource Group is, but rumor has it you can find out more here.

If you have multiple Subscriptions you can select the one that should be billed for this AppInsights instance here.

Currently, there is only the "Central US" Location. I guess, if App Insights will find it's users, there will be more locations added.
Set up Application Insights - Step 1 of 2

There is now a new icon on your home screen: "tutorial APPLICATIONINSIGHTS" (I have no clue why the instance name is in lowercase and the service name is in ALL CAPS).

Click this new icon and you will finally find your Application Insights.

Set up Application Insights - Step 1 of 2

You are now on the usage statistics dashboard, which will be the starting point for all analysis. The dashboard is fully configurable and is populated with some default widgets. These, too, are aligned in tiles. The most prominent default tile is the Timeline. You can watch the trend in numbers of metric items of the past week and you will see new items coming in live. All views in Application Insights are viewing live data, which is especially useful for websites I'd imagine.

If you are interested in statistics of a longer time range, let's say half a year, you can easily configure that via the "Time Range" tool button.

I will describe more features after we got some data into our dashboard.

Set up Application Insights - Step 1 of 2

The last step in the Azure Portal before some coding is to copy the Instrumentation Key, which is our unique identifier that we need to provide to AppInsight's Telemetry API that is used to collect and send telemetry data into our Azure AppInsights dashboard.

Set up Application Insights - Step 1 of 2

Collecting data from a desktop app

For our testing purposes, we will create a simple WPF application with three buttons.
Our Test Application
We will track three different telemetry items:
  • Click of Button 1, including the total number of clicks on this button in the running session.
  • Click of Button 2, including the exact timestamp of the click.
  • A crash.
All items share some context information that is initialized in app startup. I chose to set the User ID to a fixed user called "tutorial1" and add a custom property named "app_start" that includes the time when the app was started.
To start collecting data, we need to utilize AppInsight's telemetry API. We can install the required assemblies via NuGet by right-clicking our project in the Solution Explorer, then selecting "Manage NuGet Packages" and install the package named Microsoft.ApplicationInsights (Application Insights Core API).

The class Microsoft.ApplicationInsights.TelemetryClient is the core class that we need to collect data. First, we initialize the Instrumentation Key and the context in MainWindow's ctor:

private TelemetryClient tc = new TelemetryClient();

public MainWindow()
{
    tc.InstrumentationKey = "aea76edd-a119-4ce3-bba0-2a31ec66880d";
    tc.Context.User.Id = "tutorial1";
    tc.Context.Properties["app_start"] = DateTime.Now.ToString(CultureInfo.InvariantCulture.DateTimeFormat);

    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

    InitializeComponent();
}

Then, we will add three event handlers for the aforementioned events that we would like to track:

private int button1Counter = 0;

private void button1_Click(object sender, RoutedEventArgs e)
{
    var ev = new EventTelemetry("button1");
    ev.Properties["click_counter"] = (++button1Counter).ToString();
    tc.TrackEvent(ev);
    tc.Flush();
}

private void button2_Click(object sender, RoutedEventArgs e)
{
    var ev = new EventTelemetry("button2");
    ev.Properties["click_time"] = DateTime.Now.ToString(CultureInfo.InvariantCulture.DateTimeFormat);
    tc.TrackEvent(ev);
    tc.Flush();
}

private void buttonCrash_Click(object sender, RoutedEventArgs e)
{
    object foo = null;
    string crash = foo.ToString();
}

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    if (e.ExceptionObject is Exception) {
        tc.TrackException(new ExceptionTelemetry((Exception) e.ExceptionObject));
        tc.Flush();
    }
}

That's all!
Now we can start this nice little demo app and mash the buttons a few times. Remember that the app will actually crash when you click on Crash!.
When you are done playing with your app, we can head back to the Azure Portal and look at the AppInsights dashboard. As I said earlier, the data is updated live, so the newly created items should be visible immediately. If they are not, just hit "Refresh".


Watch Live Telemetry Data

Voila! There it is: One user, and four crashes - I apparently hit on "Crash!" four times. We can inspect the crashes to see more information.


Inspect crashes

You can see interesting things like how many times the crash occured, how many users where affected. If I initialized the context of the TelemetryClient properly, we could see the affected program versions, devices names and operating systems that the crash happened on. I'm sure that you can imagine that all these properties will be very interesting when trying to fix crashes in your app.

As with any telemetry items, you can even attach custom properties to the crash log, so you can include information that might be interesting in your specific app, such as the title of the active window when the crash happened or even the free disk space or things like that.

You could see these custom properties together with a few other properties that are gathered by default on the "Exception Properties" page.
Exception properties page

If you are not using an online crash logging facility already, this will really take your bug fixing to a new level!

There are similarly useful stats for your custom events that you logged when clicking the two buttons.

Custom event infos

TL;DR


See the feature list and the requirements at the top.
Then, execute these steps:
  • Create an Azure account, if you do not already have one
  • Add [Developer Services > Application Insights] in your Azure Portal
  • Copy the Instrumentation Key
  • Create a new WPF app
  • Add the package "Microsoft.ApplicationInsights" Core API via NuGet
  • Create a Microsoft.ApplicationInsights.TelemetryClient and call TrackEvent, TrackPageView, TrackException, TrackMetric, TrackRequest or TrackTrace.
  • Watch the data appear in the AppInsights dashboard

Code


You can find the full example code on GitHub.

Thursday, June 18, 2015

Hacky and Clean Programming

When I do programming, I do it in either of two "modes". Each of these modes serves a different purpose and I use them at different stages to achieve a goal. It is very important to be aware of the current stage you are in, because programming in the wrong mode can be most harmful for either productivity or code quality.

I call these two modes the "hacker mode" and the "clean mode".

Hacker mode

In "hacker mode", I try out either new technologies or architectural ideas. For example, when your current goal is to write a library to control a Bluetooth  device, I would first go into "hacker mode" and try things out and figure out what would be the most efficient and most stable way to use the raw Bluetooth API.

When hacking, I do not care for code quality. I may violate my own guidelines, use ugly casts, name variables "x", "foo" or "data". The uglier, the better. Because I will definitely throw that code away. This is a very important aspect that should not be violated. You have to be aware that you will throw it away, and you have to actually do this in the end. If what you hacked somehow does not work out, throw it away and start with a new hacking session - and throw this one away, too, once you learned the important aspects.

And if you are afraid that, when re-writing what you have hacked before, the Second System Effect (as described by Fred Brooks in The Mythical Man Month) might kick in, I can assure you that with this method I have not yet ever experienced this. I think the Second System Effect applies to larger scales only, and only when putting effort into producing high quality in the first system, too.

After I hacked away and figured out which calls must be made in which order and know the parameters for best results and found a good structure for the API and the implementation, I sit back, have a good look at it and memorize the important parts. Then I stash the code aside for later reference and mentally mark it as "To Be Deleted".

Now I can switch to "clean mode".

Clean mode

I am programming in "clean mode" when I have a good mental model of what I want to create. When I know the important key parts of implementation and have an idea how the API and the architecture should look like. Sometimes this information comes from a hacking session. Sometimes it is just there because I have been thinking about the problem for days, months or even years and now finally decided that everything is clear and can be put into code.

Most of the time, when programming in clean mode, I am doing DDD - Documentation Driven Development. Don't worry, this is not the new hip paradigm that you missed. It's essentially TDD, but I am writing the documentation of the code even before writing the tests.

Most important: The Docs

One major argument why TDD is cool is because you get "a feeling how your code works out when it is put into actual use". The same argument goes for writing docs. When writing docs, I always try to state the important details, not the obvious. When thinking about the non-obvious, you will learn whether the overall design is slick, or does have a few rough edges. With docs and tests combined, you can be pretty sure that the design is sound and that it works out well in practice.

There are a few, easy rules to follow when writing docs. This is especially important when writing them before the actual implementation.

First, it must be clear what the core function of the element you are documenting is. If there is not one core function, but multiple tasks  that are accomplished, you are most likely doing it wrong. Describe the core function of the element in one sentence, i.e. in a @brief.

Second, state the preconditions that must be met to use the element. The less preconditions you can name, the better. If there are no preconditions that are not enforced by the type system, you are doing it right. If the type system is not strong enough to express the constraints of the input parameters, document them in detail. The rumor has it that Haskell has an awesome type system, but unfortunately I have had not yet a chance to use it for productive work.

Third, and maybe most important for maintenance, state the side effects that may happen and which conditions they may likely happen under. If you are a really good programmer, you are writing functional code and can skip this part. You simply do not have side-effects then.

Additionally to these, the standard rules obviously apply: Describing each parameter in detail, possible exceptions thrown, how the return value has to be interpreted, etc.

While I do this, I always have two aspects in mind:
1. What actual use does the element have for a potential user and which goals would he target?
2. How will I possibly implement this element?

And it is very important not to get distracted by the implementation and create a bad API that does not resemble the tasks that a user of the class want it to accomplish, but instead just wraps the underlying technology. But it is also important to not create APIs that can not possibly be implemented in any reasonable way, or the performance will suffer considerably. You should avoid leaky abstractions for (nearly) all costs, but there is often a limit to this. (This is often worth prototyping in hacky mode.)

When I am done writing the docs, I begin writing the tests and see how my idea of how the API might be put to use actually performs. I use the docs that I have written and the side-effects and corner-cases that I have described to derive test cases and therefore get a pretty decent coverage.

I often draw some rough pseudo-UML to visualize the dependencies and relationships.

When actually implementing the functionality, I apply all the lessons that you have learned from Clean Code. I am aware of the docs and update them, when necessary. This may also lead to redesign the API and therefore the tests. I am consciously taking the risk that implementation details that do not fit into the API are costly, because I have experienced it many times that this approach is worth it, since it results in well architectured, maintainable, clean and most importantly easy to use code.

Final notes

As stated in the beginning, it is most important to distinguish these two modes of programming and apply the correct one in each situation. Also, I would advice against using a mixture of both. Do not write hacky code in a clean code base and do not write clean code while hacking. It is just not worth it, because you either harm your code bases quality or are less productive than you could.

Only do hacking in fresh, isolated code bases that are drilled down to the minimal. This of course requires you to isolate parts and think of good, small components to build your software in, which is valuable in itself.

Monday, May 18, 2015

The Software Industry is standing in it's own way

The Software Industry is driven by Programming. Without programming, there would not be software, obviously.
The easier and faster programming will get, the better will the software industry deliver innovations, maintain their cash cows, gain customers, make revenue.
But then why is programming so hard? Why does it cost so much and why is it so often done so badly?

Learning a Programming Language is hard


Ever tried to explain to some non-programmer that has never seen or written source-code before how an application or website is built?

They have no clue, not even the slightest, what "programming" really is. In contrast to other complex fields such as architecture, brain-surgery, chemistry or law, the majority of people does not know how programming in principal works.

But they could be excellent programmers, perhaps. They are maybe just not into programming because they are not attracted to fiddling with source files, wading through compiler errors, gathering information from sources spread across the internet and writing expressions that are meaningless to them. (Ever thought about why it is called a "class", anyone?)

And then, there are so many!


Not only non-programmers need to learn a programming language. Especially when seeking a new job after programming for like 10 years for the same company, you will notice that the industry is split afar. Are you a C++ guru? Good luck finding a job if you do not have any embedded companies nearby. Are you a PHP veteran? You will be out of luck if you do not have any web companies in your reach. Wikipedia lists 122 programming languages.

Even if only counting the ones widely in use, you come up with quite a number: Java, C#, C++, C, Objective C, Visual Basic, PHP, Perl, Ruby, Python, JavaScript, COBOL (ugh!), FORTRAN (ugh, too), Object Pascal/Delphi.

And then there are the newcomers and niche-languages, maybe in use by your favorite start-up you would like to apply at: D, TypeScript, CoffeeScript, Clojure, Scala, F#, Go, Rust, Dart, Haskell, Lisp, Lua, Swift, Tcl, Erlang.

Not enough? Then here is a small excerpt from popular domain specific languages: SQL and PL/SQL (in different flavors from different DBMSes), CSS, XUL (for Mozilla Firefox), Regular Expressions, UNIX Shell Script, PowerShell, Matlab, XSLT, UML.

And knowing one of them is not enough


Making it even worse, you often have to use many of them to build a software, especially when doing web development. You need a backend language like Ruby (with the domain-specific framework "on Rails"), a domain specific language inside the UI template. Then you need to write the HTML skeleton and the CSS styles. Most often, you need to write some raw SQL, too. This sums up to SIX languages in parallel use. Have you ever heard bout context switches being harmful for work productivity?

At the company I am currently working for, we are looking for C++ programmers. We create software in the business domain. That doesn't suit too well - most applicants have a very, very technical background with either Matlab or embedded engineering as their main focus. UI and usability is often not important in these fields. Office software meets quite different requirements than mathematical or electrical stuff, that's why low-level programmers are usually not suited for the work we are doing.

But we can not easily hire a, say, web UI and usability expert with HTML, JavaScript and Ruby background. Because learning C++ is very hard, and if you do not already know it, the chance of writing buggy code is very high. So the only way to hire a programmer is either find a good C++ programmer that is not a number cruncher, or we hire a programmer without C++ background and train them before they take on actual work, which is very costly.

And even with the same Language, Things can be different


And even if you are an awesome programmer in, let's say Ruby, this does not get you far. What if the company you want to work for uses a framework that you have never used before and is totally different? Even when you create the same stuff with it. Try to learn Ruby on Rails? That's nearly as much as learning a new programming language. Try to learn Qt when you already know MFC or vice versa? Even harder, since you will fall back to your old habit and create shabby stuff that will not fit the new environment.

How silly this is


Why do we need so many languages, most of them only justified by irrational reasons? Why can't we have only a few programming languages that differ in their fundamental properties and are used in all domains that require these properties? One object-oriented language, one functional language, one declarative language, one data-definition language. Or maybe even only one programming language in different flavors or in different "modes".

Each language's quality would rise, their community would be bigger, making it easier to find help online. You could actually use the language that you learned at your university in your job. The evolution of the language would be quicker, since there will be more parties interested in it. Sure, this will bring up other problems, such as concurrent ideas and visions for the language. But these can be addressed. Or circumvented, if a single organization is responsible for the language. This has worked in the past, for example with UML, Java, C#, OpenGL.

The software industry is strange. No other industry would allow so many different approaches to the same problems at hand, because it does imply a huge financial risk for each company in the industry. The software industry might be just too wealthy or too ignorant to see and address these issues with programming. I think the main cause for the current status quo is because it is so easy to build a new language or a new framework. And the inner drive of many programmers to create "their own baby" instead of making someone else's product better and use it for your own purposes. That's in some way related with the complexity and diversity of current programming languages. Often forks, clones or similar projects are started because the initiator is used to a different programming language. Why would anyone port SQLite to CSharp, if you can access SQLite's C API from within C#?

Sunday, March 3, 2013

Export layers from svg files to png using xslt and inkscape

If you have svg files and you want to export all but one layer, or only some specific layers to png files using the command line (e.g. in an automated batch job or script), you can not do this with Inkscape out of the box. There is no parameter to export only one layer or to export all but one layer or anything similar. Because svg files are actually xml files, you can use xslt to strip out the layers you do not want to export.

Prerequisites

  • You need inkscape and an xslt transformation tool installed.
  • For Windows you can use msxsl
  • For Linux you can use xsltproc.
  • Of course, you need an svg file with multiple layers created with inkscape. (Inkscape uses the <g> tag to create layers and the layer name that you can see and modify in Inkscape is specified in the "inkscape:label" attribute).

Exporting all but one layer

To export all but a certain layer, you can use this xslt template. You just have to change the "inkscape:label" from 'Layer 2' to whatever layer name you want.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    >
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svg:g[@inkscape:label='Layer 2']"/>
</xsl:stylesheet>

Just copy this text into a text-file and save it (preferable with the file extension ".xsl" or ".xslt").
Then, from the command-line, do the following:

msxsl Example.svg YourXsltFile.xslt -o YourNewExample.svg
C:\Program Files (x86)\Inkscape.com YourNewExample.svg --export-png=YourNewExample.png
(Use "xsltproc -o YourNewExample.svg YourXsltFile.xslt Example.svg" instead of msxsl for Linux).

Exporting certain layers

When you want to export just a number of layers, it's better to use this template for the xslt file:
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    >
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svg:g"/>

    <xsl:template match="svg:g[@inkscape:label='Background']|svg:g[@inkscape:label='Layer 2']">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Sunday, October 23, 2011

Better, type-safe dependency properties in C#, WPF

WPF is a great toolkit for graphical user interface programming where you can truly (and easily) separate program logic from user interface.
The dynamic and flexible binding mechanism is powerful, yet easy to use (once you grasp it :D). Because of it's dynamic nature, type safety is often an issue. Even the most fundamental constructs, like declaring a property that you can use as a binding target (called DependencyProperty) requires you to use casts. Here as a simple example that declares a DependencyProperty called Number of type int:

using System.Windows;

class ProgramLogic : DependencyObject {

    public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number", typeof(int), typeof(ProgramLogic));

    public int Number {
        get { return (int) GetValue(NumberProperty); }
        set { SetValue(NumberProperty, value); }
    }
}
As you can see, there are some constructs that you would usually avoid, such as using typeof and - the single worst construct in every programming language - a cast to int in the property's getter.
While describing this to a friend lately, we said to ourselfs: "Why did they choose this construct? C# does have Generics, so why didn't they use it? Even if it would be just a helper function or class, it'd be much better than that.". So we came up with a wrapper to DependencyProperty, which is a bit shorter, and, most importantly, does not require a cast.
class DepProp <PropertyType, OwnerType> where OwnerType : DependencyObject {

    public DepProp(string name) {
        property = DependencyProperty.Register(name, typeof(PropertyType), typeof(OwnerType));
    }

    private DependencyProperty property;

    public DependencyProperty Property {
        get { return property; }
    }

    public PropertyType Get(OwnerType owner)
    {
        return (PropertyType) owner.GetValue(property);
    }

    public void Set(OwnerType owner, PropertyType value)
    {
        owner.SetValue(property, value);
    }
}
The class DepProp (pick a better name when you decide to use it, please) uses two generic parameters. The first one is the type of the property, the second one is the owner's type, which must be derived from DependencyObject. IMHO, using generic parameters is much better than using typeof. These generic parameters are used to guarantee that later calls to Get() and Set() are called with - and return - the correct types. This way, we made the DepdencyObject.GetValue() call type-safe. Sure, the implementation still uses a cast, but what I find most important is that there are no casts spread throughout the whole project. A neat side-effect is that using this class requires a tiny little less typing than the original DependencyProperty. Another nice feature is that you don't need to call a static member function to register your dependency property. Instead, you use new, just like you would do with any other object. Here is the implementation of ProgramLogic using the new DepProp:
class ProgramLogic : DependencyObject {

    public static readonly DepProp<int, ProgramLogic> NumberProperty = new DepProp <int, ProgramLogic>("Number");

    public int Number {
        get { return NumberProperty.Get(this); }
        set { NumberProperty.Set(this, value); }
    }
}
As we can see, the required code is a little less. But the real nice thing is that the compiler can help you pointing out refactoring errors. Let's imagine that you would want to change your NumberProperty to be of type string instead of int. When you change the generic parameter of your NumberProperty declaration and initialization, the compiler would spill out an error in the "normal" property's getter and setter, because the property is still of type int.
I hope that you find this (really) small helper class useful and that it inspires you to write more code like this that makes your overall codebase more maintainable and readable.

Wednesday, July 13, 2011

GridLayout for WPF: Escape the Margin hell

Working with WPF, you surely have come across the System.Windows.Controls.Grid class. It is a derivation of System.Windows.Controls.Panel, which in turn is a base class for layouters. You can use a Grid to create windows that have their child elements arranged in a uniform manner.

When you have worked with the Grid class, you probably know about this issue: Adding elements to the Grid will make them be strung together without any spacing between them. When you want to add spacing, you have to set each element's Margin property accordingly. This wouldn't be half as bad - it's just that, depending on where in the Grid your element is, you have to set the left, top, right and bottom margins differently. This can become quite a tedious task and makes your XAML look far more complicated than it needed to be. And that's not all - imagine you putting together a prototype of a very complex UI. Just think about one of those equalizer/sound processor programs that have dozens of controls arranged in a grid. You finally finished your prototype - you think it looks awesome - and show it to your boss. His face turns to a disgusted visage and he says "Why is it all so clung together? You can barely tell the buttons apart since they are too near to each other. Can't you add more space between them?". With the standard Grid class, you would gasp, look a bit depressed and tell your boss to come again in an hour or two. And when he comes around and wants to look at your updated prototype, you are still not finished changing all the margins correctly.

Forget that scenario. Use the GridLayout class from the download below and change all margins at once. It automatically sets a uniform margin to all child elements of this specialized Grid class. And even better - it is smart enough to set the Margin.Left of elements in the first column to 0. The same goes with the Margin.Right in the rightmost column, Margin.Top in the first row and Margin.Bottom in the last row. With this class, you simply change the newly introduced ChildMargin property and be done - you will see the effect of the changes immediately, live in the WPF designer and at runtime.

Here is a screenshot of a simple form done with the default System.Windows.Controls.Grid class - without setting any special margins. You can see how narrow the space between the elements is and that it does not look very appealing.

Default Grid form example

And here is the same form done with the GridLayout. Note that only the class of the Grid has been changed - the child elements are exactly the same.

GridLayout form example

The best of all is that this has been done in very few lines of code. It just took two steps: The first was to introduce a new property in a class that derives from System.Windows.Controls.Grid that would define the margin that the cild elements of the new Grid would use. The second set was overriding

protected void MeasureOverride(Size)
that has been introduced in FrameworkElement. The overwritten version of MeasureOverride enumerates all children and changes their Margin accordingly. After that, the base version of MeasureOverride is called. This makes sure that, before each arrangement, the margins are updated correctly.

Here is the complete source-code of the GridLayout:


using System.Windows;
using System.Windows.Controls;

namespace GridLayoutTest
{
    // The GridLayout is a special Panel that can be used exactly like the Grid Panel, except that it
    // defines a new property ChildMargin. ChildMargin's left, top, right and bottom margins will be applied
    // to all children in a way that the children will have a vertical space of ChildMargin.Top+ChildMargin.Bottom
    // and a horizontal space of ChildMargin.Left+ChildMargin.Right between them.
    // However, there is no margin for the borders of the internal widget, so that the GridLayout itself can be
    // aligned to another element without a margin.
    // It's best to have a look at TestWindow, which effectively tests all possible alignments of children.

    public class GridLayout : Grid
    {
        public static readonly DependencyProperty ChildMarginProperty = DependencyProperty.Register(
            "ChildMargin",
            typeof(Thickness),
            typeof(GridLayout),
            new FrameworkPropertyMetadata(new Thickness (5))
            {
                AffectsArrange = true,
                AffectsMeasure = true
            });
        // The child margin defines a margin that will be automatically applied to all children of this Grid.
        // However, the children at the edges will have the respective margins remove. E.g. the leftmost children will have
        // a Margin.Left of 0 and the children in the first row will have a Margin.Top of 0.
        // The margins that are not set to 0 are set to half the ChildMargin's value, since it's neighbour will also apply it,
        // effectively doubling it.

        public Thickness ChildMargin
        {
            get { return (Thickness)GetValue(ChildMarginProperty); }
            set 
            {
                SetValue(ChildMarginProperty, value);
                UpdateChildMargins();
            }
        }

        // UpdateChildMargin first finds out what's the rightmost column and bottom row and then applies
        // the correct margins to all children.

        public void UpdateChildMargins()
        {
            int maxColumn = 0;
            int maxRow = 0;
            foreach (UIElement element in InternalChildren)
            {
                int row = GetRow(element);
                int column = GetColumn(element);
                if (row > maxRow)
                    maxRow = row;
                if (column > maxColumn)
                    maxColumn = column;
            }
            foreach (UIElement element in InternalChildren)
            {
                FrameworkElement fe = element as FrameworkElement;
                if (null != fe)
                {
                    int row = GetRow(fe);
                    int column = GetColumn(fe);
                    double factorLeft   = 0.5;
                    double factorTop    = 0.5;
                    double factorRight  = 0.5;
                    double factorBottom = 0.5;
                    // Top row - no top margin
                    if (row == 0)
                        factorTop = 0;
                    // Bottom row - no bottom margin
                    if (row == maxRow)
                        factorBottom = 0;
                    // Leftmost column = no left margin
                    if (column == 0)
                        factorLeft = 0;
                    // Rightmost column - no right margin
                    if (column == maxColumn)
                        factorRight = 0;
                    fe.Margin = new Thickness (ChildMargin.Left   * factorLeft,
                                               ChildMargin.Top    * factorTop,
                                               ChildMargin.Right  * factorRight,
                                               ChildMargin.Bottom * factorBottom);
                }
            }
        }

        // We change all children's margins in MeasureOverride, since this is called right before
        // the layouting takes place. I was first skeptical to do this here, because I thought changing
        // the margin will trigger a LayoutUpdate, which in turn would lead to an endless recursion,
        // but apparantly WPF takes care of this.

        protected override Size MeasureOverride(Size availableSize)
        {
            UpdateChildMargins();
            return base.MeasureOverride(availableSize);
        }


    }
}

You can download a complete project with an exhaustive test scenario here:

GridLayout test window

Download

Edit: I forgot to take the ColumnSpan and RowSpan into account in the first version. This lead to margins being too large when an element with a Column- or RowSpan was spanning to the rightmost or bottommost row or column. This has been fixed in version 1.1. Download link has been updated.

Wednesday, May 18, 2011

Using .NET and WPF in Win32 legacy applications, Part 1: The basics

Introduction

There are applications that are just impossible to port to any new technology, because of sheer size. Unfortunately, most of these applications are very important to their creators, such as commercial applications that have been developed for decades. Those applications often matured over the time and are satisfying a broad range of users. Rewriting these in a new programming language or a new framework, while being economical, would be impossible.

That's why interoperation and downwards-compatibility is something every new platform should provide. .NET, with it's new Windows Presentation Foundation (WPF) is one of these platforms. You can use .NET in the (from Microsoft's point of view) "legacy" C++ programming language through C++/CLR. And you can use WPF controls and windows in the now deprecated WinForms classes using the "interop" class System.Windows.Interop.HwndSource. Fortunately, since WinForms is built on raw Win32 API under the hood, this HwndSource class is suitable to be used to integrate WPF with raw Win32 applications as well. And it's not that hard at all.

For the impatient among us, you can directly skip to the download and look at the source code. It's only a few dozen lines of code.

Getting started

To get started, we will create a new, empty C++/CLR project. We need C++/CLR, since, obviously, we need to access .NET from either C or C++ source code. I will assume that the "legacy" application you want to use WPF in is a C++ project, since C projects can easily be ported or integrated with C++ code.

Step 1: Creating a new C++/CLR project

In Microsoft Visual C++ 2010 Express, you do that by choosing File -> New -> Project from the menu. Then you select Visual C++ > CLR > CLR Empty Project as the template. I picked win32wpfinterop as the project name, but you can use any name you want. When you hit OK, you will have a new, empty project.

Step 2: Building the Win32 window skeleton

Since C++/CLR is a superset of the "normal" C++ that you write in Visual C++, you can use the Win32 API just as you please. The window example skeleton does not differ from normal C++ at all. Add a new C++ File to the Source Files folder (filter) and add your Win32 window code. Here's how my code looks:

#include <Windows.h>

// Constants
namespace {
   TCHAR * windowClassName = TEXT("win32host");
   TCHAR * windowTitle     = TEXT("Win32 Host (Win32 WPF Interop)");
   int          windowWidth     = 200;
   int          windowHeight    = 100;
}

// Window message procedure
LRESULT CALLBACK WindowProc(
  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam)
{
   switch (uMsg) {
   case WM_DESTROY:
      ::PostQuitMessage (0);
      return 0;
      break;
   default:
      return ::DefWindowProc (hwnd, uMsg, wParam, lParam);
   }
}

// Main program entry  point
[System::STAThread] // This is IMPORTANT, but it's for in C++/CLR  only
int CALLBACK WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPSTR lpCmdLine,
   int nCmdShow)
{
   // Register our Window class
   ::WNDCLASS wndclass;
   wndclass.style = CS_VREDRAW | CS_HREDRAW;
   wndclass.lpfnWndProc = &WindowProc;
   wndclass.cbClsExtra = 0;
   wndclass.cbWndExtra = 0;
   wndclass.hInstance = hInstance;
   wndclass.hIcon = NULL;
   wndclass.hCursor = NULL;
   wndclass.hbrBackground = reinterpret_cast <HBRUSHgt; (COLOR_BTNFACE + 1);
   wndclass.lpszMenuName = NULL;
   wndclass.lpszClassName = windowClassName;
   ::RegisterClass(&wndclass);

   // Create our main, raw win32 API window
   // We create the window invisible (meaning that we do not provide WS_VISIBLE as the window style parameter), because making it visible and then
   // adding a HwndSource will make it flicker.
   HWND mainWindow = ::CreateWindow(
      windowClassName,
      windowTitle,
      0,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      windowWidth,
      windowHeight,
      NULL,
      NULL,
      hInstance,
      0);

   // Now that setting up the HwndSource is finished, we can finally make our window visible
   ::ShowWindow (mainWindow, SW_SHOW);

   // Start message processing
   ::MSG message;
   while (::GetMessageA(&message, 0, 0, 0)) {
      switch (message.message) {
      case WM_QUIT:
         break;
      default:
         ::TranslateMessage(& message);
         ::DispatchMessage(& message);
         break;
      }
   }
   return 0;
}

Download here

Yeah I know, it's a bit length ;-) but that's just how Win32 code is. The good news is that adding WPF components is much less code than this skeleton. Here is how your window should look like:

Empty Win32 Window

You need to add the User32.lib to your references, since the functions we used are defined in the Windows' User32 library. You need to right-click on your project in the Solution Explorer and choose Properties. Then navigate to Configuration Properties > Linker > Input and add User32.lib as an Additional Dependency.

Step 3: Create a HwndSource

Before we will be going to use WPF classes, we need to add the required WPF Assemblies to our project references. Right-click your project in the Solution Explorer again, but this time choose References. Now press Add New Reference and get a cup of coffee, while Visual Studio loads every registered .NET assembly. (This has become much faster in Visual Studio 2010, but it is still unbearably slow.) We will need the following assemblies to our project: System (for String), WindowBase and PresentationCore (for HwndSource) and PresentationFramework (for Label).

As the simplest example, we will be adding Label (type System.Windows.Controls.Label) to the window in this tutorial. But we can not just add a Label object to the Window -- the Label class has no members that would take a HWND as the parent class or anything like that. Instead, we need to create an intermediate object that builds the very bridge between Win32's HWND and WPF's System.Windows.UIElement. That intermediate object is of the aforementioned type System.Windows.Interop.HwndSource. Creating a HwndSource-object is very similar to creating a new win32 control - The HwndSource constructor basically takes the same parameters as WinAPI's RegisterClass () and CreateWindow() do. We create a HwndSource using this call:

System::Windows::Interop::HwndSource ^ hwndSource = gcnew System::Windows::Interop::HwndSource (
      CS_VREDRAW | CS_HREDRAW, // window class styles
      WS_CHILD,                // window flags
      0,                       // extended windows styles
      0,                       // x position (will be overridden later)
      0,                       // y position (will be overridden later)
      "WPF Interop",           // window title (not visible)
      static_cast <System::IntPtr> (mainWindow)); // parent window

HwndSource is, at the same time, a pure HWND-style window and a WPF UIElement. This means it can be hosted by another HWND (because we passed the WS_CHILD flag), but can host a WPF UIElement itself. And since being able to host one element in WPF means that you can host any number of elements (e.g. by using a Grid), you have the ultimate freedom to embed complex controls written in .NET and WPF in your Win32 application.

Step 4: Finally, add the Label

It's a bit tricky to get hold of the HWND window handle of HwndSource, because of .NET and C++ type differences. The HWND is available as a System.IntPtr. You need to call ToInt32 and reinterpret_cast it to a HWND like so:

HWND hwndSourceHandle = reinterpret_cast <HWND> (hwndSource->Handle.ToInt32 ());

Now we can call any Win32 API functions on that HWND, such as SetWindowPos:

::SetWindowPos (
      hwndSourceHandle,
      NULL, // ignored
      10,   // x position
      10,   // y position
      180,  // width
      80,   // height
      SWP_NOZORDER | SWP_SHOWWINDOW);

The HwndSource now exists, but that alone is not much of a gain. It's not even visible. You need to create some visible WPF control and add that to the HwndSource. Adding to the HwndSource means setting the control as the HwndSource's RootVisual. Here's how you can do this:

System::Windows::Controls::Label ^ label = gcnew System::Windows::Controls::Label ();
label->Content = gcnew System::String ("WPF Label -- it works!");
label->Background = System::Windows::Media::Brushes::White;

hwndSource->RootVisual = label;

When you insert this code between the call to ::CreateWindow() and ::ShowWindow(), you will experience your first moment of success and a window like this should be visible:

Win32 Window with WPF Label

Controls that don't required keyboard focus work very good. Controls with keyboard focus work good, too, as long as there are no other controls in the host window that may steal the focus from WPF. The next part will be about making keyboard handling and focusing work correctly, so stay tuned.
(Don't expect it before June or July 2011, though)

There's a complete example project for Visual C++ 2010 (build with VC++ 2010 Express) with commented source code for download.

Download

And besides: You can build a window's complete content in a C# class library e.g. as a UserControl, add that class library's assembly as a Reference in your C++/CLR's project and go ahead and use it in this interop framework we just built. This basically means that you can embed C# windows and controls in your legacy C++ application.

Friday, April 1, 2011

Avoiding Anti-Aliasing when drawing Rects, Lines in DrawingVisual's DrawingContext

When building my own high-speed grid control recently, I came across the problem that, when drawing the grid lines, they were anti-aliased and looked very ugly. I searched the web and came up with nothing for phrases like "anti aliasing drawingvisual" or "blurry lines drawingvisual" or even "crisp lines drawingvisual". None of them returned any result, until I came across an answer on StackOverflow (which I currently can't find again).

The solution is very easy, while not even remotely logical to anyone not knowing the deep internals of DrawingVisual. First, here is what you usually would try to draw lines from position (10, 10) to position (200, 10):

drawingContext.DrawLine(new Pen (Brushes.Black, 1), new Point(10, 10), new Point(200, 10));

The result would like something like this:

Non-antialiased line

As you can see, the line is not really black. And it is not one pixel wide. That's because it is rendered "blurry".

The obvious, totally intuitive way (oh, did you notice the irony?) to avoid this, you have to do this:

drawingContext.DrawLine(new Pen (Brushes.Black, 1), new Point(10.5, 10.5), new Point(200.5, 10.5));

And here is our desired result:

aliased line

Yes, you have to add 0.5 to your fraction-less position. And you will get pixel-perfect lines. This works for DrawRect, too.

Here's a full example with some grid lines:

class DrawElement : FrameworkElement
    {
        protected override void OnRender(DrawingContext drawingContext)
        {
            double x = 10.1;
            Pen pen = new Pen(Brushes.Black, 1);
            while (x < ActualWidth)
            {
                double actualX = Math.Ceiling(x) + 0.5;
                drawingContext.DrawLine(
                    pen,
                    new Point(actualX, 0),
                    new Point(actualX, ActualHeight));
                x += 10.1;
            }

            double y = 10.1;
            while (y < ActualHeight)
            {
                double actualY = Math.Ceiling(y) + 0.5;
                drawingContext.DrawLine(
                    pen,
                    new Point(0, actualY),
                    new Point(ActualWidth, actualY));
                y += 10.1;
            }
            base.OnRender(drawingContext);
        }
    }

And here's the result:

Tuesday, December 7, 2010

Listen to what Microsoft has to say about using colors in user interfaces

I just stumbled upon a very interesting and important article on MSDN about colors and their use in user interfaces.

After the fundamentals of different colors spaces are explained, the article continues with design concepts and guidelines that are important to every software developer not exclusively programming on monochrome displays. It highlights the fact that a large portion of the male population has difficulties distinguishing colors and links to the publication Can Color-Blind Users See Your Site?, which describes this topic in more in-depth. But not only color blind people will get annoyed by software that uses colors that are hard to distinguish.

Another highlighted aspect are themes and the possibility for users to change their software visuals to their liking. Those wishes should be respected by every software developer and designer.

The primary goal of a user interface is to ease the user's perception of what is going on and/or how he can accomplish what he currently wants to do with your software. There are many different ways to make this as easy as possible, and icons and colors are a very important part of it. But there are many things you can do wrong when styling your application. You have to take factors like different display hardware and lighting conditions, people's unique color perception and individual themes into account.

Wednesday, August 18, 2010

What include guards in C++ are, and what they are not

And why they do not solve "multiple definition" errors.

Include guards are heavily used in C++ and you see them in virtually any code base (that has more than two files). Sometimes there is a bit of confusion what they do, and what they can not do. I decided to explain everything in detail, so I ended up explaining the whole C++ compilation process of preprocessing, compiling and linking your application or library.

Introduction to include guards

First, it's important to know that include guards are not a language feature. They are a technique that use standard preprocessor features to solve a common issue. Namely, they avoid that one header is included multiple times. Let's assume a simple example of two files: test.cpp and the corresponding test.hpp:





test.hpp:
class Test
{
   public:
      void foo();
};
test.cpp:

#include <test.hpp>
/* Some more includes */
#include <test.hpp> // Error! class Test is already defined

void Test::foo()
{
   // Do something here
}

int main()
{
   Test test;
   test.foo();
}

As you can see, test.hpp is included two times in this example. This might not be common in the same implementation file, but when the list of include files is very long, this might very well happen. Remember that an #include is basically the same as when you copy & pasted the content of the included file at this very position. Only that this is done for you by the preprocessor. The resulting code when you run test.cpp through a preprocessor will look like this:

test.cpp - preprocessed

class Test
{
   public:
      void foo();
};

class Test
{
   public:
      void foo();
};

void Test::foo()
{
   // Do something here
}

int main()
{
   Test test;
   test.foo();
}

It should be obvious now why the error occurs. You can't define two classes with the same name in the same translation unit. And that's where the include guards come to the rescue. The basic idea behind include guards is: Do something in the header that will make the preprocessor not "copy & paste" the content into the including implementation file a second time. Besides getting rid of duplicate declarations, this even speeds up compiling, since otherwise the compiler would have to process the same content twice. This goal is achieved by checking whether a certain preprocessor macro is defined. If not, the macro will be defined so that a second check will notice that it is already there, which means that the header is already included. Here's how it is be done:

#ifndef TEST_H
#define TEST_H

class Test
{
   public:
      void foo();
};

#endif

This is what happens, from the viewpoint of the preprocessor:

  • 1st Include of test.hpp
    • Is TEST_H defined? - no
    • Define TEST_H
    • Include content of test.hpp
  • 2nd Include of test.hpp
    • Is TEST_H defined? - yes
    • Skip to the #endif direction
    • Include everything in test.hpp after the #endif

      (In 99.9%, this should be empty)

This leads to the desired result for the preprocessed test.cpp, even when we include test.hpp twice:

test.cpp - preprocessed with include guards
class Test
{
   public:
      void foo();
};

// Here should be the second include, which has been avoided by the include guard

void Test::foo()
{
   // Do something here
}

int main()
{
   Test test;
   test.foo();
}

Compiler-specific directions, #pragma once

Since include guards are so common, some compiler vendors (read: Microsoft) decided to create a special directive for them. You might have come across the statement #pragma once while reading through code. This #pragma once is all three preprocessor-directives in one. It replaces the #ifndef, the #define and the #endif (where the #endif is always at the very end of the file). As this is a vendor-specific directive, not all compilers support it. One reason for this may be because it does not solve a problem that couldn't be solved otherwise. This is why you should obide the following, simple rule:

Don't use #pragma once

Because:

  • It's compiler-specific and is not portable
  • Because of this, not everyone reading your code might know it
  • It does not offer big advantages over the "classic" include guards.
(I said "big" advantages. As noted on the Wikipedia article for #pragma once, Visual C++ includes optimization code that makes headers using #pragma once be skipped faster than classic include guards. While this might be desirable, I can't imagine that in practice it will be of great benefit. And, after all, GCC includes optimization for classic include guards, too, which might render the speed improvements of #pragma once on Visual Studio minimal.)

The compile process: Preprocess, compile, link

To fully understand the issue at hand, you have to know how the whole compilation procedure for C++ works. It is divided into three steps.

The first step is the preprocessor. Everything that starts with a # sign is a preprocessor directive. The most common ones are #define, #ifdef or #ifndef, #endif and so on. The preprocessor is essential to C++ because it's the only pragmatic way to split up declarations and definitions and make the same function or class usable from multiple implementation files. The preprocessor is called upon each implementation files (to make this clear again: These are usually called .cpp). The implementation files include header files (and should never include other implementation files). All preprocessor directives in the header files will be processed, too, which means that you can #include other files in the header, #define macros and create include guards. The result of a preprocessed implementation file is a large file that includes every included header, and of course the header included of those headers, and so on. For headers that use libraries such as the standard library, boost, Qt or something like this, the result will often be huge.

The second step is the compilation. This huge mess - also called the translation unit - will now be run through the compiler. Yes, the compiler only compiles one file. And this is not the .cpp file you might have passed on the command line or that you added to the project. It will be a file generated from the preprocessor that does not even remotely resemble your original .cpp file (except for the very bottom part). Most noteworthy, you will not find a single preprocessor directive (like #define) in this resulting file, since they all have been already processed by the preprocessor. The result of the compilation is the object file. The object file is not human readable and does not include source code anymore. Instead, it includes so-called symbols and their content, which might be variables, constants, functions and virtual function tables. This is why you usually have one object-file in your compiler's working directory (this is the Release and Debug directories for Visual Studio. GCC puts the object-files right where your .cpp file is, if you do not specify a file explicitly) for each implementation file in your project. You don't have object files for headers, because they are not individually compiled. They are only "glued" on top of your implementation files. At this point it is important to know that when the compiler creates a function call, it does not include the absolute address of the function in the generated code. Instead, it includes the symbol of that function. In C, this simply is the function's name. In C++, it's the function's name mangled with some meta-information that depends on the compiler. It's very similar with global variables and virtual function tables. They are not referenced by an absolute address, either, but via their symbol name. This means that the object files created by the compiler do not include machine code that is ready to be executed. The symbols have to be replaced with their absolute addresses. And this is where the linker jumps in.

The third and last step is the linking. Just like the compiler, the linker does not know about header files. And it does not know about implementation files, either. It only knows the object files and the linker's job is to link all object files together to one executable or library, that can finally be interpreted by the hardware. It does this by pasting all object files into one, and whenever a symbol occurs (this might be in a virtual or static function call or when referencing a global variable, for example), it replaces this symbol with it's absolute address. That is why you sometimes get errors like "Symbol xyz is already defined in foo.obj". This means that you defined a function or variable in two different translation units, which will generate the same symbol. This is not allowed per One Definition Rule because the linker would not know which of them it should use.

Multiple definitions

There are two ways you can cause multiple definitions of the same symbol: You accidentally define the same global variable or function at two distinct places (e.g. one time in the header and a second time in the implementation file) or you include a header that defines a global variable or function in two separate translation units. The first issue is handled by the compiler. As this double definition is in but one translation unit, the compiler notices that the identifier in question is already declared (and probably defined) and bails out. Here is an example of a double definition of a function foo():

test.hpp
void foo() { } // Note the empty function body!

test.cpp

void foo()
{
   /* Do something */
}

This sometimes can happen when changing a function to be inline and forgetting to remove the original definition.

The second issue is a bit more tricky.
Remember that a translation unit is the implementation file prepended by all included headers. So we take the same header as before, defining an inline function void foo() { }. But this time, it is included from two files in the project, one named test.cpp and the other named test2.cpp:

test.hpp
void foo() { }

test.cpp
#include "test.hpp"

// The actual content of the program is irrelevant
int main ()
{
}

test2.cpp
#include "test.hpp"

// Here are some functions defined in test2.cpp

When you compile this project, you will get an error message along the lines of

multiple definition of `foo()'
. This is because both translation units define a symbol foo, which is prohibited by the holy One Definition Rule.

Include guards to the... rescue?

So, you might think .o( When the function may not be defined twice, let's wrap test.hpp in an include guard! ). Try it and see for yourself. It will not make a difference. This is because the preprocessor will be run for each implementation file separately, leading to two distinct translation units. When test.cpp is preprocessed, TEST_H will not be defined and the header's content will be included in the resulting translation unit. Then the resulting code is compiled, leading to a test.o or test.obj, without any error. There is only one declaration and definition of the function in this translation unit, after all. When the second implementation file is being preprocessed, the preprocessor starts over, which means that #defines made in the first translation unit will not be available in the second or any other preprocessing. This means that TEST_H is still not defined for test2.cpp, so foo()'s definition will be included a second time. It will now be compiled into test2.o or test2.obj. foo() will be defined in both, test.obj and test2.obj.

The final step is the linking, which should lead to an executable or machine-readable library. But the linker notices that foo() is defined two times, prints the aforementioned error message and aborts it's task. Because the linker does not even look at the source code that the object files were compiled from, it does not know where the double definitions occured. In fact, the linker even works without the source code being available.

This means that include guards do not solve multiple definition errors.

Friday, April 23, 2010

Samsung N150 Eliah Netbook review

I recently bought a white Samsung N150 netbook because I need it for my upcoming vacation in Japan. There are two target audiences for netbook users: Customers with a limited budget and customers that appreciate the small size and high portability of such devices. In my case, both was true. Since I've spent most of my money on my trip to Japan, I was not able to buy a laptop for like 600-700€ or something. Additionally, I wanted something small that would easily fit in my backpack, including a protectional case, and that does not weigh too much. With it's 10" display and a total size of 180x264mm (10.4"x7.4") and a weight (including battery) of 1240g (2.73 lbs), it fully meets my mobility expectations. You don't even notice the weight when carrying it in a backpack or bag.

Specs

Here are some additional specs: Like almost every netbook, the N150 features an Intel Atom at 1,6 GHz. It already uses the newer generation that has been introduced at the beginning of this year. The screen's resolution is 1024x600 pixels, displayed by an Intel GMA 3150 chipset. The resolution can be scaled to 1024x768 for applications that need this resolution, but it then obviously looks ugly. There is an external VGA plug that can output up to 2048x1536 pixels. Neat! I already tried to connect my HDTV and it perfectly works a Full HD 1920x1080 resolution. The N150 ships with Windows 7 Starter and a few drivers, utility software and games pre-installed. On the first boot, the installation is automatically being finalized, which took something like 2 hours, d'oh. In the setup process, you can choose the sizes of the two partitions that will be created. You have a total of 250GB harddisk available for your needs. I chose to have a 80GB system partition and left the rest for data storage. Because Windows 7 Starter only supports 1 GB of memory - you have to upgrade to Windows 7 Home Premium for something around 80€ when you want more - the netbook has only 1 GB of DDR2-800 installed. The memory can easily be upgraded, because there is a special removable cover to access the module. Another limitation in Windows 7 Starter is that you can't use the external monitor as an extended desktop. Only cloning of the image is allowed. The problem with not being able to change your desktop wallpaper on Windows 7 Starter can be circumvented using this trick.

Connectors

It comes with a total of 3 USB ports, two on the right and one on the left. The one on the left is the only one that can be used with devices that draw power from the USB port and is labeled with a small "power" symbol. You can enable and disable the power output on this port with a special utility that comes pre-installed. Microphone and external speakers or headphones can be connected via two separate plugs. The aforementioned VGA connector is on the right side, while the ethernet cable can be plugged in on the left side, next to the round, relatively small power connector. Only 10 and 100mbit ethernet are supported - so no gigabit ethernet on the netbook :-( The AC adapter works with 100 to 240 volts, making it perfectly suitable for my stay in Japan. Quite hidden is an SD-card slot beneath the touchpad with the typical, somewhat fiddly cover. It supports the SD, SDHC and MMC formats.

Internal peripheral

That's it for the connectors for possible external peripheral. There already are some nice hardware pieces built in. One of it is the mandatory 802.11 b/g/n WLAN, but Bluetooth is also included, which can be quite handy to transfer pictures from your cell phone when you don't have a suitable (and usually expensive) cable at hand. While you can plug in an external microphone, there is already one built in. It's located next to the touchpad, which was kind of a stupid decision because you easily cover it with your hand when using the touchpad. I used it to Skype with friends and they said that the quality was very good - which surprised me, because it is so tiny. The webcam has a resolution of 320x200 pixels and is very slow. It's not that much fun doing video-chat with it, because you hardly see your movements. A software from Cyberlink is included that can be used to toy with the recorded picture. But it's actually not that great, either. What really bothers me is that there is no hardware switch or other means to disable or cover the webcam. When you got malware installed that can remote-control your webcam, you will never notice. There is no indicator whether the webcam is active or not, either.

Keyboard and touchpad

Being very small, the keyboard obviously does not come with a standard layout. The keys Insert, Delete, Enter, Page up, Page down and the arrow keys are directly accessible. Home and End, on the other hand, are only accessible by pressing the Fn key that's located between the left Ctrl and Windows keys. This is actually the only thing that requires some time getting used to. The rest of the layout is nice and I could immediately touchtype on the keyboard. Too much typing leads to numb fingers (at least for me, of course), because the keys are pretty hard. The numblock keys are located on the regular character keys and can be activated by pressing Numlock (only availble via Fn key). When pressing Fn and the designated numblock keys, they have the same function as the deactivated numblock keys. The F-keys have special functions that can be used by pressing the Fn key:

  • Escape: Sleep
  • F2: Battery status
  • F3: Euro sign (€)
  • F4: Switch monitor modes (when an external monitor is attached)
  • F5: Switch backlight on/off
  • F6: Mute sound
  • F7: Samsung Support Center
  • F8:
  • F9: Disable/Enable WLAN
  • F10: Disable/Enable Touchpad
  • F11: Numlock on/off
  • F12: Scroll lock on/off
  • Insert: Pause
  • Directional up/down: Brightness
  • Directional left/right: Sound volumne
All in all, the keyboard is very usable, despite the Home and End keys and the mislocation of the <>| key.

The multi-touch touchpad has two buttons - no middle mouse button! Scrolling is done with a two-finger move, which sometimes just doesn't want to work, especially when not sitting directly in front of the keyboard. But most of the time scrolling works very neat. There's also a "three-finger-flick" movement available that's supposed to switch between tabs in browsers, but it doesn't work for me (using Google Chrome as my brother on the netbook). The touchpad's sensitivity can be configured and after configuring for my needs, it works flawlessly (well, most of the time, at least). I bought an external mouse that matched the colors of the netbook, but rarely use it - only when gaming. My overall impression of the touchpad is, keeping it's size constraints in mind, very good. And that's although this my first laptop and I'm not used to touchpads at all.

Software

I removed all pre-installed games before trying them, so I can't tell you whether they are fun or not. A 60-day trial of Microsoft Office 2007 and a full version of Microsoft Works is shipped with the N150, too. The Samsung Recovery Solution is pretty neat. You can easily back up your system partition to your data partition and restore it with only a few mouse-clicks. I think that Samsung Recovery Solution is a re-branded Acronis software. Since I own Acronis True Image Home, I've created a bootable USB-stick with Acronis that I use instead of the Samsung Recovery Solution, though. There are other Samsung tools for: Extending battery life, enable/disable the chargable USB port, manage the display, resolution and network settings and a software to update all Samsung tools. As with all other Windows 7 versions, Windows Live comes for free, which is not at all that bad. For example, you can use the Windows Live Movie Maker to convert movies to a lower resolution when playback is sloppy (which is the case with 720p material).

Working with the N150

When I bought this netbook, I thought that I'd have to live with a number of limitations due to the low-end hardware. I was wrong. The 1.6 GHz Atom with 1 GB of RAM actually performs much better than I had expected. I never ran into memory shortage, even when browsing with a number of open tabs, some of them containing a flash stream. Skype works fast and neat, too, although it warns me that my hardware was too slow. Video playback works great for standard definition videos. 720p videos are a little bit sloppy. It feels like only a few Hertz are missing to play them without stuttering. :-( Using VLC I get much better results than with Windows Media Player or Media Player Classic. I noticed that Flash video streams are very sloppy sometimes, though. I haven't figured out why, yet.

Even when under load, the netbook does not get very hot. It's more like a convenient hand warmer than something that would bother you. The fan and the harddisk are quiet, too, although the constant sound of the harddisk seeks can get on your nerves. You don't hear anything at all when there is some background noise (like a TV or something).

The display's low resolution is less of a problem than I initially thought, too. While there is quite a bit of vertical scrolling, it's not that bad because of the two-finger scrolling move (that works vertically and horizontally, btw). Some applications, however, expect a minimum of 1024x768. That's why you can switch to this resolution and scale it to 1024x600 (which looks ugly, of course, but may be necessary for some buttons to be reached).

But the CPU's missing performance shows in heavy computational tasks such as video transcoding. As I said, 720p videos are not playing without disturbance, so I tried to recode it to 480p using Windows Live Movie Maker (since that's what I had at hand). On my desktop system (a Core i7 860), it took something like 7 minutes, while the netbook was working on it for 1:15 hours. Admittedly, it's not very fair to compare the N150 to a system in which the CPU alone costs as much as the complete netbook.

Gaming

I would never have thought that a netbook could be such a neat gaming device. Of course, it's only older games or games with 2D graphics that run on the N150. But since there are awesome classic games, you can have quite a lot of fun with gaming on this netbook. For instance, you can run Quake III in 1024x600 with something between 30 and 80 fps. Yay! You can play Diablo II on it, too, but it becomes very sloppy, sometimes only one frame every few seconds, when there are many enemies on screen. Go check abandonia.com for old games for free, such as Nightmare Creatures or Blood. There's also gog.com that sell classic games for relatively low prices. Modern "mini-games" like Plants vs. Zombies (you can get it on Steam for half the price) or the extremely famous FarmVille (on facebook) are perfectly playable, too. I even play Beat Hazard (on Steam) using a wireless XBox 360 Gamepad. But of course the device has some limits. I tried Torchlight, a modern Diablo-clone from the original Diablo programmers, but the game was running very sloppy and not playable, although it has a "Netbook mode". You need an Ion-netbook to run it smoothly, I guess. Basically every game released before 2000 should be ok. For later games, I'd try the demo before buying it. I ran the oldest available 3DMark, 3DMark03, and scored 670 points. Doesn't sound amazing, but seems to be enough :-)

Conclusion

I am very happy with this device. The price-tag is friendly to your wallet, the size is portable and the material quality is great. There are a few drawbacks (such as not being able to turn off the camera and a missing middle mouse button), but when you can live with them, there's nothing you can complain about. I have had much fun with it so far, and am sure it'll be a good companion on my trip to Japan. Great buy!

Thursday, April 15, 2010

C++ Trivia: Another reason to avoid function-style casts

I was asked to solve a problem that two of my collegues were puzzled by. The source code was short and minimalistic, but the error was not very obvious. Here's the code (modified, because the original included dependencies to Qt):

#include <iostream>
#include <string>

class Test
{
public:
   enum Enum
   {
      First,
      Second,
      Last
   };

   Test(Enum e): m_value(e) { }

   std::string name() const
   {
      switch (m_value)
      {
      case First:
         return "First";
      case Second:
         return "Second";
      case Last:
         return "Last";
      }
      return std::string();
   }

private:
   Enum m_value;
};

int main()
{
   for (int i = 0; i < Test::Last; ++i)
   {
      Test test(Test::Enum(i));
      std::cout << test.name() << std::endl;
   }
}

Can you spot the error without compiling? Don't worry. Even compilers do not agree on this one. Visual C++ 2005 and gcc 4.4.1 both spit out a similar error message in line

"std::cout << test.name() << std::endl;"
. gcc, by the way, has the more helpful error message here:
test.cpp:39: error: request for member ‘name’ in ‘test’, which is of non-class type ‘Test(Test::Enum)’
Does this help you? Have a close look at the code in the for-loop. Only look at the solution when you are out of ideas!

Klick here to see the solution.

The statement
Test test(Test::Enum(i));
is a function declaration. There is a rule in C++ that everything that can be read as a function declaration will be a function declaration. In this particular case, it's a function returning an object of type Test, taking an enum value of type Test::Enum with the parameter name i. It's important to know that you always can put parameter names in parantheses. This means that
void test(int i);
is the same as
void test(int (i));
The failed attempt to cast i to a value of type Test::Enum lead to a construct that looks like a function parameter. So test is a function name, which obviously can't be used in the manner of test.name(). Hint: This wouldn't have happened if static_cast had been used.

Saturday, April 10, 2010

Change wallpaper background image on Windows 7 Starter for netbooks

This came as quite a surprise. I knew that Windows 7 Start might have some limitations. Luckily, the limitation of started applications has been dropped. But the only really annoying thing that it is missing is the ability to change your wallpaper. This is really a bummer and I can imagine that quite a few people will pay the $80 bucks for an Anytime upgrade to Windows 7 Home Premium just for this reason. But I don't want to throw my money at Microsoft for such a silly reason, so I investigated whether it is possible to change the wallpaper through some registry-hacks or something. I found out that many just replaced the original image and it worked for them. They were using older (pre-release) versions of Windows 7 Starter and this has been "fixed" in the final release. So the only way is using tools like WindowBlinds by Stardock. However, this tool will replace the complete look and feel of your Windows installation. Since I like the original look and feel and don't want to replace a large part of my system with 3rd party software, so I looked into more possible solutions. The best tool that I could find is available at a french site and called Starter Background Changer. This tool replaces the "Personalize" screen of Windows with a home-made interface (that has a few funny translations, at least in German) that lets you change your desktop's background image and some other settings. Here's a screenshot of the interface in German:

Starter Background Changer screenshot

Thursday, February 4, 2010

Hardware price/performance guides for processors and graphics cards

What started with graphic card manufacturer's mangled naming schemes has long been continued by the CPU manufacturers. The days where you knew that a "GeForce 3" was faster than a "GeForce 2" and a Pentium 500MHz is faster than a Pentium 400MHz are gone now. CPU's clocks and number of cores can not be measured in a linear fashion, hence price comparison became very hard in the last few years. Luckily, a few tools are available to us consumers that make this a bit easier.

CPUs

First of all, there's a very neat CPU price/performance comparison list at pulsiageek's site. It's especially useful because you can sort it by price, performance or price/performance-ratio.

Graphic cards

Then there's a list of graphics cards containing cards from the old 2MB 3dfx Voodoo graphics card up to the latest GeForce GTX 295. The list over at gpureview.com does not contain a benchmark result, unfortunately, but it contains the MSRP.

Mobile graphics

Mobile GPUs are a whole different story, so it's good to know that there is a separate list at notebookcheck.net that contains the 3DMark01, 3DMark03, 3DMark05 and 3DMark06 score, which is probably the easiest indicator for performance. While there are numerous restrictions you can apply to the list to filter out specific graphics cards, there is no MSRP or reseller price mentioned. There's also a list available that includes actual FPS rates for popular games for each mobile GPU.

Tuesday, February 2, 2010

Scroll to the last highlight in irssi

Perhaps you know this situation: You have irssi running in screen and have been away for a few days. You come back and see that you have been highlighted a few hours or maybe even days before. Irssi usually shows you the highlighted line in the server window and it may be something like "daniel: What? Nooo!". Now you're wondering "What the heck was he refering to?", since you don't remember the conversation at that time. Now you would start scrolling back, probably hundreds of lines. When you are connected to your irssi via ssh over a slow line, this may take a second or more per page. It often happens to me that it takes 3 minutes or more to scroll back, just to find out that he mistyped another nick.

I now finally learned about a way to scroll to the highlighted position directly. With the command

/scrollback goto [dd-mm] HH:MM
you can scroll directly to a point in time. And since the timestamp is usually displayed next to the highlight in the server window, it's possible to jump straight to the highlighted position. You can then use
/scrollback end
to go back again to the most recent message in the window.

I was annoyed by that tedious scrolling task for years now, and asked in #irssi every now and then about it, but until today nobody could give me a solution.

Thanks to jink from #irssi on freenode for telling me about /scrollback goto!