none
hbrBackground = (HBRUSH)(COLOR_WINDOW+1), what is +1 for???

    Question

  •  Hi!
    The question is about window class registration, when you create a new application with VS,
    and in most examples you can find on the Internet the following code is used: 
    Code Snippet
    wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
     
    This line sets white window background (for Win 2000 and XP, and Vista, I guess). Try to remove +1 and you get white background
    anyway, so why we have to add +1?
    By the way, when using Dev-C++, it generates code in a different way:
     
    Code Snippet
     wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

     

    THERES NO +1 or so...
     
    Please help to figure it out
    Tuesday, June 12, 2007 5:02 AM

Answers

  • The first COLOR_* value defined is COLOR_SCROLLBAR with the value 0 (see Winuser.h). If you didn't add one you wouldn't be able to differentiate between COLOR_SCROLLBAR and a NULL HBRUSH.

     

    If you remove the +1 and only specify COLOR_WINDOW (5) you effectively get the same as COLOR_MENU (4) + 1, i.e. the menu color. Maybe they're both defined to be white.

     

    Tuesday, June 12, 2007 6:44 AM

All replies

  • The first COLOR_* value defined is COLOR_SCROLLBAR with the value 0 (see Winuser.h). If you didn't add one you wouldn't be able to differentiate between COLOR_SCROLLBAR and a NULL HBRUSH.

     

    If you remove the +1 and only specify COLOR_WINDOW (5) you effectively get the same as COLOR_MENU (4) + 1, i.e. the menu color. Maybe they're both defined to be white.

     

    Tuesday, June 12, 2007 6:44 AM
  • Yes, that makes sense.. But why on the Earth  they use COLOR_BACKGROUND without +1?
    Tuesday, June 12, 2007 8:08 AM
  • These system colors are defined in winuser.h

     

    Code Snippet

    /*

    * Color Types

    */

    #define CTLCOLOR_MSGBOX 0

    #define CTLCOLOR_EDIT 1

    #define CTLCOLOR_LISTBOX 2

    #define CTLCOLOR_BTN 3

    #define CTLCOLOR_DLG 4

    #define CTLCOLOR_SCROLLBAR 5

    #define CTLCOLOR_STATIC 6

    #define CTLCOLOR_MAX 7

    #define COLOR_SCROLLBAR 0

    #define COLOR_BACKGROUND 1

    #define COLOR_ACTIVECAPTION 2

    #define COLOR_INACTIVECAPTION 3

    #define COLOR_MENU 4

    #define COLOR_WINDOW 5

    #define COLOR_WINDOWFRAME 6

    #define COLOR_MENUTEXT 7

    #define COLOR_WINDOWTEXT 8

    #define COLOR_CAPTIONTEXT 9

    #define COLOR_ACTIVEBORDER 10

    #define COLOR_INACTIVEBORDER 11

    #define COLOR_APPWORKSPACE 12

    #define COLOR_HIGHLIGHT 13

    #define COLOR_HIGHLIGHTTEXT 14

    #define COLOR_BTNFACE 15

    #define COLOR_BTNSHADOW 16

    #define COLOR_GRAYTEXT 17

    #define COLOR_BTNTEXT 18

    #define COLOR_INACTIVECAPTIONTEXT 19

    #define COLOR_BTNHIGHLIGHT 20

    #if(WINVER >= 0x0400)

    #define COLOR_3DDKSHADOW 21

    #define COLOR_3DLIGHT 22

    #define COLOR_INFOTEXT 23

    #define COLOR_INFOBK 24

    #endif /* WINVER >= 0x0400 */

    #if(WINVER >= 0x0500)

    #define COLOR_HOTLIGHT 26

    #define COLOR_GRADIENTACTIVECAPTION 27

    #define COLOR_GRADIENTINACTIVECAPTION 28

    #if(WINVER >= 0x0501)

    #define COLOR_MENUHILIGHT 29

    #define COLOR_MENUBAR 30

    #endif /* WINVER >= 0x0501 */

    #endif /* WINVER >= 0x0500 */

    #if(WINVER >= 0x0400)

    #define COLOR_DESKTOP COLOR_BACKGROUND

    #define COLOR_3DFACE COLOR_BTNFACE

    #define COLOR_3DSHADOW COLOR_BTNSHADOW

    #define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT

    #define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT

    #define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT

    #endif /* WINVER >= 0x0400 */

     

    That + 1 is in my opinion only an obfuscating mechanism (though not necessarily intentional). I suggest using directly the symbol name for the color you want and not things like COLOR_WINDOW+1. As you can see that is not readable and understandable.

    Tuesday, June 12, 2007 9:32 AM
  •  Marius Bancila wrote:

    That + 1 is in my opinion only an obfuscating mechanism (though not necessarily intentional). I suggest using directly the symbol name for the color you want and not things like COLOR_WINDOW+1. As you can see that is not readable and understandable.

     

    It's certainly not an obfuscation mechanism, it's a fully documented feature. Check out the docs for the WNDCLASSEX structure (specifically hbrBackground).

     

    I have no idea why Dev-C++ generates the code it does.

     

    Tuesday, June 12, 2007 10:53 AM
  •  Mattias Sjögren wrote:
     Marius Bancila wrote:

    That + 1 is in my opinion only an obfuscating mechanism (though not necessarily intentional). I suggest using directly the symbol name for the color you want and not things like COLOR_WINDOW+1. As you can see that is not readable and understandable.

     

    It's certainly not an obfuscation mechanism, it's a fully documented feature. Check out the docs for the WNDCLASSEX structure (specifically hbrBackground).

     

    I have no idea why Dev-C++ generates the code it does.

     

    Yes, the code is obfuscated, because instead of generating

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

     

    they could have simply generate

    Code Snippet

    wc.hbrBackground  = (HBRUSH)(COLOR_WINDOWFRAME);

     

    Tuesday, June 12, 2007 1:57 PM
  • Sure, but I'd argue that would be even more confusing. The background color in both cases will be that of the *window* system color, not that of the window frame.

     

    Tuesday, June 12, 2007 2:57 PM
  • wc.hbrBackground = (HBRUSH)0 sets client to transparent.
    This ability to have no background at all creates offset between windows COLOR_* values and value accepted by
    RegisterClass(WNDCLASS) because COLOR_SCROLLBAR is defined as 0.
    Thursday, March 05, 2009 10:46 AM
  • Adding +1 sets the background to white. Without any modifier the background would be gray. Adding +2 makes the background black, -2 blue, -5 transparent.
    Sunday, June 14, 2009 1:12 AM
  • Adam Besaw wrote:
    > Adding +1 sets the background to white. Without any modifier the
    > background would be gray.

    That could be COLOR_MENU + 1.

    > Adding +2 makes the background black

    COLOR_WINDOWFRAME + 1

    > -2 blue

    COLOR_ACTIVECAPTION + 1

    > -5 transparent.

    That's just a NULL handle.

    There's a set of COLOR_* constants for various parts of Windows
    interface. COLOR_WINDOW happens to have numeric value of 5. Those
    constants start at zero (COLOR_SCROLLBAR has numeric value 0), and so
    you have to add one to the constant when using it in place of HBRUSH in
    WNDCLASS[EX]: otherwise, COLOR_SCROLLBAR would be indistinguishable from
    NULL handle.

    Note that COLOR_WINDOW is not necessarily white, COLOR_ACTIVECAPTION is
    not always blue and so on. You can change this in Control Panel |
    Display | Appearance. By using those COLOR_* constants, you can have
    your window match the color scheme selected by the user.
    --
    Igor Tandetnik


    Sunday, June 14, 2009 2:12 AM
  • To add on to what others already said... An alternative is to use GetSysColorBrush(COLOR_WINDOW) to avoid the +1 logic.
    Microsoft MVP - Visual C++
    Blog: http://nibuthomas.com
    Sunday, June 14, 2009 3:27 PM
  • To add on to what others already said... An alternative is to use GetSysColorBrush(COLOR_WINDOW) to avoid the +1 logic.

    That's not a particularly good alternative...

    The documentation for the GetSysColorBrush() function says specifically that:

    An application must not register a window class for a window using a system brush. To register a window class with a system color, see the documentation of the hbrBackground member of the WNDCLASS or WNDCLASSEX structures. 

    It seems like you're much better off just doing what the documentation for WNDCLASS or WNDCLASSEX tells you, and adding 1. If someone reading the code doesn't understand why you've done that, they can just refer to the documentation.

    • Proposed as answer by Sean Rinehart Saturday, May 12, 2012 1:45 AM
    Sunday, December 11, 2011 5:33 AM