Delegate
声明函数指针类型——一种命名的签名,变量、参数和UDT成员可以持有对匹配的可调用对象的引用。委托值在位级别与 LongPtr 兼容,但在赋值、传递或调用时增加了编译时签名检查。
INFO
Delegate 语句是twinBASIC扩展。在经典VBA中,函数指针是由 AddressOf 产生的无类型 LongPtr 值,通过自定义机制(DispCallFunc、CallWindowProc 垫片等)间接调用。
语法:
[ Public | Private ] Delegate Function name [ CDecl ] ( [ arglist ] ) As type
- Public
- 可选 在ActiveX项目中,将委托类型导出到类型库,使其他项目的使用者可以看到 name。
- Private
- 可选 不将委托导出到类型库;仅在项目内可用。
- name
- 命名委托类型的标识符。必须是有效的twinBASIC标识符。
- CDecl
- 可选 将委托标记为使用C调用约定(
cdecl——调用者清理栈),用于建模C运行时API(如qsort)所期望的回调。默认为stdcall。参见API声明。 - arglist
- 可选 参数签名,与 Sub 或 Function 的写法完全相同——逗号分隔的
[ ByVal | ByRef ] [ Optional ] *varname* [ As *type* ]部分。 - type
- 委托签名的返回类型。
声明之后,name 可在允许类型的任何地方使用:声明函数指针类型的变量和参数、作为 Type(UDT)成员的类型、或作为 Declare 语句或 Interface 成员的参数类型。
委托值通常由 AddressOf 产生,它产生一个对具有匹配签名的常规过程的委托类型引用。为向后兼容,委托变量也可以接受通过其他方式获得的普通 LongPtr 地址——该值不经检查直接通过。委托变量的调用方式与函数相同:result = myDelegate(arg1, arg2)。
示例
一个基本委托,声明、赋值并调用:
vb
Private Delegate Function Operation (ByVal A As Long, ByVal B As Long) As Long
Public Function Addition(ByVal A As Long, ByVal B As Long) As Long
Return A + B
End Function
Private Sub Command1_Click()
Dim op As Operation = AddressOf Addition
MsgBox "Answer: " & op(5, 6)
End Sub委托用作UDT成员,建模Windows CHOOSECOLOR 结构的 lpfnHook 字段。将 Long/LongPtr 赋值给 lpfnHook 的现有代码继续工作;新代码可以直接赋值 AddressOf Handler 并在编译时检查签名:
vb
Public Delegate Function CCHookProc (ByVal hwnd As LongPtr, ByVal uMsg As Long, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Public Type CHOOSECOLOR
lStructSize As Long
hwndOwner As LongPtr
hInstance As LongPtr
rgbResult As Long
lpCustColors As LongPtr
Flags As ChooseColorFlags
lCustData As LongPtr
lpfnHook As CCHookProc ' Typed function pointer instead of LongPtr.
lpTemplateName As LongPtr
End Type
Dim tCC As CHOOSECOLOR
tCC.lpfnHook = AddressOf ChooseColorHookProcCDecl 委托,用作C运行时 qsort API的比较器参数:
vb
Private Delegate Function LongComparator CDecl ( _
ByRef a As Long, _
ByRef b As Long _
) As Long
Private Declare PtrSafe Sub qsort CDecl Lib "msvcrt" ( _
ByRef pFirst As Any, _
ByVal lNumber As Long, _
ByVal lSize As Long, _
ByVal pfnComparator As LongComparator _
)