zoukankan      html  css  js  c++  java
  • WNDCLASS成员变量hbrBackground赋值时候的奇怪用法说明。

    最近有个需求是需要一个窗口的背景色。发现RegisterClass函数在注册窗口的时候就可以指定背景色,所以直接修改这个值不就可以了吗?

    然后看了WTL中窗口类的注册宏,发现里头的用法很奇怪。

    怎么把一个颜色值+1后强制转换成了画刷句柄。很好奇这是怎么回事儿,然后就开始这个问题的探索。

    立马查询了官方文档:

    https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassa

    https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassa

    官方文档说的很清楚了:

    hbrBackground

    Type: HBRUSH

    A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types:

    • COLOR_ACTIVEBORDER
    • COLOR_ACTIVECAPTION
    • COLOR_APPWORKSPACE
    • COLOR_BACKGROUND
    • COLOR_BTNFACE
    • COLOR_BTNSHADOW
    • COLOR_BTNTEXT
    • COLOR_CAPTIONTEXT
    • COLOR_GRAYTEXT
    • ......

    也就是说,这个画刷句柄,你要么传入一个物理画刷句柄。或者也可以传入一个颜色值,但是这个颜色值需要+1,然后再转换成画刷句柄值,然后对颜色值也有要求,必须是系统定义的颜色值,后面列举出来了。

    那问题就来了,问什么传入画刷句柄的API可以传入颜色值呢?还有这么奇怪的要求。

    google 查询了一番。基本上有了答案。

    https://stackoverflow.com/questions/15658341/color-window-in-hbrbackground

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/e4fd1c4b-4407-4743-a74f-7d78338c17d2/hbrbackground-hbrushcolorwindow1-what-is-1-for?forum=vcgeneral

    基于上面两篇文章的讲解和自己的理解,总结如下:

    1.为了方便直接把颜色值当做句柄值来绘制背景,相当让这个API更方便的使用了,所以微软这么做了。

    2.为什么要加1呢?因为COLOR_SCROLLBAR定义为0(参考附录),如果不加1就分不清楚是COLOR_SCROLLBAR还是一个空的画刷了,所以需要加1。这个定义可能是比较早,所以是为了像老代码兼容。

    3.这么简单的加1有什么问题吗?没有,因为系统定义的颜色值都很小,而画刷句柄的值一般都很大,是一个内存指针。他们两个值不可能重叠。所以微软知道哪个范围的值是真实的画刷句柄,哪个是传入的系统颜色值。

      (注:0-0xFFFF的地址是空指针赋值分区,如何地址都不能访问,系统颜色值没有超过0xFFFF。)

    4.自己随便写一个RGB的颜色值,然后也加1,再转换成画刷句柄可以吗?不可以,只支持系统颜色值。原因可以参考第3条的解释。这也说明了一个问题:如果想要用自定义的颜色值来当背景画刷句柄,需要创建一个真实的物理画刷句柄。比如CreateSolidBrush等。

    实际上,很多API需要HBRUSH的地方,都可以使用系统颜色值加1的方式来实现。

    比如FillRect函数:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-fillrect

    官方也是说可以传入系统颜色值加1的。

     上面的文档也说明了系统颜色值有哪些。GetSysColor函数支持哪些就有哪些。

    可以参考GetSysColor的官方文档中的详细列表:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor

    附录:系统颜色值定义:

    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 */

  • 相关阅读:
    Shell中的特殊变量和结构
    自由的Debian
    关于系统定制的一些链接
    超出两行显示省略号
    json转换
    区分LocalStorage和偏好数据
    去除谷歌浏览器中的默认文本框样式
    js访问xml
    js执行跨域请求
    mvc通过controller创建交互接口
  • 原文地址:https://www.cnblogs.com/1yzq/p/14221205.html
Copyright © 2011-2022 走看看