support for COM events |
worksheet.events.Change =
{args ->
def range = args[0]
println "\tEVENT Change (${range.Column},${range.Row}) = ${range.Value}"
}
|
As with other COM method types, events support passing values by reference. This is particularly important in light of the fact that events don't return a value. If you want to be able to send data back to whoever raised the event, you have to pass values back to the sender using byref arguments. Fortunately, this is easy to do using the EventArguments instance.
Take, for example, the following class written in Visual Basic 2005. When you call RaisePassBooleanByref, it will raise the OnPassBooleanByref event, by reference. This gives us an opportunity to change the value of the boolean in the event handler!
Option Explicit On
Option Strict On
Option Compare Binary
<Microsoft.VisualBasic.ComClass()> Public Class TestEvents
Public Event OnPassBooleanByref(ByRef Value As Boolean)
Public Function RaisePassBooleanByref(ByVal Value As Boolean) As Boolean
RaiseEvent OnPassBooleanByref(Value)
Return Value
End Function
End Class
|
In the following Groovy code, note how the return value changes after we define the event handler, which simply inverts the value of the first argument.
assert activeX.RaisePassBooleanByref(false) == false
activeX.events.OnPassBooleanByref = {args -> args[0] = !args[0]}
assert activeX.RaisePassBooleanByref(false) == true
|
Note that you may only change a value if it has been passed by reference. Otherwise you get an exception.
Back in the first example, I defined and event handler for an Excel Worksheet. There is another piece of information you need to make that example actually work. For many COM objects (and all true ActiveX objects), the underlying COM event handler is defined in a standard way that's easy to find and work with. However, for some COM objects, like those in Microsoft Office and Internet Explorer, there isn't enough information available for Scriptom to find the associated event interface. When this happens, you must manually define the prog-id of the object before you define any event handler. To help you out as much as possible, these are available as constants in the Scriptom library for the Office suite and for Internet Explorer. Here is how you define a prog-id for an ActiveXObject.
import org.codehaus.groovy.scriptom.tlb.office.excel.Excel; worksheet.events.useProgId Excel.progIds.Worksheet //Equivalent to worksheet.events.useProgId 'Excel.Sheet' |
Additionally, there are some objects in Office and other applications where the event interface exists, but it cannot be discovered, and the object does not have an associated prog-id. The Excel Workbook object is one example of this. We're hoping to address this limitation in a future version of Scriptom.