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
{
get
{
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),
BCM_SETNOTE,
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),
BCM_GETNOTELENGTH,
IntPtr.Zero, IntPtr.Zero) + 1;
StringBuilder sb = new StringBuilder(length);
SendMessage(new HandleRef(this, this.Handle),
BCM_GETNOTE,
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!