77范文网 - 专业文章范例文档资料分享平台

探索Win32系统之窗口类(Window Classes in Win32)(2)

来源:网络收集 时间:2018-12-06 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

如果使用这两个标志,窗口的的客户区或整个窗口都在“字节边界”上对齐,也就是说,系统调整窗口的水平位置,客户区或整个窗口的左边坐标是8的倍数。win32 SDk的文档说这两个标志影响窗口的宽度,但是实际上笔者没有发现这个现象,此标志只影响窗口的水平位置(左边)。

看看系统如何摆放一个边框宽度为4的窗口:

Placement with CS_BYTEALIGNWINDOW 0,y 0,y 0,y 0,y 8,y 8,y 8,y 8,y 8,y 8,y 8,y 8,y 16,y 16,y 16,y 16,y 16,y Placement with CS_BYTEALIGNCLIENT 4,y 4,y 4,y 4,y 4,y 4,y 4,y 4,y 12,y 12,y 12,y 12,y 12,y 12,y 12,y 12,y 20,y Original window location 0,y 1,y 2,y 3,y 4,y 5,y 6,y 7,y 8,y 9,y 10,y 11,y 12,y 13,y 14,y 15,y 16,y 这两个标志在以下两个情况中无效:

?

如果显示设备对每个象素使用8个或更多的位数,字节对齐并不会带来什么好处。这种情况下,系统在创建和移动的时候忽略了CS_BYTEALIGNCLIENT和CS_BYTEALIGNWINDOW这两个标志。

?

如果使用SetWindowPos函数改变窗口的位置,此函数忽略窗口的

CS_BYTEALIGNCLIENT和CS_BYTEALGNWINDOW标志指定的位置限定。在Win32 SDK文档关于WM_WINDOWPOSCHANGEING的描述让人费解,它说:“对于一个有WS_OVERLAPPED和WS_THICKFRAME风格的窗口来说,

DefWindowProc函数响应WM_WINDOWPOSCHANGING消息,并向窗口发送一个WM_GETMINMAXINFO消息,此消息的处理是验证窗口的新位置和尺寸,迫使窗口接受CS_BYTEALIGNCLIENT和CS_BYTEALIGNWINDOW限定”

其实当DefWindowProc接受到WM_WINDOWPOSCHANGING消息后,确实发送一条WM_GETMINMAXINFO消息,但是并不迫使窗口接受字节对齐的风格,为了确保字节对齐风格,应用程序必须通过计算再改变其水平位置

CS_BYTEALIGNCLIENT 和CS_BYTEALIGNWINDOW的存在是为了优化程序的性能,尤其在是3.0版本的windows系统以前。那时侯,所有的系统字体宽度都是固定的,系统可以通过使窗口字节对齐优化字体的显示。在3.0以后的window里,这一点已经被忽略了。 如果程序使用BitBlt函数从一个窗口向另一个窗口,或者从窗口的某个矩形区域向另一个矩形区域拷贝象素,还是可以通过设置CS_BYTEALIGNCLIENT标志来获得更好的性能。如果客户区是字节对齐的,程序也可以尽量保证BitBlt操作发生在字节对齐的矩形里, BitBlt操作将会比发生于非字节对齐的矩形里的操作更快。当然,字节对齐仅仅是对窗口的左边界而言的,如果要进一步的提高性能,应该连宽度都进行字节对齐。

其实对于可以显示256及以上颜色的视频卡或显示器,对字节对齐的需求已经微乎其微了。256色显示器已经自己实现了字节对齐,实际上,一些16色的显示器也是字节对齐的。在大部分显示器上根本看不出来字节对齐限定对窗口位置的影响。一句话,字节对齐标志已经没有什么重要的作用了。

使用CS_BYTEALIGNWINDOW的时候也等同于包含了CS_BYTEALIGNCLIENT;对话框类本身已经默认包含了CS_BYTEALIGNWINDOW标志 CS_OWNDC, CS_CLASSDC, CS_PARENTDC 这几个标志决定窗口的默认DC

?

如果使用CS_OWNDC标志,属于此窗口类的窗口实例都有自己的DC(称为私有DC),私有DC仅属于该窗口实例,所以程序只需要调用一次GetDC或BeginPaint获取DC,系统就为窗口初始化一个DC,并且保存程序对其进行的改变。ReleaseDC和EndPaint函数不再需要了,因为其他程序无法访问和改变私有DC。当选择了CS_OWNDC,程序改变影射模式(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代替了。

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

其实,在没有指定CS_DBLCLKS标志时,程序本身也可以检测到双击事件的。参见MSDN里Dr.GUT的\文章,不过要有一些技巧.一般的情况下,如果没有指定CS_DBLCLKS,在窗口的消息循环里将不会得到WM_LBUTTONDBLCLK消息。

所有的标准窗口控件,对话框,桌面窗口类都默认拥有CS_DBLCLKS标志。第三方控件最好也加上此风格,以使其在对话框编辑器里可以正常工作。 CS_GLOBALCLASS

CS_GLOBALCLASS是唯一一个针对类本身起作用而不是对单个窗口起作用的标志.系统将包含这种标志的窗口类作为应用程序全局类保存,这样类可以应用于注册该类的进程内的所有EXE和DLL,当EXE或DLL退出或卸载,或对该类调用UnregisterClass后,该类则被销毁。在注册该窗口的程序退出前,所有从该类创建的窗口都必须先关闭(对于DLL来说,这是自动进行的)。 CS_HREDRAW ,CS_VREDRAW

CS_HREDRAW标志表示当窗口的水平尺寸(宽度)改变的时候,重画整个窗口。

CS_VREDRAW则是在窗口垂直尺寸(高度)改变时重画整个窗口。按钮和滚动条都有这两种风格。 CS_NOCLOSE

如果指定了CS_NOCLOSE标志,则窗口上的关闭按钮和系统菜单上的关闭命令失效。 CS_SAVEBITS

菜单,对话框,下拉框都拥有CS_SAVEBITS标志。当窗口使用这个标志时,系统用位图形式保存一份被窗口遮盖(或灰隐)的屏幕图象。首先,系统要求显示驱动保存图象位数据,如果显示驱动本身的存储空间足够,保存操作成功,window系统也可以使用这些保存的位数据。如果不够,系统将位数据在全局内存里以位图的方式保存,并且在USE模块局部堆

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库探索Win32系统之窗口类(Window Classes in Win32)(2)在线全文阅读。

探索Win32系统之窗口类(Window Classes in Win32)(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/346575.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: