您现在的位置: 中国教师站 >> 教师关注 >> 电脑技术 >> 编程技术 >> Visual C >> 正文

Google
探索Win32系统之窗口类(Window Classes in Win32)
作者:Siny 文章来源:中国教师站cn-teacher 点击数: 更新时间:2007-4-22 12:49:20
改变影射模式(Mapping Mode)的时候必须小心,当由系统擦除窗口的背景时,系统假定和默认其影射模式是MM_TEXT。如果私有DC的影射模式不一样,窗口被擦除的地方将不再可见。

CS_OWNDC标志在WinNT和Win9x的作用也是有差别的。在WinNT,win32子系统和其他NT进程有相同的地址空间(4GB),应用程序使用此地址空间里的2GB,每个有CS_OWNDC标志窗口实例占用800个字节,在NT下,这里面没有什么问题。而Win9x为GDI保留了64K的局部堆,DC进入这个堆之后,即使其他GDI对象数据被释放,DC依然在。这意味着每个CS_OWNDC的窗口都在这个宝贵的内存空间里占用800个字节。所以,为win9x写的程序最好尽量少的使用CS_OWNDC这个标志。win9x的修正版打算解决这个问题,但效果不明显(而且win9x已经开始式微了)

如果使用CS_CLASSDC标志,所有属于该类的窗口实例共享相同的DC(称为类DC).类DC有一些私有DC的优点,而更加节约内存(因为不需要为每个窗口实例都分配800字节的DC空间了)。每个窗口实例都通过GetDC或BeginPaintde得到设备上下文(DC)句柄,如果没有别的窗口需要该DC,不需要调用ReleaseDC或EndPaint释放DC。在一个窗口实例上通过GetWindowDC,GetDC,GetDCEx,BeginPaint获得 DC,并对其中的一些参数进行更改的话,所进行的更改除了剪切区域和设备本身属性(Device origin)之外对所有其他窗口实例都是有效的。和CS_OWNDC相同的是,必须确保影射模式也是MM_TEXT,否则,被系统擦除的背景将不再可见。

为NT编写的程序最好不要使用这个标志,因为“节约内存”的好处根本不明显。对于win9x来说,却是有用的,因为对于win9x的64K的GDI局部堆来说,节约的空间意义更重大一些。

  • 如果使用了CS_PARENTDC标志,属于这个类的窗口都使用它的父窗口的句柄。和CS_CLASSDC相似的是,多个窗口共享一个DC,不同的是,这多个窗口(虽然有父子关系并且共享DC)并不要求都属于同一个窗口类。

WIN9x下,所有的标准窗口控件都有CS_PARENTDC标志。WinNT下,除了ComBoBox之外的窗口控件都有此标志。因此,比如Edit控件和ListBox控件都共享他们的父窗口(比如对话框)的DC

(注:这一段是我根据原文再加上自己的理解,不一定完全正确:) CS_PARENTDC带来的好处就一个字:速度。Win9x系统为每个线程预留了5个DC缓冲区,如果一个窗口(比如一个对话框)有多于5个的字窗口(比如有6个或以上的编辑框),而每个子窗口都有自己的DC的话,DC缓冲区就失去了效力,系统得为每个子窗口根据剪切边界和设备属性重新初始化一个DC,这多于5个的DC在DC缓冲里不停交换,不能确保在缓冲里被访问。而如果每个子窗口都和父窗口共享一个DC,在频繁访问该DC时,该DC在于DC 缓冲里被找到的几率显然相当的高,从而可以被高速的访问,显著的提高了速度,所以一般来说标准窗口控件都和父窗口共享DC。WinNT可以拥有多于5个的DC缓冲,所以它可能可以提供足够的DC缓冲 -- 但是不保证时时如此。

使用CS_PARENTDC的另一个效果是,子窗口可以在父窗口的客户区随意做画,就象画在自己的客户区一样. 负责表现Edit控件和ListBox控件周围的3D效果的CTL3D库就是利用了这个特性。注意如果程序需要改变各子窗口的影射模式,那么最好不要用CS_PARENTDC标志,否则将很容易引起各子窗口影射模式的混乱,因为所有的子窗口都使用同一个DC。

  • 如果不指定CS_OWNDC,CS_CLASSDC或CS_PARENTDC这几个标志,此类的窗口使用一个通用DC,并置于DC缓冲里以供使用。通用DC在使用前获取,使用后释放,在DC获取的时候,DC里的上下文按默认值初始化,除非当时该DC已经在窗口的DC缓冲里(比如没有调用ReleaseDC或EndPaint释放DC),这样的话DC的剪切边界和设备属性都不需要被重新初试化,可以节约一些时间。

在WinNT里,DC缓冲没有确定的数量。如果所有的DC缓冲都在使用中,而程序调用了GetDC和BeginPaint,NT则再分配一个缓冲。

出于对win9x的兼容考虑,win32程序最好把 DC的使用限制在5个以下,并且尽可能快的释放DC.

如果要忽略类创建时由标志位决定的窗口的默认DC,程序可以使用GetDCEx函数,指定DCX_CACHE标志,则完全忽略CS_OWNDC和CS_CLASSDC标志,并从缓冲里返回一个通用DC.

ScrollWindow和ScrollWindowEx函数处理DC的方法则有所不同:

  • ScrollWindow使用窗口默认的DC。因此,如果窗口使用CS_OWNDC或CS_CLASSDC标志,ScrollWindow使用相应的DC(窗口私有DC或类DC,其影射模式有可能被程序改变,不为MM_TEXT).传递给ScrollWindow的坐标值必须和DC的影射模式相一致。

  • ScrollWindowEx使用系统通用DC(这种DC使用MM_TEXT的影射模式),而忽略窗口的标志。传递给ScrollWindowEx的坐标值必须是MM_TEXT影射模式下的客户区坐标值。

CS_DBLCLKS

CS_DBLCLKS标志使窗口可以检测到双击事件。窗口响应双击的细节如下:

  • 如果窗口没有CS_DBLCLKS标志,系统向窗口依次发送如下消息:

WM_LBUTTONDOWN

  • WM_LBUTTONUP

  • WM_LBUTTONDOWN

  • WM_LBUTTONUP.

其实相当于两个单击。

  • 如果窗口有CS_DBLCLKS标志,则系统向窗口依次发送如下消息:

WM_LBUTTONDOWN

  • WM_LBUTTONUP

  • WM_LBUTTONDBLCLK

  • WM_LBUTTONUP.

第一种情况中的第二个WM_LBUTTONDOWN被WM_LBUTTONDBLCLK代替了。

注意,在上述序列中间可能会插入其他的一条或一些消息,所以这两个消息序列不一定是完全

上一页  [1] [2] [3] [4] [5] [6] 下一页

相关专题:
 
 网友评论:(评论内容只代表网友观点,与本站立场无关!)
GOOGLE广告

阅读排行

| 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |
中国教师站

中国教师站 版权所有 Copyright © 2006-2020 All Rights Reserved 站长:Sina & Siny
[备用域名:www.JXZYW.Com] 有事请留言有事请留言
【实力成就精品 诚信呵护品牌】

信息产业部备案
苏ICP备06018635号