ATOM表

1.进程间的数据交换。
考虑 WM_SETTEXT 消息的实现,这个消息将lParam这个参数指向的字符串,设置为窗口的标题,我们可以在不同的进程中发送这个消息。那么这个消息如何实现呢?
考虑进程1中的字符串 LPCTSTR str = TEXT("Hello,World"),我们要把该字符串发送到进程2中该如何去做。我们知道每一个Win32进程都有其私有的进程地址空间,这些地址空间是虚拟的,所以同一个地址在不同的进程中起实际指向的物理内存是不同的,对于变量str,它实际是进程1中的一个虚拟地址,所以我们如果直接把该虚拟地址发送到进程2中,在进程2中通过该虚拟地址进行寻址,肯定不可能得进程1中字符串TEXT("Hello,World"),所在的位置。所以我们不能直接传递地址。再考虑进程是由操作系统创建的,操作系统完成了进程的虚拟地址空间和物理地址空间之间的转换,所以系统对进程的信息了如指掌,我们可以将传递字符串的这个工作交给系统来做。我们将进程1中的字符串TEXT("Hello,World"),保存到系统的地址空间中,并给该字符串提供一个系统级别的索引(Index),这个索引使用整数来标示,从而在系统中建立起一个索引和字符串(也可以是其他复杂的数据结构)的映射表。
然后进程2使用这个索引在系统地址空间中获得这个字符串。这样就完成的字符串在不同的进程地址空间中的传递。
Windows操作系统确实提供了这么一个功能。其中我们提出的索引就是ATOM,那个映射表就是ATOM表。
2. what is atom
typedef unsigned short WORD;
typedef WORD ATOM;
ATOM类型实际就是一个2字节整数。
2.1 Atom表的分类:
① Global Atom Table
当一个进程将一个字符串保存到全局原子表中时,系统生成一个在系统范围内唯一的atom,来标示该字符串。在系统范围之内所有的进程都可以通过该atom(索引),来获得这个字符串。由于全局原子表,在系统范围内是唯一的,所以我们常常利用全局原子表来实现进程间数据的交换。
② Local Atom Table
本地原子表存在的意义。为了实现不同进程间数据的交换,我们使用全局原子表,那么我们为什么要在一个进程内使用原子表呢,或者说本地原子表存在的意义是什么?
答:An application requiring the same string in a number of structures can reduce memory usage by using a local atom table. Rather than copying the string into each structure, the application can place the string in the atom table and include the resulting atom in the structures. In this way, a string appears only once in memory but can be used many times in the application.
2.2 原子表的实现
原子表内部使用hash table来实现的
Atom tables are implemented as hash tables. By default, a local atom table uses 37 buckets for its hash table. However, you can change the number of buckets used by calling the InitAtomTable function. If the application calls InitAtomTable, however, it must do so before calling any other atom-management functions.
2.3 原子表的形式,向规定原子表中的一些术语。我们说的 atom(key) 就是原子表中item的索引,我们说 atom name(value) 就是该item所对应的值。
atom就是2个字节的整数,所以atom的取值范围是:0x0000 -- 0xFFFF
atom的类型有两种:string atoms和integer atoms这两种不同的atom其可索引的 atom name,具有不同的特点。
① string atoms (atom name(value) 是 string 类型的 atom(key))
 image001_thumb10
其中的,重要一点,atom name在atom table中执行搜索时是大小写不敏感的。
② integer atoms (atom name(value) 是 integer 类型的 atom(key))
 image003_thumb1
例如:桌面的窗口类的值是:"#32769"
对话框窗口类的值是:"#32770"
2.4 atom的使用
① 全局原子表的 CURD
GlobalAddAtom
GlobalDeleteAtom
GlobalFindAtom
GlobalGetAtomName
① 本地原子表的 CURD
AddAtom
DeleteAtom
FindAtom
GetAtomName
3. Win32 中窗口类结构和CreateWindow函数中的信息被保存进程地址空间还是系统地址空间?
RegisterClass函数的声明如下:
 image005_thumb
这个函数返回的 ATOM 是全局原子表中的atom还是本地原子表中的atom?
应该是本地原子表中的atom,窗口类(WNDCLASS)这个结构是在本地原子表中保存着。
4. 关于菜单
5. 窗口类 (Window Classes)
Windows操作系统支持三种类型的窗口类,System Classes, Application Global Classes, Application Local Classes。这三种窗口类的区别在与,不同类型的窗口类其有效作用域,以及何时被注册,何时被销毁都是不同的。
5.1 窗口类的类型
① 系统窗口类(System Classes)
系统窗口类是由操作系统为我们注册的,大部分的系统窗口类被系统中的所有进程所共享。当一个进程中的线程第一次调用User或者GDI函数时系统就注册这些系统类。
可以被任何进程使用的系统窗口类:
 image007_thumb
只有系统可以使用的系统窗口类:
 image009_thumb
② Application Global Classes
An application global class is a window class registered by an executable or DLL that is available to all other modules in the process. The .dll must register the class during its initialization procedure and must specify the CS_GLOBALCLASS style。
To remove an application global class and free the storage associated with it, use the UnregisterClass function.
如果我们在一个dll文件中创建一个窗口类,然后将其加载到exe文件中,在exe中创建该窗口类的是一个实例(CreateWindow),我们就必须在dll中的在指定WNDCLASS的窗口类风格是添加 CS_GLOBALCLASS 。
每一个窗口类都与一个Module相关联,模块的句柄和窗口类的名称共同表示了一种窗口类,模块的句柄和窗口类的名称相当于一个联合主键。所以在不同的模块中窗口类的命称可以相同。
③ Application Local Classes
The system destroys a local class when the module that registered it closes. An application can also use the UnregisterClass function to remove a local class and free the storage associated with it.
窗口类名是保存在系统私有的atom表中的。

posted @ 2014-03-06 11:41  a ray of sunshine  阅读(1125)  评论(0编辑  收藏  举报