Themes are quite popular thing under Windows and it is very hard to make an application that would look decent regardless of user-selected colors. It is somewhat easier when you can cover all your needs with predefined theme colors. but sometime you just need a few more in order to emphasize an element.
As an example we can take simple highlighting of an error. Changing offending text to dark red works really nice on white background. If user has dark background, dark red text is probably not as visible.
Easiest solution (and I fear most often used one) is to ignore this issue. If user has such stupid theme, it is his problem. Needless to say, this is very rude. If user wants to have black background, user should have it. Lunatics should not be restricted!
Other solution is to find colors for every combination expected in wild. Given customization possibilities this is probably not a path worth taking. However, we can divide all possible theme choices into subsets and work from there.
I usually just fit everything into two color buckets - light and dark. If I detect that background is light, I use one color, while I use another if background is dark. This simple solution works almost always.
Function looks something like this:
bool IsColorDark(Color color) {
var y = 0.2126 * color.R + 0.7152 * color.G + 0.0722 * color.B;
return (y <= 160);
}
It just calculates luminance of a given color (0-255). All colors with high luminance are considered light and all those with low luminance are dark. Somewhat arbitrary cutoff point value used here is 160. I found that it works quite well for my needs.
To check whether color belongs on dark end of spectrum we just place it in function call:
if (IsColorDark(myColor)) {
//do something for dark
} else {
//do something for light
}