深入探究Windows API中风格参数使用按位或的原因

熟悉Win32编程的人都知道,很多API函数中需要一个风格参数,如CreateWindow。使用这些函数时如果要用多个风格,就要用到“|”(按位或)运算符。那么,为什么要用按位或运算符呢?

首先,我们得知道按位或的意思。“或”运算就是,如果两个参数都为0,结果就是0,只要有一个参数是1,结果就是1。按位或就是把数字转化为二进制,对每一位进行或运算。这样,我们可以得出以下结论:

  1. 任何数和0按位或还得原数;
  2. 任何数和1按位或都得1。

接下来,让我们看看几种常用风格代表的数值:

风格 数值
WS_VISIBLE 0x10000000L
WS_CHILD 0x40000000L
WS_POPUP 0x80000000L

其中,0x10000000L二进制是000010000000000000000000000000000(后面28个0),0x40000000L二进制是001000000000000000000000000000000(后面30个0),0x80000000L二进制是010000000000000000000000000000000(后面31个0)。
仔细观察就会发现,每个风格表示的二进制都只有一位是1,而且都在不同位上。通过以前的两个结论可以得知,每对一个风格进行按位或,就有一位会变成1,其它位都不会变。即使一种风格已经被设置过,再设置一次也不会有影响。这样系统只需要读取每一位,根据风格执行相应操作就可以了。

有的时候,我们需要取消某个风格,如使用CHARFORMAT2W结构体时,里面的dwMask成员可能需要在程序运行期间修改。取消某个风格的方法如下:
以CHARFORMAT2W中的dwMask成员为例,如果我们开始设定了CFM_BACKCOLOR | CFM_CHARSET | CFM_COLOR 格式,想取消CFM_COLOR,可以使用一下代码:

cf.dwMask&=(~CFM_COLOR);

其中&是按位与符号,“与”和“或”正好相反,如果两个参数都是1,结果就是1,只要有一个参数为0,结果就是0。按位与就是把数字转化为二进制,对每一位进行与运算。这样,我们可以得出以下结论:

  1. 任何数和1与都得原数;
  2. 任何数和0与都得0。

~是按位取反,把每一位二进制都反转,把1变成0,0变成1。
前面说过,每个风格表示的二进制都只有一位是1,那么,把这个风格按位取反后,二进制只有一位是0,而且就是原来是1的那一位。根据上面的结论,这样就可以取消一种风格,而其它风格保持不变。

判断一种风格是否存在,只需要和这种风格进行按位与,看看结果是否为0,如果为0则没有这种风格,否则有这种风格。因为与运算只有在两个数都是1的前提下才得1,风格肯定有一位是1,根据第一个结论,就可以获得想判断的那一位的数值了。

猜你喜欢

转载自blog.csdn.net/qq_54121864/article/details/115264595
今日推荐