探索Win32系统之窗口类(Window Classes in Win32)
Kyle Marsh 本文主要介绍 在本文中 窗口类的风格决定了窗口的外观和风格。所有的窗口都会属于某一个窗口类。在创建一个窗口之前,必须注册 大部分开发人员认为窗口类是个麻烦的东西,他们顶多就是从例子或其他代码中拷贝一个 我们的将讨论的题目包括: 一:窗口类的类型 window 1.系统全局窗口类( windows 以及其他不那么常用的控件如TabCtrl等. 还有: WindowsNT Windows 95/98 所有的 应用程序可以通过 在 系统全局窗口类实现 现在的 系统全局类在 16 winNT 服务进程管理每个 在 2.应用程序全局类。 应用程序全局类是注册的时候指定了 16 Win32 作为这个特性的扩展, 这样当任意一个 3. 应用程序局部类 WIN32 二:窗口类包含的信息和作用 窗口类都包含些什么信息呢?让我们看以下窗口类结构体。 WNDCLASS 描述 style 一组标志位的组合。定义比如窗口位置,设备上下文 lpfnWndProc 指向窗口过程的地址,该窗口过程负责处理窗口类相应的窗口消息 cbClsExtra 指明需要额外分配的内存数量,单位为 cbWndExtra 指明需要额外分配的内存数量,单位为 hInstance 标识注册该类的 hIcon 当一个属于该类的窗口被最小化的时候,显示的图标 hCursor 属于鼠标该类的窗口里显示的指针 hbrBackground 定义当程序打开或重画某个属于该类的窗口是,填充窗口客户区的颜色和样式 lpszMenuName 如果没有显性定义菜单时,窗口的默认菜单 lpszClassName 字符串的类名 以下详细讨论各成员的具体意义: Style 如果使用这两个标志,窗口的的客户区或整个窗口都在“字节边界”上对齐,也就是说,系统调整窗口的水平位置,客户区或整个窗口的左边坐标是 看看系统如何摆放一个边框宽度为 Original window location Placement with CS_BYTEALIGNWINDOW Placement with CS_BYTEALIGNCLIENT 0,y 0,y 4,y 1,y 0,y 4,y 2,y 0,y 4,y 3,y 0,y 4,y 4,y 8,y 4,y 5,y 8,y 4,y 6,y 8,y 4,y 7,y 8,y 4,y 8,y 8,y 12,y 9,y 8,y 12,y 10,y 8,y 12,y 11,y 8,y 12,y 12,y 16,y 12,y 13,y 16,y 12,y 14,y 16,y 12,y 15,y 16,y 12,y 16,y 16,y 20,y 这两个标志在以下两个情况中无效: 其实当 CS_BYTEALIGNCLIENT 如果程序使用 其实对于可以显示 使用 这几个标志决定窗口的默认 在 出于对 CS_OWNDC 如果使用 为 WIN9x ( 使用 如果要忽略类创建时由标志位决定的窗口的默认 ScrollWindow CS_DBLCLKS 注意,在上述序列中间可能会插入其他的一条或一些消息,所以这两个消息序列不一定是完全连续的。 其实,在没有指定 所有的标准窗口控件,对话框,桌面窗口类都默认拥有 WM_LBUTTONDOWN 其实相当于两个单击。 WM_LBUTTONDOWN 第一种情况中的第二个 CS_GLOBALCLASS CS_HREDRAW 如果指定了 菜单,对话框,下拉框都拥有 CS_SAVEBITS 以上都是style成员的可选标志。 WNDCLASS 当一个程序或 cbClsExtra 在 如果用类声明并注册一个对话框类型的窗口,cbWndExtra的值必须设置为DLGWINDOWEXTRA,系统对话框管理器需要这么多的额外数据对对话框进行管理。 WNDCLASS WNDCLASS WNDCLASS WNDCLASS COLOR_ACTIVEBORDER COLOR_HIGHLIGHTTEXT COLOR_ACTIVECAPTION COLOR_INACTIVEBORDER COLOR_APPWORKSPACE COLOR_INACTIVECAPTION COLOR_BACKGROUND COLOR_INACTIVECAPTIONTEXT COLOR_BTNFACE COLOR_MENU COLOR_BTNSHADOW COLOR_MENUTEXT COLOR_BTNTEXT COLOR_SCROLLBAR COLOR_CAPTIONTEXT COLOR_WINDOW COLOR_GRAYTEXT COLOR_WINDOWFRAME COLOR_HIGHLIGHT COLOR_WINDOWTEXT 用颜色值赋值时,必须强制类型转换为 如果 WNDCLASS WNDCLASS 三 当程序需要根据一个类创建一个窗口,系统通过以下步骤来定位该类 1 2 在 winNT win9x 四 应用程序的如何使用窗口类信息。 一旦注册了一个类,一般来说除了使用该类创建窗口之外就没有什么需要作的事情了。当然,如果需要访问该类信息,子类化,或者超类化该类,介绍一些方法就是有用的。 如果需要获取和改变类的信息,可以使用以下函数: 具体的调用参数以及其他相关的一些类函数可以参见 SetClassWord 术语“子类化” 在 术语 关于子类化和超类化的具体描述,请参阅 结束语
Microsoft Developer Network Technology Group
MSDN
技术组win32系统里窗口类的运做和使用机制,探索一些细节问题,使win32窗口类的信息更加明朗化。,"类","窗口类"这两个术语等同,都不是指C++类,而是指和窗口相关的一组信息的集合。(register)一个相应的窗口类。32位Windows操作系统类可以注册被系统里所有的程序所使用的窗口类。RegisterClass函数,修改一下部分参数而已。这仿佛有些轻视了,没有发挥窗口类的作用。本文将对此进行探索,并且描述窗口类如何的使应用程序得到优化。(Windows Classes)
系统提供了三种类型的窗口类System global classes)
本身注册了几个系统全局类供全部的应用程序使用,这些类包括了以下的常用标准窗口控件
(列表框)
不注册类 #32772,因为它不使用题头带图标风格的窗口(由于我用的是win2k操作系统,这一点没有尝试)win32应用程序都可以使用系统全局类,但不能增加或删除一个这样的类。“子类化”(SubClassing)这些类来改变系统全局类的属性。在Win32里,应用程序子类化某个系统全局类只会影响本进程内窗口的表现,而不会影响另外一个进程或应用程序。比起相应的操作会影响其他窗口的win16时代,这是一个进步。Win32里,Ms鼓励“子类化”系统类的行为。因为这个技术可以非常有效和方便的改变窗口的表现。例如:如果应用程序希望限制edit控件的输入和编辑行为,可以通过子类化edit类并设置一个新的窗口过程(WindowProc)来自己处理处理键盘操作来实现。子类化以后,此应用程序里创建的edit控件将使用新的窗口过程,以代替标准的edit控件窗口过程。win32平台使系统类和各32位进程互不相干,系统类如何实现的并不会直接影响应用程序。本节将描述系统类的实现,当然,跳过此节并不妨碍全文的阅读和理解。win9x里的实现
位应用程序共享相同的进程空间。在win9x里,16位程序的表现和它在win3.1里是一样的。
的实现
HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows/APPINIT_DLLS
typedef struct tagWNDCLASS {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASS;
CS_BYTEALIGNCLIENT
,CS_BYTEALIGNWINDOW
8个或更多的位数,字节对齐并不会带来什么好处。这种情况下,系统在创建和移动的时候忽略了CS_BYTEALIGNCLIENT和CS_BYTEALIGNWINDOW这两个标志。
CS_OWNDC, CS_CLASSDC
, CS_PARENTDC
CS_OWNDC标志,属于此窗口类的窗口实例都有自己的DC(称为私有DC),私有DC仅属于该窗口实例,所以程序只需要调用一次GetDC或BeginPaint获取DC,系统就为窗口初始化一个DC,并且保存程序对其进行的改变。ReleaseDC和EndPaint函数不再需要了,因为其他程序无法访问和改变私有DC。当选择了CS_OWNDC,程序改变影射模式(Mapping Mode)的时候必须小心,当由系统擦除窗口的背景时,系统假定和默认其影射模式是MM_TEXT。如果私有DC的影射模式不一样,窗口被擦除的地方将不再可见。
DC,程序可以使用GetDCEx函数,指定DCX_CACHE标志,则完全忽略CS_OWNDC和CS_CLASSDC标志,并从缓冲里返回一个通用DC.和ScrollWindowEx函数处理DC的方法则有所不同:
使用窗口默认的DC。因此,如果窗口使用CS_OWNDC或CS_CLASSDC标志,ScrollWindow使用相应的DC(窗口私有DC或类DC,其影射模式有可能被程序改变,不为MM_TEXT).传递给ScrollWindow的坐标值必须和DC的影射模式相一致。
CS_DBLCLKS
CS_GLOBALCLASS
CS_HREDRAW ,CS_VREDRAW
CS_NOCLOSE
CS_SAVEBITS
的效率本身是很难度量的。CS_SAVEBITS提高了“临时”窗口比如菜单,对话框,下拉框的性能。但是,存贮位信息的开销也是很明显的,尤其由系统代替显示驱动存储位信息的时候,系统承担了速度和存储开销。 使用CS_SAVEBITS的好处其实依赖于窗口遮盖的区域发生了什么事情,如果该区域相当复杂,需要重画很多的效果,那么,存储该区域可能比重画该区域要来的轻松,如果反之,该区域可以相当快速的重画,或者在被遮盖的时候还经常发生变化并且变化很显著,保存的方案反而影响了整体性能。
结构里的lpfnWndProc成员保存了该窗口类的窗口过程地址。该窗口类的所有窗口都使用该过程地址,对于从该类创建的窗口,系统将所有相关的消息交给此窗口过程来处理。窗口过程实现窗口的功能,程序可以使用SetClassLong函数来改变窗口类的窗口过程。这个操作叫“子类化”(Subclassing)。当程序改变了该过程的地址,在改变前已经创建的窗口还是使用原来的地址,而以后创建的窗口才使用新的过程地址。DLL子类化一个窗口或设置窗口过程函数,必须在模块定义文件里输出该新窗口过程。
的hInstance成员标识类所在的模块。此成员可以为进程的hInstance,或DLL的hInstance,但不可以为NULL.
的hIcon成员标识此窗口类的图标。程序一般使用LoadIcon,从系统标准图标库(如IDI_APPLICATION)或用户指定的图标资源中来获取一个图标句柄。如果hIcon的值为NULL,当系统给程序发送WM_ICONERASEBKGND消息的时候,程序给窗口画上程序的主图标.
里的hCursor成员表示属于该类窗口的默认鼠标指针。当设置了该值,当鼠标移入窗口区域时,系统将指针由系统默认形状变成所设置的指针形状。程序可以使用LoadCursor函数从标准系统指针库(比如IDC_ARROW)或用户指定指针资源中获取指针句柄。程序可以通过SetCursor函数随时改变指针。如果hCursor的值未设置(设置为NULL),程序必须在鼠标指针移入窗口时进行设置,否则将使用系统默认的鼠标指针形状。
hbrBackground成员设置为NULL,程序必须在响应WM_PAINT的时候负责画背景。程序也可以响应WM_ERASEBKGND消息,或根据调用BeginPaint函数时填充的PAINTSTRUCT结构里的成员fErase的值类判断是否需要重画背景。
里的lpszMenuName成员表示默认主菜单。可以使用MAKEINTRESOURCE宏把资源里菜单项的ID号转变成连续的字符串值赋给该成员。如果使用CreateWindow或CreateWindowEx函数从该类创建窗口时没有在函数参数里指定别的菜单资源,那么出现在各窗口上的主菜单就是lpszMenuName指定的菜单。如果lpszMenuName为NULL,窗口则没有默认的主菜单。
.如果系统无法发现一个同名的局部类,那么,就继续搜索进程的全局类列表,这次的搜索不比较实例句柄。win9x,如果在程序全局类空间里无法发现同名类,则继续查询进程内的系统窗口类列表。
从类信息读回来一个Long类型的值(比如,窗口类的窗口过程地址)
从类信息读回来一个word类型的值。比如以下调用得到类的额外数据量:
nClassExtra = GetClassWord(hwnd,GCW_CBCLSEXTRA);
获取窗口类的名字。
(subclassing)描述的是用一个新的窗口过程代替原窗口过程。术语“实例子类化”(即子类化单个窗口)是指使用SetWindowLong函数改变某一个窗口实例的窗口过程。“全局子类化”(子类化整个窗口类)则是指使用SetClassLong改变整个类的默认窗口过程函数。32位windows 系统里,可能难于子类化另一个进程里的窗口或窗口类,一般来说,子类化都是发生于同一个进程里的(“打破进程边界”的相关的主题本文没有涉及)。
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
MDI:ComBoBox
探索Win32系统之窗口类(Window Classes in Win32)
最新推荐文章于 2024-04-15 18:19:12 发布
680

被折叠的 条评论
为什么被折叠?



