按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
。if uMsg WM_CHAR
mov eax;wParam
mov edi;offset szAllowedChar
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第9章 通用控件
9。6 控件的超类化(2)
mov ecx;sizeof szAllowedChar
repnz scasb
。if ZERO?
。if al 》 '9'
and al;not 20h
。endif
invoke CallWindowProc;lpOldProcEdit;
hWnd;uMsg;eax;lParam
ret
。endif
。else
invoke CallWindowProc;lpOldProcEdit;
hWnd;uMsg;wParam;lParam
ret
。endif
xor eax;eax
ret
_ProcEdit endp
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
; 基于Edit类建立一个新的类:HexEdit
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
_SuperClass proc
local @stWC:WNDCLASSEX
mov @stWC。cbSize;sizeof @stWC
invoke GetClassInfoEx;NULL;addr szEditClass;addr @stWC
push @stWC。lpfnWndProc
pop lpOldProcEdit
mov @stWC。lpfnWndProc;offset _ProcEdit
push hInstance
pop @stWC。hInstance
mov @stWC。lpszClassName;offset szClass
invoke RegisterClassEx;addr @stWC
ret
_SuperClass endp
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
_ProcDlgMain proc uses ebx edi esi hWnd;wMsg;wParam;lParam
mov eax;wMsg
;********************************************************************
。if eax WM_CLOSE
invoke EndDialog;hWnd;NULL
;********************************************************************
。else
mov eax;FALSE
ret
。endif
mov eax;TRUE
ret
_ProcDlgMain endp
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
start:
invoke GetModuleHandle;NULL
mov hInstance;eax
invoke _SuperClass
invoke DialogBoxParam;hInstance;DLG_MAIN;
NULL;offset _ProcDlgMain;NULL
invoke ExitProcess;NULL
;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
end start
由于在对话框初始化的时候,对话框管理器就要根据对话框资源的内容创建每个子窗口控件,所以在调用DialogBoxParam函数显示对话框之前,“HexEdit”类就必须存在,否则初始化工作会失败。因此,程序在DialogBoxParam函数之前调用_SuperClass子程序进行超类化的工作。
在_SuperClass子程序中,程序通过GetClassInfoEx函数获取Edit控件的类结构,然后将结构中的窗口过程指到自己的_ProcEdit子程序中,接下来将hInstance字段设置为自己的实例句柄,并将类的名称改为“HexEdit”,最后用RegisterClassEx函数注册一个新的“HexEdit”类:
nst
szEditClass db 'Edit';0
szClass db 'HexEdit';0
de
。。。
mov @stWC。cbSize;sizeof @stWC ;@stWC是一个WNDCLASSEX结构
invoke GetClassInfoEx;NULL;addr szEditClass;addr @stWC
push @stWC。lpfnWndProc
pop lpOldProcEdit
mov @stWC。lpfnWndProc;offset _ProcEdit
push hInstance
pop @stWC。hInstance
mov @stWC。lpszClassName;offset szClass
invoke RegisterClassEx;addr @stWC
新的窗口过程和子类化窗口中的例子是一样的,在这里就不进行分析了,程序的结果就是:用HexEdit类建立的所有窗口的功能和子类化窗口例子中IDC_HEX编辑框的功能是一样的。
本程序演示的是派生类在对话框中的使用情况,在这里基于派生类创建的窗口是由对话框管理器自动调用CreateWindowEx函数创建的,如果将派生类使用在普通窗口中的话,可以通过指定派生类的名称,自己使用CreateWindowEx函数来创建。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第10章 内存管理和文件操作
10。1 内 存 管 理(1)
10。1。1 内存管理基础
Win32中的内存管理是分层次的,系统提供了几组层次不同的函数来管理内存,它们是标准内存管理函数、堆管理函数、虚拟内存管理函数和内存映射文件函数。所有的这些函数都是为了让用户能在比较高的层次上方便地管理内存,以便将程序和底层的内存分页机制隔离开来。如图10。1所示,这几组函数的层次是各不相同的。
图10。1 Windows的内存分层管理
Windows使用一个以页为基础的虚拟内存系统,与分页有关的概念已经在第1章的1。3。2小节中有所介绍。Windows充分利用了80x86处理器保护模式下的线性寻址机制和分页机制,这些机制是Win32内存管理的基础,Win32提供了一组虚拟内存管理函数来管理虚拟内存,主要用于保留/提交/释放虚拟内存,在虚拟内存页上改变保护方式,锁定虚拟内存页以及查询一个进程的虚拟内存等操作,这是一组位于底层的函数。
堆管理函数相对比较高级一点,堆的主要功能就是有效地管理内存和进程的地址空间。DOS操作系统下的C语言中就已经有了“堆”的概念,这时的“堆”是程序初始化时向操作系统申请并预留的大块内存,程序通过C函数在这块空间中申请和释放内存。
在Win32中,进程可以使用的整个地址空间就是一个堆。并且“堆”的概念又被引伸了一步:Win32中分两种堆,一种是进程的“默认堆”,默认堆只有一个,指的就是可以使用的整个地址空间;另一种是“动态堆”,也称为“私有堆”,私有堆类似于DOS下C语言中使用的那种堆,一个进程可以随意建立多个私有堆,也可以随意将它们释放,私有堆全部位于默认堆中,从概念上看,它和默认堆并没有什么不同,就像一个跨国公司和属下的子公司同样都是按照公司的规程操作一样。使用堆管理函数可以对所有的私有堆和默认堆进行操作。
标准内存管理函数总是在默认堆中分配和释放内存,这组函数就是常规意义上的内存管理函数。
内存映射文件函数相对比较独立,它是为了文件操作的方便性而设立的,当对文件进行操作的时候,一般总是先打开文件,然后申请一块内存用做缓冲区,再将文件数据循环读入并处理,当文件长度大于缓冲区长度的时候需要多次读入,每次读入后处理缓冲区边界位置的数据往往是个麻烦的问题。曾经介绍过Windows可以使用磁盘文件当做虚拟内存(参考图1。5,虚拟内存的实现),内存映射文件函数使用同样的办法将一个文件直接映射到进程的地址空间中,这样可以通过内存指针用读写内存的办法直接存取文件内容。
对比这些函数,可以发现它们涉及的系统资源是各不相同的,如表10。1所示。
表10。1 不同内存管理函数的操作对象
内存管理函数
涉 及 方 面
标准内存管理函数
一个进程的默认堆
堆管理函数
一个进程的虚拟地址空间、系统内存、进程堆资源结构
虚拟内存管理函数
一个进程的虚拟地址空间、系统页文件、系统内存、硬盘空间
内存映射文件函数
一个进程的虚拟地址空间、系统页文件、系统内存、硬盘空间、标准文件I/O
10。1。