Vista Command Link Control with C# / Windows Forms

I’m pretty sure all of you, who are using Windows Vista, have come along this new control:

It’s called “Command Link” and it is used across many of the new wizards and dialogs included for Windows Vista. I was wondering how to include such controls in an own Windows Forms application (as for WPF I could just simply template a button).

While researching, I found out, that this command-link-button is a simple Win32 button restyled with a new button style (BS_COMMANDLINK). As Windows Forms buttons also wrap classic Win32 buttons, it is possible to restyle one of these for a command link button.

All you have to do is set the FlatStyle of the button to System and apply the BS_COMMANDLINK style to the Style property of the CreateParams of the button.

    public class CommandLink:Button
const int BS_COMMANDLINK = 0x0000000E;

public CommandLink()
this.FlatStyle = FlatStyle.System;

protected override CreateParams CreateParams
CreateParams cParams = base.CreateParams;
cParams.Style |= BS_COMMANDLINK;
return cParams;

This will produce a basic command link, as shown above, including a text, but now description. To set a description text, you’ve got to send a special button WindowMessage BCM_SETNOTE:

  SendMessage(new HandleRef(this, this.Handle),
IntPtr.Zero, “Note text”);

Getting the content of the note text requires to messages BCM_GETNOTELENGTH, returning the length of the note, and BCM_GETNOTE, querying n+1 characters of the note text.

  int length = SendMessage(new HandleRef(this, this.Handle),
IntPtr.Zero, IntPtr.Zero) + 1;

StringBuilder sb = new StringBuilder(length);

SendMessage(new HandleRef(this, this.Handle),
ref length, sb);

return sb.ToString();

Finally you can also switch the default icon of the command link to a shield, to indicate an administrative operation.

To establish this, you can also use a message, BCM_SETSHIELD (but you have to remember the current value of it, as there is no BCM_GETSHIELD,..)

  SendMessage(new HandleRef(this, this.Handle), BCM_SETSHIELD,
IntPtr.Zero, true);

I created properties to wrap these two messages, and packed it all up into a custom WinForms control! With this, all you need to do is drop a CommandLink into your form and set the properties to create forms like this:

Feel free to download the CommandLink control source included as attachment!


Comments (4)

  1. knom says:

    I agree with you, I’d also expected more managed integration!

    But anyway the .NET 3.0 is a BIG new MANAGED part in Windows Vista ("unfortunately" it is also available on XP, win2k3 so that doesn’t count full).

    And to be honest, Command Links for instance (although unmanaged) aren’t that hard to implement!

  2. Kevin Daly says:

    Re. the WPF issue: It’s disappointing that this (along with other new system UI elements in Vista) wasn’t implemented as WPF to start with (or didn’t at least get some direct Windows Forms support…but WPF would have been my preference anyway).

    After PDC 2003 one thing we definitely *weren’t* led to expect was a truckload of new COM libraries and native code APIs, and once again having to write managed wrappers for them (I even seem to recall, with intense if rueful mirth, something about how it would be native code that had to have wrappers for managed elements…).

    I love Vista and especially WPF, but Microsoft do have some serious sucking up to do among those of us who’ve thrown ourselves into managed code, confident that it was the way of the future…’cos right now we’re feeling a bit stupid while it looks like the status of .NET under Vista isn’t that much different from the status of VB under say Windows 2000.

    Sorry about the rant but I just had to get that off my chest.

  3. knom says:

    There IS a shareable WPF version of the Command Link:

    You just need to leverage the "Vista Bridge" Library, which is part of the Windows SDK!

  4. DanielMoth says:

    The Winforms wrapper is "old" 🙂

    I keep getting questions about a WPF version. If you do create a publicly shareable one, let me know so I can link to it from my blog.