之前为了注册一个自定义协议,需要通过注册 AppleEvent 来实现,在 Objective-C 中,可以很方便的使用 NSAppleEventManager 来注册 AppleEvent 句柄,但是在 REALbaisc 中,是没有办法直接去调用 NSAppleEventManager 的,所以需要通过声明然后调用 C API 来实现相应的功能。
与 NSAppleEventManager 中功能相对应的 C API 有 AEInstallEventHandler, NewAEEventHandlerUPP 等,通过这些 API 我们也可以在 REALbasic 中来注册 AppleEvent 了,再配合 Info.plist 中的 URLScheme 声明,即可实现 URL 自定义协议处理句柄。
#if TargetCarbon
soft declare function AEInstallEventHandler Lib CarbonLib ( _
theAEEventClass as Integer, _
theAEEventID as Integer, _
handler as Integer, _
handlerRefcon as Integer, _
isSysHandler as Boolean) as Integer
Soft Declare Function NewAEEventHandlerUPP Lib CarbonLib (userRoutine as Ptr) as Integer
Static CallbackUPP as Integer = 0
If CallbackUPP = 0 then
dim m as MemoryBlock = AddressOf ForwardCarbonAEEventToObject
If m is nil then
Return
End if
CallbackUPP = NewAEEventHandlerUPP(m)
End if
dim v as Variant = me
dim OSError as Integer = AEInstallEventHandler( _
OSTypeToUInt(kInternetEventClass), _
OSTypeToUInt(kAEGetURL), _
CallbackUPP, _
v.Hash, false)
msgbox str(OSError)
#endif
先使用 NewAEEventHandlerUPP 来生成一个 AppleEvent 回调函数的句柄,然后调用 AEInstallEventHandler 来注册一个共享函数 ForwardCarbonAEEventToObject 为 AppleEvent 事件处理句柄。
AEInstallEventHandler 所需的 AEEventClass 和 AEEventID 都是一个 4 字节的整型,但是通常我们在调用的时候,是用的一个 4 字符的字符串,因此需要一个函数来将 4 字符转换为 4 字节的整形。
// code from ToolbarSearchField by The ZAZ Studios
// http://www.thezaz.com/opensource/realbasic/macosx/searchfield/
static m as new MemoryBlock(4)
m.LittleEndian = false
m.StringValue(0, 4) = s
return m.UInt32Value(0)
在 ForwardCartonAEEventToObject 里,参数 theEvent 和 replyEvent 都量个整形,为了从这两个参数里拿到数据,还需要使用 AEGetParamPtr 来从 AppleEvent 中拿到数据。
soft declare function AEGetParamPtr lib CarbonLib ( _
theAppleEvent as Integer, theAEKeyword as Integer, _
desiredType as Integer, byref actualType as Integer, _
dataPtr as Ptr, maximumSize as Integer, _
byref actualSize as Integer) as Integer
当然还有一系列的 AEGetDataDesc、AEGetDescSize 等函数可以,具体可以查 Xocde 随带的库文档。
关于注册自定义协议,可以参考这篇文章。
通过 Core Foundation 中的一些 C API,在 REALbasic 也可以完成一些平台相关的工作,虽然麻烦了些:)
话说在Cocoa里,注册自定义URL Scheme是相当简单的。
是的,所以用 REALbaisc 就杯具了,找了 Cocoa 注册协议的代码,然后找到相应的 C API,然后再用 REALbasic 定义……