首页  >   经验  >   Windows零基础入门:2.21 窗口类结构体之窗口类风格CS_CLASSDC

Windows零基础入门:2.21 窗口类结构体之窗口类风格CS_CLASSDC

查看 codexia 的博客 2015-09-16 17:23:25 2483 会员文章,禁止转载
Windows   入门  
手机阅读 | 转发赚积分
手机收藏 | 分享给好友
简介本文首先介绍了窗口类DC的概念,并分析了窗口类DC的背景知识。重点分析了它的使用场景。然后用代码来验证说明,并通过对代码的几处改动来验证不同的情况,分别改成窗口独有DC风格和不接触占用的互斥使用。

    CS_CLASSDC风格注册的窗口类,系统会为这个类分配一个窗口类DC。用这个窗口类创建的所有窗口,都共享这一个DC句柄。也就是说,这些窗口所使用的DC是公用的。
    这个和前面一讲《Windows零基础入门:2.20 窗口类结构体之窗口类绘图风格CS_OWNDC》说到的不一样。前面一讲的DC是窗口相关的,是窗口独有的DC。在窗口内部执行绘图,不需要反复的创建和释放。而这里的窗口类DC,则不是某个窗口独有,而是用这个窗口类创建的所有窗口共同拥有。一个窗口使用了之后,设置的画笔颜色,文字颜色等信息,都会保留。另一个窗口使用时,依然是上一个窗口使用留下的样子。
    相对于窗口独有的DC,窗口类DC成了共有的资源,也就表示,这个资源必然不是窗口能够控制的,窗口最多就是拿来用用而已。窗口无权创建也无权释放。这个和窗口独有DC一样,你最多就是走走形式,使用完后的释放并不会起作用。当应用程序结束后,所注册的窗口类也就被销毁,这个时候系统自然就会释放窗口类DC。自然是窗口类注册的时候系统创建的窗口类DC。
    因为窗口类是和进程相关的,所以,一个进程中的多个线程都可以基于这个窗口类创建窗口。
那么,这些线程就可能同时去使用这个DC。如果发生这种情况,系统会保证一次只有一个线程能够成功的完成绘图。也就是说,这个DC是一次只能被一个线程拥有。
    这么来理解,窗口类在进程中注册,只要使用了这个窗口类来创建的窗口,都共享这个窗口类DC。注册窗口类时指定好CS_CLASSDC这个标志哦。不管是应用程序局部窗口类还是应用程序全局窗口类,对于一个进程的所有线程来说,都没有关系。所有线程都在进程空间中,都是一家人。这个好比,你在家里放一个WiFi,不管是说这是家里私用的,还是提供路人也可以使用的,对于一家人来说,都是可以用的。只是,如果你设置为家里私用的,路人就看不到,对于家人来说,没关系。这些线程就是进程这个家里的所有家人。
    虽然说这个窗口类DC是这个窗口类创建的所有窗口共有的,但是,一次只能有一个线程在使用。一个线程就相当于一个使用者。因为窗口类DC只有一个,你用了,他就只能等。你可以把DC想象为一套画图的工具箱。一次一个人用,是相互排斥的。对于一个线程来讲,就只有一个人会用,那么他什么时候用都不会用不了。而涉及到多线程,就会产生抢的可能。因为在多CPU的环境里,是可以允许多个线程同时执行的。比如双核CPU,可以同时执行两个线程,四核CPU,可以同时执行四个线程。还有一种情况,多线程就算在单核CPU执行,他们也是轮流使用CPU。而一个线程在使用窗口类DC的时候,可能要执行比较长时间,这样一次执行过程完成不了绘画过程。但是此时又轮到其他线程执行。因为一个线程执行时已经在用这窗口类DC了,必然会对DC里的一些参数进行设置,比如设置文字颜色,画刷颜色等等,如果切换到其他线程执行的时候,其他线程也可以使用这个DC的话,其他线程也要设置DC,这样就导致混乱,结果画的稀里糊涂。所以系统就要保证,一次只能有一个线程占有窗口类DC,即使它现在在睡觉,也是它的。其他线程不要企图使用。只有当他释放了窗口类DC之后,就解除占用,那么其他的线程就可以使用这个窗口类DC了。而说到这里,可以知道,释放窗口类DC并不是真的释放窗口类DC,而是解除占用而已。如果你不解除占用,其他线程画图就无法使用了。
    下面用代码来解释这个机制。为了突出主题,将不必要的注释去掉了。详细的注释可以参考前面课程文章。

开通会员付1C币>>阅读全文
标注
评论
站内搜
百度搜
传送到手机
手机扫码,识别文字,完成传送x
加载中...
标注内容x
加载中...
添加标注x
收藏 0 点赞 0
公众号
微信赞赏
支付宝赞赏
领支付宝大红包
QQ群

相关阅读

分享到:
分享文章[Windows零基础入门:2.21 窗口类结构体之窗口类风格CS_CLASSDC]到QQ空间
  • codexia 2019-03-19 09:30:43

    hdc是一个存储句柄的变量,beginpaint函数获取的是一个窗口类DC的函数,获取到的句柄存储在hdc中。然后通过endpaint函数来释放这个获取到的窗口类DC的函数。 这里有两个概念,一个是句柄变量,一个是窗口类DC。代码中注释里说的自动释放指的是局部变量在出了作用域后会释放变量本身所占的内存。而窗口类DC要释放,必须要用endpaint函数。窗口类DC的释放,仅仅是解除当次获取后占用的状态,不会真的将窗口类DC占用的内存释放掉。释放窗口类DC的目的就是此线程用完后,解除占用,让其他线程用。 不过因为beginpaint函数获取到了窗口类DC,而窗口类DC又是全局的,所以你如果用全局变量存储这个DC的句柄,下次不需要beginpaint函数就可以用里面的配置了,比如里面设置过颜色什么的。具体的,可以通过试验来了解更多,然后参考MSDN的介绍。课程的所有推论和试验以及结论,都是参照msdn的文档来做的,以此来将文档所描述的知识点挖掘出来,让更多人深入了解。 另外,win7,win8,win10在窗口机制上是有差异的。没有研究win8和win10具体哪些机制有调整,详细的需要在MSDN文档里找。
    0回复

    赤勇玄心行天道-HeavenTao 2019-03-18 22:47:12

    我在我的的Win10系统上测试,如果有CS_CLASSDC的窗口在占用DC,那么其他的该类窗口用GetDC()是不会创建临时的DC,仍然是使用相同的DC,并且用该DC时会导致画图失败。
    0回复

Win32课程菜单

猜您感兴趣