每一个窗口类都有一个相关联的窗口过程,这个窗口过程是被同一个类的所有窗口所共享。窗口过程处理这个类的所有窗口的消息从而控制他们的行为和外观。
进程必须注册一个窗口类后才能创建一个窗口。注册窗口类用一个类名字关联到窗口过程,类风格,以及其他的类属性。当进程在CreateWindow或者CreateWindowEx中指定了一个类名的时候,系统就会创建一个窗口,其中窗口过程,风格,其他属性跟这个类名相关联。
- 窗口类的类型
- 系统类
- 应用程序全局类
- 应用程序局部类
- How the System Locates a Window Class
- Registering a Window Class
- Elements of a Window Class
1窗口类型
<1>系统类
系统类是系统注册窗口类。许多系统类可被所有进程使用,有的则仅在只能在系统内部使用。由于系统注册这些类,所以进程不能破坏它们。
系统会在进程中的任意一个线程首次调用用户或许系统的GDI函数的时候来注册这些系统类。
每个应用程序接受它自己对系统类的副本。在同一个中的VDM所有的16bit的Windows应用程序分享同一个系统类,就像他们在16bit的Windows上一样。
下表介绍了可用于所有进程使用的系统类。
Class |
Description |
Button |
The class for a button. |
ComboBox |
The class for a combo box. |
Edit |
The class for an edit control. |
ListBox |
The class for a list box. |
MDIClient |
The class for an MDI client window. |
ScrollBar |
The class for a scroll bar. |
Static |
The class for a static control. |
下面的表描述了只能别系统调用的系统类
Class |
Description |
ComboLBox |
The class for the list box contained in a combo box. |
DDEMLEvent |
The class for Dynamic Data Exchange Management Library (DDEML) events. |
Message |
The class for a message-only window. |
#32768 |
The class for a menu. |
#32769 |
The class for the desktop window. |
#32770 |
The class for a dialog box. |
#32771 |
The class for the task switch window. |
#32772 |
The class for icon titles. |
<2>应用程序全局类
一个应用程序全局类是由一个可执行文件或DLL注册的窗口类,它可以被进程中的所有其他模块访问。例如,你的your.dll可以调用RegisterClassEx函数注册了一个自定义的控件定义作为一个应用程序全局类,从而当一个进程加载这样一个dll的时候,它就可以创建这个自定义控件的实例。
创建一个可以在每一个进程中使用的类,在.dll中创建窗口类并且在每一个进程中加载dll。为了能在所有的进程章加载这个dll,要把它的名字加载到注册表中HKEY_LOCAL_MACHINE \ SOFTWARE\ MICROSOFT \ Windows NT\CURRENTVERSION\ Windows键的值Applnit_Dlls中。
当一个进程启动时,系统会在新启动的进程调用入口函数之前加载上下文中指定的dll。Dll必须在它的初始化过程中注册窗口类并且必须指定为CS_GLOBALCLASS风格
要删除一个应用程序全局类,并释放与它相关联的存储,使用UnregisterClass函数。
<3>应用程序局部类
一个应用程序局部类是exe或者dll注册只让自己用的。尽管你可以注册许多局部类,但是通常只注册一个。这个窗口类支持应用程序主窗口的窗口过程。
当注册窗口类的模块关闭的时候,系统会销毁局部类。应用程序也可以调用UnregisterClass函数来移除局部类并且释放和它相关的内存。
2系统是怎样找到一个窗口类
系统会为每种类型的窗口类(即以上说明的三种窗口类)分别维护一个结构列表。当应用程序调用CreateWindow或CreateWindowEx来创建一个窗口时,系统会根据指定的窗口类,按照以下过程来定位这个类:
<1> 根据指定的窗口类名和进程(或模块)的实例句柄(因为其它模块,也会以相同的窗口类名注册,所以会以模块的实例句柄作区分),查找Application Local Classes;
<2> 若没有在1步骤中找到,则查找ApplicationGlobal Classes;
<3> 若没有在2步骤中找到,则查找SystemClasses;
所有由应用程序创建的窗口,包括因应用程序的行为使系统创建的窗口,都是采用这个过程定位的。