Welcome to MSDN Blogs Sign in | Join | Help

What went wrong in Windows 95 if you use a system color brush as your background brush?

If you want to register a window class and use a system color as its background color, you set the hbrBackground member to the desired color, plus one, cast to an HBRUSH:

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

Windows 95 introduced "system color brushes", which are a magic type of brush which always paint in the corresponding system color, even if the system color changes.

HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW);

The hbrWindow brush will always paint in the color corresponding to GetSysColor(COLOR_WINDOW), even if the user changes the color scheme later.

Now, you might be tempted to use a system color brush as your class background brush. After all, if you want the background to be the system window color, why not use a brush that is always the system window color?

Well, because the documentation for GetSysColorBrush explicitly tells you not to do that. If you tried this on Windows 95, it would have seemed to work for a while, and then bad things would start happening.

The system color brushes were added as a convenience to save people the trouble of having to create solid color brushes just to draw a system color. Profiling in Windows 95 revealed that a lot of time was spent by applications creating solid brushes, using them briefly, and then destroying them, so anything that could be done to reduce the rate at which applications needed to do this was a good thing.

The system color brushes were implemented in Windows 95 by creating them and then telling GDI, "Hey, if somebody tries to DeleteObject this brush, don't let them." This prevented the system color brushes from being accidentally destroyed.

Except when it didn't.

When you registered a window class with a background brush (and by that, I mean an honest-to-goodness brush and not a pseudo-brush you get from that (HBRUSH)(COLOR_xxx + 1) stuff) the window manager did the same thing to the brush as it did to the system color brushes: It told GDI, "Hey, if somebody tries to DeleteObject this brush, don't let them." This prevented people from destroying brushes while the window manager was still using them to draw the background of a window.

When you unregistered the window class, the window manager told GDI, "Okay, delete this brush, and yes, I told you not to let anyone DeleteObject it, but I'm overriding it because I was the one who protected it in the first place. I'm just cancelling my previous instructions to protect this brush." The window manager takes responsibility for destroying the brush when you register the class; therefore, when you unregister the class, the window manager is obligated to clean up and destroy the brush. (Actually, it's a little more complicated than that, because it is legal to use one brush as the background brush for multiple window classes, but let's ignore that case for now.)

Do you see the problem yet?

What if you registered a window class with a system color brush as the background brush and then unregistered it? (Don't forget that classes are automatically unregistered when the process exits.) When you registered the class, the brush got protected, and when you unregistered the class, the Windows 95 window manager told GDI to override the protection and destroy the brush anyway.

Oops, we just destroyed a system color brush. Even though those brushes were protected, the protection didn't work here because you went through the code path where the window manager said, "Override the safety interlocks!"

But of course, you didn't need to use a system color brush in the first place. You should have used that (HBRUSH)(COLOR_xxx + 1) pseudo-brush.

(Note to nitpickers: This story talked about Windows 95. It does not apply to any other version of Windows. The problem may or may not exist in those other versions; I make no claims.)

Published Tuesday, November 28, 2006 7:00 AM by oldnewthing
Filed under: ,

Comments

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 10:17 AM by Bob

So what happened when people went down this code path? Palette corruption? Random crashes?

For that matter, what tipped you guys off that people were doing this?

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 10:40 AM by Peter Ritchie

What happens?  Now they're using a brush handle that in the best case is just "freed", or it has been re-used as a different colour brush.  Worst case, it's not a brush handle anymore and who knows what will happen in that case...

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 10:45 AM by Frederik Slijkerman

It would have been better if the Win95 developers would have introduced a new 'system' flag for brushes instead of re-using the 'do not delete because I am a class brush' flag...

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 10:56 AM by JS

I love you, .NET.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 11:05 AM by Aaron

re: Frederik

Yeah, on casual analysis this just looks like bad design.  Don't implement an optimization and then break that very same optimization by implementing something that unregisters/destroys/whatever the handle regardless.  Couldn't the code check to see if the handle was some sort of special "immortal" handle and not tear it down in that case?  Where these two features implemented by different groups or something?

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 12:17 PM by GregM

I take it that "don't destroy this" was just a flag and not a reference count.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 12:36 PM by ping?
Why wasn't it done with a reference count in the first place?...

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 1:44 PM by Mike

Isn't hindsight wonderful?  Obviously what happened was that originally there wasn't (and as far as I know still isn't) any support for reference counted brushes.  Nothing wrong with that, it wasn't deemed necessary in the original design.

So then along comes sombody who notices this perf issue.  The GDI guys already have a mechanism to prevent "system" brushes from being deleted so it's a trivial feature to implement.  They either don't remember or don't know that the USER guys (a different team remember) are already monkeying around with this flag on thier own whim and boom you have a bug.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 1:51 PM by Gabe

Keep in mind this was 1995. Back then programmers were expected to cooperate with the system, and documenting what not to do was considered sufficient. That's laughable now in the days where users must be protected from programmers, but it wasn't then.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 2:40 PM by Kuwanger

"Keep in mind this was 1995. Back then programmers were expected to cooperate with the system, and documenting what not to do was considered sufficient."

I disagree.  While it was the case that many people were used to the idea, having moved over from Win16, and it was assumed that programmers weren't nefarious, it wasn't the case that it was assumed documentation would be a sufficient protection.

Simply put, programs crashed because of bugs.  One of the main selling points of Windows 95, over Windows 3.11, was a greatly increased resistance to program crashes causing system-wide failures (along, of course, with a 32-bit api).  Yet competitors of the time (OS/2 and Windows NT being good examples) implemented a truly separate memory address space (ie, they didn't, AFAIK, leave critical shared DLLs in a read/writeable share arena where any program could do nasty things effecting all running programs) and worked to resolve misbehaving programs from causing the system to crash or other programs running at the same time to malfunction in unexpected (for the user) ways; ie, a programmer gotcha wouldn't be covered and programs that did malfunction would almost certainly rapidly crash themselves alone.

Having said all that, this was clearly a bug and an oversight in the original design.  Whoever designed it clearly wasn't thinking far enough ahead to actual usage.  Certainly such is a common affair in programming (sadly), but that doesn't really excuse in any way this instance.  In any case, it sounds like old news and an interesting example of how a simple design change many times need more thought put into it.

[System color brushes were a new Windows 95 feature. I thought you folks decided that people who mis-use new features deserve what they get. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 3:41 PM by waleri

For me is much more interesting, why the value is +1

[You should be able to figure this out on your own. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 3:44 PM by Kuwanger

"System color brushes were a new Windows 95 feature. I thought you folks decided that people who mis-use new features deserve what they get."

Perhaps I'm not understanding the effects of destroying the system color brushes, but does that have a system-wide effect?  If so, I'd like to point out that memory protection was also a new Windows 95 feature.  It'd seem appropriate to make either the system color brushes read-only to processes or give each process their own copy.

If, however, system color brushes are local to a process only and the effect is merely one application trashing itself, then I guess I don't see it as much of a big deal.  It'd probably help if I were to study the MSDN before spouting off, eh?

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 7:16 PM by 640k

> [You should be able to figure this out on your own. -Raymond]

Does that reply mean:

1. It's obvious and too time consuming for you to explain.

2. You don't know.

3. A polite way to tell people to use the suggestion box instead.

4. You really think all readers are able to figure this out on their own.

PS I'm not able to figure this out on my own.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 8:18 PM by Stu

So what you're saying, Raymond, is that there is a bug in Windows 95's handling of system colour brushes in conjunction with Window backgrounds?

So why wasn't it fixed!? I can understand keeping bug-compatability with older versions of Windows, but this was a new feature!

[What's to fix? Programs that encountered this problem were breaking the rules. They deserved to lose. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 8:23 PM by Neal

I haven't done any programming in 5 years, and did very little gdi stuff when I did, but I'll take a guess at it.  COLOR_XXX's are defined starting at 0, hence the first would give you a null brush, which is either not a good thing or it has a special meaning (believe this is the case) therefore the +1.

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 8:25 PM by Chris

640k,

Check out the COLOR_XXXX #defines in winuser.h, especially COLOR_SCROLLBAR

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Tuesday, November 28, 2006 8:54 PM by Norman Diamond

> But of course, you didn't need to use a

> system color brush in the first place. You

> should have used that (HBRUSH)(COLOR_xxx + 1)

> pseudo-brush.

But of course you[*] DID need to use a system colour brush in the first place.  When you discovered that you had to use that (HBRUSH)(COLOR_xxx + 1) pseudo-brush instead, you lost the following capability:

> a magic type of brush which always paint in

> the corresponding system color, even if the

> system color changes

Pedantic correction to my own writing:  you[*] didn't lose that capability because

> it seemed to work for a while, and then bad

> things would start happening.

So you[*] never had that capability in the first place, you lost a misguided hope of having that capability.  Still, I see how the idea sure looked attractive to programmers of the day, just as you[**] did.

[* "you" = impersonal 2nd-person developer not Mr. Chen]

[** "you" = Mr. Chen, just to add an off-topic token abuse of an ambiguous grammar]

[I don't know what you're talking about. The (HBRUSH)(COLOR_xxx+1) thing existed since Windows 1.0 and always created a tracking pseudo-brush. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Wednesday, November 29, 2006 3:26 AM by Norman Diamond

> The (HBRUSH)(COLOR_xxx+1) thing existed since

> Windows 1.0 and always created a tracking

> pseudo-brush.

I thought this description in the base note

> Windows 95 introduced "system color brushes",

> which are a magic type of brush which always

> paint in the corresponding system color, even

> if the system color changes.

meant that the older type didn't magically track system colour changes.

[The (HBRUSH)(COLOR_xxx+1) pseudo-brushes always tracked. GetSysColorBrush provides real-brush equivalents to those pseudo-brushes (which work only in window class background registration). -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Wednesday, November 29, 2006 5:30 AM by Jon

a bit offtopic, but would you care to comment about the vista shutdown menu discussion?

[If you've been following this site you'd know that is not something I write about. (What's the title of this blog again?) All I'm going to say is that there's more to it than people make it out to be. All you've seen so far is one side of the story. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Wednesday, November 29, 2006 6:42 AM by KJK::Hyperion

Jon, I will comment if it's the same to you. That article is full of shit. Windows gives exactly two options, and they are the right ones, you know, those Joel pleads for, and I don't understand what the hell the article is even about. Maybe about that "advanced" pop-up menu nobody concerned will ever see

The new "sleep mode" that debuts in Vista is also the "right choice": it works as stand-by, i.e. instant power-on, but behind the scenes it also performs a hibernate, so when the power goes off or 20 minutes pass, the computer safely turns off and your session is preserved

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Wednesday, November 29, 2006 7:04 AM by Stu

"[What's to fix? Programs that encountered this problem were breaking the rules. They deserved to lose. -Raymond]"

But in this case, seeing as it is a new feature and all, the "rules" were probably written around the bug.

[It was designed that way on purpose. The assumption is that programmers aren't stupid. Programming is hard because nobody said it was going to be easy. Before commenting further please read this article. I get the feeling most of the people saying that it's a bug don't understand the mindset of the day. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Thursday, November 30, 2006 5:21 PM by 0x0d

nice example how bug turns into feature, when nobody want fix it :)

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Thursday, November 30, 2006 5:25 PM by 0x0d

/*It was designed that way on purpose. The assumption is that programmers aren't stupid.*/

But note that win'95 pretended to be multitasking OS. So it should at least _try_ to protect programs from being corrupted by closing handles from other programs. So this is a bug in this protection.

[If you want Windows NT you know where to get it. -Raymond]

# re: What went wrong in Windows 95 if you use a system color brush as your background brush?

Thursday, November 30, 2006 8:17 PM by Norman Diamond

> If you want Windows NT you know where to get

> it.

On its own that statement is true, but it's not a valid answer to complaints about Windows 95.  People who wanted to pay for Windows NT instead of paying for Windows 95 (or 98) didn't know where to get it.  Unless we could make do with slyly configured crippled selections of hardware from about two vendors, we had to pay twice in order to get Windows NT.

New Comments to this post are disabled
 
Page view tracker