当前位置:C++技术网 > 精选软件 > Windows零基础入门:2.17 窗口类结构体之位或组合和位与去除窗口类风格

Windows零基础入门:2.17 窗口类结构体之位或组合和位与去除窗口类风格

更新时间:2015-09-10 19:29:35浏览次数:1+次

    在《Windows零基础入门:2.14 (1)窗口类使用完整代码演示和详细注释》中,有完整的代码,窗口类部分有了详细的注释。这里不重复贴代码。

    先给一个位操作符表,大家参考:

    位操作符表
    上节课讲到了窗口类风格的各种取值的所有可能,以及各个值的宏定义,也介绍了怎么给窗口类结构体变量的类风格style成员赋值,那么我们现在就先使用代码来演示如何使用。

WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
     第一句就是定义一个窗口类结构体变量,然后第二句给窗口类风格成员赋值。这里使用了位或操作符将两个窗口类风格组合起来了。因为CS_HREDRAW 和 CS_VREDRAW是两个宏,实际上就是一个整型常量,在上一节课里已经介绍了。那么这里我们其实可以直接使用数字来赋值以及组合,如下:

WNDCLASS wndclass;
wndclass.style = 0x0002 | 0x0001;// 十六进制表示
     或

WNDCLASS wndclass;
wndclass.style = 2 | 1;// 十进制表示
     这样和上面一样可以设置这个窗口类风格。只是你也看到了,如果用数字的话,你就很难看到这些数字代表的是什么意义了。这样就不方便了,所以说,上面的宏的使用,就清晰了,通过英文字符可以快速的判断它代表的意义。
    如果你还要使用其他风格,可以在后面接着位或进来就可以了,如:

WNDCLASS wndclass;
wndclass.style = 2 | 1 | CS_GLOBALCLASS;// 十进制表示与宏的混合使用
     之前设置好的风格,或者一些复合型的,有些宏就是几种风格的混合,这个很常见。如果你要去掉一个混合中的风格其中一种,或者是之前设置了几种,但是后来又要取消,那么你可以使用位与&来处理。而要对位取反,注意一定不要写成了!哦,!是逻辑取反,位取反是~操作符。我们要去掉一种风格,就是要将这个风格代表的位设置为0即可。
    我们来以水平重绘窗口类风格去除为例来介绍。

WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.style = wndclass.style & (~CS_HREDRAW);

     这里只是演示,所以,就先位或赋值了水平重绘风格CS_HREDRAW,然后后面我不想要了,我就用位操作来除掉。

wndclass.style = wndclass.style & (~CS_HREDRAW);
     这句代码有人喜欢写成:

wndclass.style &= (~CS_HREDRAW);

    就是简化一下而已。&=操作符相信大家应该知道,&=和>=一样的拆解,这是C/C++语言里的基础知识了。就等同于上面一种写法。
    我们将去除一种风格拆解为几步:
1.对风格取位反~CS_HREDRAW(这里使用括号括起来,不用担心记不住优先级的问题,在开发中很常用,不要纠结于这些东西,开发时不会去研究什么语法,那个简单安全用哪个)
    CS_HREDRAW就是一个数字0x0002,换成二进制为:0000000000000010,对其取位反,也就是让每一位都由0变为1或者1变为0。这里和逻辑取反不一样,逻辑取反则是对于真假求反,真变为假,假变为真,而0则为假,非零则为真。这点区别需要明白,以免弄混。所以对其取位反后,结果为:1111111111111101。
2.对窗口类成员style进行位与wndclass.style & (~CS_HREDRAW)
    因为之前对style成员已经设置了两种风格,值分别为CS_VREDRAW(1)和CS_HREDRAW(2),位或之后style的二进制值为:000000000011。所以,和第一步取位反的结果相位与,对应的位都为1则为1,否则为0,所以过程和结果为:

1111111111111101  第一个的位反~CS_HREDRAW结果,
0000000000000011  wndclass.style的开始赋的值
位与&
----------------------
0000000000000001  结果为1,也就是CS_VREDRAW

     对于位与的巧妙的应用,请阅读《深入讲解位与实现轮转遍历和特判的高效的运算代码技巧》和《高!最全面经典的轮流策略实现技巧》。
3.赋值给style风格,完成去除。
    最后一步就是将得到的值,赋值给style:

wndclass.style = wndclass.style & (~CS_HREDRAW);

     所以,最后相当于 

wndclass.style = CS_VREDRAW;

     这样就实现了去除水平重绘的风格了咯。
    那么对于风格的赋值、组合(|)、去除(~、&=)的灵活使用就介绍完了。后面节次将讲述这些风格的背后的故事,包括上节课的疑问的解答。本节课把这些消化后,对于任何位操作修改的地方,都可以轻松应对了。
    而我们平时修改窗口类风格的时候,就是窗口类已经注册好了,我们要修改窗口类,就要使用本节课使用的操作完成。而修改窗口类的内容,在前面的课程讲了,这里就不重复了。不清楚的,回去再看看。