Getting System Colors In C#June 29th, 2008 |
*** READ THE COMMENTS! I have been enlightened.
***
Maybe it’s just me, but it took me forever to figure out how to set the background color of a control to the “window” color the user has set up in the control panel. 99% of the time this is white but since I’m one of those guys who runs with dark window colors, I was determined not to make that assumption and do things the right way.
Ways you can’t do it:
- System.Windows.Forms.SystemInformation: You can get a wealth of information from here, including whether or not the user has chosen to always show pull-down menu access key underlines, or only when ALT is held… but no color information. Close, but no cigar.
- Color.System.
: all the other colors live here. I was hoping for a “System…” subsection under here or at least names like “ActiveBorder” intermingled with “hard coded” names (Lemon Chiffon!), but couldn’t find any. - Control.DefaultBackColor: So close! This appears to return the 3D face color, but regardless isn’t what I was looking for. I want a big list of all the system colors, not just a one-off.
The Way:
System colors, in C#, are called “known colors.” Once you know this it’s easy to find:
System.Drawing.Color.FromKnownColor(KnownColor.Window);
And, as you’d expect, the KnownColor enumeration contains all of the other user-definable colors (active window border, whatever).
I don’t understand the logic behind calling these colors “known colors.” If anything, Lemon Chiffon is a Known Color (well, OK maybe not to all of us, but to interior decorators at least), and the current window color is Unknown, or at least “user-defined.” But even more perplexing is why C# deviates from calling them “system colors.” In Win32 you’d call GetSysColor() (and truth be told, I almost just pinvoked that). KnownColors is a wart that detracts from the beautiful organization of C# in other places (for example, Process or System.IO.Ports).
If I were running the C# show, I would have put the system colors in with the rest of the system information.

July 1st, 2008 at 2:46 am
I think you are not correct. The class System.Drawing.SystemColors is the class you’re looking for. It’s been part of the BCL since version 1.0 of the .NET Framework. No need to pinvoke GetSysColor anymore.
Every color in System.Drawing.Color is implemented as a static Property which works as a simple wrapper to System.Drawing.KnownColor to simplify access to colors most frequently used. Instead of “Color.LemonChiffon” you can invoke “new Color(KnownColor.LemonChiffon)” with the former being far more practical. KnownColor is an enumeration (specifying LemonChiffon to return a value of 90) which makes it easier to interact with the Win32 subsystem. But you cannot access system colors with this structure which are hidden in the KnownColor enumeration for the reason just stated. The sealed SystemColor class makes use of KnownColor as well. For instance, you can call “SystemColor.ActiveBorder” to get the ActiveBorder system color or invoke “new Color(KnownColor.ActiveBorder)”.
I think the BCL is perfectly structured strictly following the fundamentals of encapsulation by isolating system colors and “normal colors” in two different data types which internally refer to KnownColor.
Hope that cleared things up for you. Regards.
Steve
July 1st, 2008 at 3:28 pm
You’re absolutely right.
After a bit of puzzlement over how I could have missed it, I realized what was going on - I recently uninstalled Visual Assist and moved onto a demo of ReSharper, and when it comes to Intellisense, and specifically the little drop-down list that appears after you type the last . on System.Drawing., ReSharper behaves differently than Visual Assist X.
Using Visual Assist, if you type “Color,” it shows you everything containing “Color.” ReSharper shows you only things that start with “Color”. So it showed only Color, ColorConverter, and ColorTranslator.
I take back the comments about C# not calling them system colors, with apologies to C# for not giving it the benefit of the doubt - System.Drawing.SystemColors is logical and well organized. I’m still not completely comfortable with both being routed into KnownColor, though - seems like SystemColors should call into SystemInformation - but whatever, now I’m splitting hairs.
Thanks for the comment - the lesson here is “don’t trust your IDE (addons) exclusively, read the docs!”