(Default)模块
(Default)模块——内部称为_HiddenModule——汇集了编译器生成调用的未限定内联过程,这些过程也可以直接调用:原始内存辅助函数、原子操作、编译时反射、代码生成和栈检查原语,以及一大堆运行时实用工具。此模块的成员无需限定符即可引用,与MsgBox和CStr的使用方式相同。
这些过程大多有意对IntelliSense隐藏,仅在高级或低级场景下使用;仅当**Math、Strings、Information或Interaction**中的高级替代方案不适用时才使用。有几个还有此处未列出的仅限内部使用的成员。
指针函数ObjPtr、StrPtr和VarPtr以及Array构造函数记录在Information模块下;Input、InputB和Width记录在FileSystem下。
读写内存
已知地址的内存使用GetMem*/PutMem*系列一次一个机器字地读取和写入——GetMem1、GetMem2、GetMem4、GetMem8和GetMemPtr用于读取,对应的PutMem1、PutMem2、PutMem4、PutMem8和PutMemPtr用于写入。vbaCopyBytes和vbaCopyBytesZero移动块;AllocMem和FreeMem管理堆分配。为这些辅助函数提供指针的构造函数——ObjPtr、StrPtr、VarPtr——位于Information中。
Dim Buffer As LongPtr = AllocMem(16)
PutMem4 Buffer, &HDEADBEEF
Dim Magic As Long
GetMem4 Buffer, Magic
FreeMem BuffervbaRefVarAry和vbaAryMove是在与C端数组布局交互时使用的低级辅助函数。
对象引用和转换
vbaObjAddref、vbaObjSet和vbaObjSetAddref直接操作COM引用计数。vbaCastObj根据给定IID返回重新解释为另一个COM接口的对象。CreateGUID生成新的GUID并以注册表格式字符串返回。
原子操作
Interlocked*系列封装了对应的Windows内核原子操作——无锁计数器和指针交换的基础构建块:InterlockedExchangePointer、InterlockedCompareExchangePointer、InterlockedCompareExchange32、InterlockedCompareExchange64、InterlockedIncrement32和InterlockedDecrement32。
编译时反射
一些内联函数询问周围类型的问题而不运行任何东西;它们由编译器解析并作为常量嵌入。GetDeclaredTypeProgId、GetDeclaredTypeClsid、GetDeclaredTypeIid和GetDeclaredTypeEventIid报告类型的COM标识符。GetDeclaredMinEnumValue和GetDeclaredMaxEnumValue返回已声明枚举的最小值和最大值。
代码生成注入和栈检查
Emit和EmitAny将原始字节或类型化字面值拼接到封闭过程的代码生成输出中——内联汇编的载体。StackOffset和StackArgsSize报告当前调用点的布局信息;UnprotectedAccess返回绕过私有成员常规访问检查的对象引用。
运行时表达式求值
Eval编译并计算以字符串形式提供的twinBASIC表达式,使用配置了标准库绑定器的新构建的TbExpressionService。
图片、位图和图标
PictureToByteArray将IPicture序列化为字节数组;CreateStdPictureFromHandle将GDI句柄包装在stdole.StdPicture中;ConvertIconToBitmap执行图标到位图的转换。
其他辅助函数
GetInheritedOwner返回控件的继承所有者对象。GetShortcutTextByEnum返回内置键盘快捷键的本地化显示文本。SetThreadGlobalErrorTrap注册一个回调,当未处理的运行时错误逃离调用线程上的活动错误处理程序链时触发。
成员
- AllocMem —— 分配本机内存块并返回其地址
- ConvertIconToBitmap —— 将图标图片转换为位图图片
- CreateGUID —— 生成新的GUID并以注册表格式字符串返回
- CreateStdPictureFromHandle —— 将GDI位图或图标句柄包装在stdole.StdPicture中
- Emit —— 将自定义Byte值注入封闭过程的代码生成流
- EmitAny —— 将自定义类型化值注入封闭过程的代码生成流
- Eval —— 编译并计算以字符串形式提供的twinBASIC表达式
- FreeMem —— 释放使用AllocMem分配的内存
- GetDeclaredMaxEnumValue —— 返回已声明枚举类型的最大值,在编译时解析
- GetDeclaredMinEnumValue —— 返回已声明枚举类型的最小值,在编译时解析
- GetDeclaredTypeClsid —— 返回与已声明类型关联的COM CLSID,在编译时解析
- GetDeclaredTypeEventIid —— 返回与已声明类型关联的COM事件接口IID,在编译时解析
- GetDeclaredTypeIid —— 返回与已声明类型关联的COM接口IID,在编译时解析
- GetDeclaredTypeProgId —— 返回与已声明类型关联的COM ProgID,在编译时解析
- GetInheritedOwner —— 返回控件的继承所有者对象
- GetMem1 —— 从内存地址读取一个字节到Byte变量中
- GetMem2 —— 从内存地址读取两个字节到Integer变量中
- GetMem4 —— 从内存地址读取四个字节到Long变量中
- GetMem8 —— 从内存地址读取八个字节到Currency变量中
- GetMemPtr —— 从内存地址读取指针大小的值到LongPtr变量中
- GetShortcutTextByEnum —— 根据枚举ID返回内置键盘快捷键的本地化文本
- InterlockedCompareExchange32 —— 原子地比较并交换32位值
- InterlockedCompareExchange64 —— 原子地比较并交换64位值
- InterlockedCompareExchangePointer —— 原子地比较并交换指针大小的值
- InterlockedDecrement32 —— 原子地将32位值减一并返回新值
- InterlockedExchangePointer —— 原子地交换指针大小的值并返回之前的值
- InterlockedIncrement32 —— 原子地将32位值加一并返回新值
- PictureToByteArray —— 将IPicture序列化为Byte数组
- PutMem1 —— 向内存地址写入一个字节
- PutMem2 —— 向内存地址写入两个字节
- PutMem4 —— 向内存地址写入四个字节
- PutMem8 —— 向内存地址写入八个字节
- PutMemPtr —— 向内存地址写入指针大小的值
- RuntimeCreateGetMessageHook —— 创建用于过滤窗口消息的IGetMessageHook
- SetThreadGlobalErrorTrap —— 注册在调用线程上引发未处理错误时调用的全局回调
- StackArgsSize —— 返回当前过程栈帧上参数的总大小(以字节为单位)
- StackOffset —— 返回变量的栈帧偏移量
- UnprotectedAccess —— 返回绕过私有成员访问检查的对象引用
- vbaAryMove —— 将一个数组变量的内容移动到另一个中
- vbaCastObj —— 返回重新解释为另一个COM接口的对象
- vbaCopyBytes —— 将一个字节块从一个地址复制到另一个地址
- vbaCopyBytesZero —— 将一个字节块从一个地址复制到另一个地址,然后清零源
- vbaObjAddref —— 递增给定地址对象的COM引用计数
- vbaObjSet —— 将对象指针赋值给对象变量,释放任何先前的引用
- vbaObjSetAddref —— 将对象指针赋值给对象变量,添加引用并释放任何先前的引用
- vbaRefVarAry —— 返回Variant数组内部SAFEARRAY描述符的指针
IGetMessageHook接口
IGetMessageHook接口钩入选定窗口——以及可选的其后代——的Windows消息流,并将选定类型的消息转发到用户提供的回调。使用RuntimeCreateGetMessageHook获取实例;使用RegisterMessage连接回调;然后调用Start激活所有已注册订阅,调用Stop移除订阅。
该接口直接继承自stdole.IUnknown(非基于分派),提供给RegisterMessage的回调类型为GetMessageHookHelper.GetMessageHandler。
Const WM_LBUTTONDOWN = &H201
Sub Demo()
Dim Hook As IGetMessageHook = RuntimeCreateGetMessageHook
Hook.RegisterMessage Me.hWnd, AllDescendants, _
WM_LBUTTONDOWN, AddressOf OnLButtonDown
Hook.Start
End Sub
Function OnLButtonDown(ByRef msg As GetMessageHookHelper.HookMSG) As LongPtr
Debug.Print "Click at"; msg.pt.x, msg.pt.y
' Return zero to let the message continue normal processing.
End Function成员
- RegisterMessage —— 为窗口和选定的后代范围订阅单个消息类型的回调
- Start —— 激活所有已注册订阅
- Stop —— 停用所有已注册订阅
EnumDescendantsModeFlags
选择传递给RegisterMessage的窗口范围:
| 常量 | 值 | 描述 |
|---|---|---|
| ExactWindow | 1 | 仅钩住指定窗口。 |
| AllDescendants | 2 | 钩住指定窗口及所有后代——子级、孙级等。 |
| DirectChildren | 4 | 仅钩住指定窗口及其直接子级。 |
GetMessageHookHelper模块
GetMessageHookHelper模块是IGetMessageHook的小型伴随模块,包含其回调使用的结构和委托类型。无需构造任何内容;这些名称仅用于声明。
HookMSG
Windows MSG结构的副本,按引用传递给GetMessageHandler回调。
Type HookMSG
hwnd As LongPtr ' Window the message is destined for.
message As Long ' The WM_* identifier.
wParam As LongPtr ' Message-specific parameter.
lParam As LongPtr ' Message-specific parameter.
time As Long ' Time the message was posted, in milliseconds since system start.
pt As HookPOINT ' Cursor position when the message was posted.
End TypeHookPOINT
具有Long坐标的2D点,HookMSG使用它来保存光标位置。
Type HookPOINT
x As Long
y As Long
End TypeGetMessageHandler
IGetMessageHook.RegisterMessage接受的回调签名。返回零通常让消息继续正常处理。
Public Delegate Function GetMessageHandler (ByRef msg As HookMSG) As LongPtr