_IVScriptEngineEvents callback interface
To retrieve the event notifications from the UsbAnalyzer application when a verification script engine object is running a script, you must implement the _IVScriptEngineEvents callback interface.
Because this interface is a default source interface for the IVScriptEngine object, there is a very simple implementation from such languages as Visual Basic, VBA, VBScript, and WSH.
Remarks
Some script engines impose restrictions on handling events from “indirect” automation objects in typeless script languages (when the automation interface to the object is obtained from a call of some method, rather than from a creation function – like CreateObject() in VBScript). Teledyne LeCroy PSG USB Protocol Suite™ provides a special COM class that allows receiving and handling notifications from VSE objects, even in script languages not supporting event handling from "indirect" objects.
(Please refer to CATCAnalyzerAdapter for details.)
Example: C++
The C++ implementation used in the examples below implements an event sink object by deriving from IDispEventImpl but not specifying the type library as a template argument. Instead, the type library and default source interface for the object are determined using AtlGetObjectSourceInterface(). A SINK_ENTRY() macro is used for each event from each source interface to be handled:
class CVSEngineSink : public IDispEventImpl<IDC_SRCOBJ_VSE, CVSEngineSink >
{
public:
. . .
BEGIN_SINK_MAP(CVSEngineSink)
// Make sure the Event Handlers have __stdcall calling convention.
SINK_ENTRY( IDC_SRCOBJ_VSE, 1, OnVScriptReportUpdated )
SINK_ENTRY( IDC_SRCOBJ_VSE, 2, OnVScriptFinished )
SINK_ENTRY( IDC_SRCOBJ_VSE, 3, OnNotifyClient )
END_SINK_MAP()
HRESULT __stdcall OnVScriptReportUpdated ( BSTR newLine, int TAG );
HRESULT __stdcall OnVScriptFinished( BSTR script_name, VS_RESULT result, int TAG );
HRESULT __stdcall OnNotifyClient ( int eventId, VARIANT eventBody, int TAG );
HRESULT Advise(IUnknown* pUnk)
{
AtlGetObjectSourceInterface(pUnk, &m_libid, &m_iid, &m_wMajorVerNum, &m_wMinorVerNum);
return DispEventAdvise(pUnk, &m_iid);
}
HRESULT Unadvise(IUnknown* pUnk)
{
AtlGetObjectSourceInterface(pUnk, &m_libid, &m_iid, &m_wMajorVerNum, &m_wMinorVerNum);
return DispEventUnadvise(pUnk, &m_iid);
}
...
};
Then, after you establish the connection with the server, you need to advise your implementation of the event interface:
IVScriptEngine vscript_engine = NULL;
try
{ vscript_engine = vscript ->GetVScriptEngine(ScriptName ); }
catch ( _com_error& er )
{ SetStatusError( er ); }
if( vscript_engine == NULL )
{
vscript = NULL;
return E_FAIL;
}
CVSEngineSink vse_sink;
HRESULT hr = vse_sink . Advise( vscript_engine ); // “Subscribe” for receiving events
...
VS_RESULT res = SCRIPT_NOT_FOUND;
try
{
res = (VS_RESULT)vscript_engine ->RunVScript();
}
catch ( _com_error& er)
{ SetStatusError( er ); }
// Tear connection with the test case.
vse_sink. Unadvise( vscript_engine );
...
Example: VBA
Public USBTracer As UsbAnalyzer
Public Trace As UsbTrace
Public GVSEngine As VScriptEngine
' VSEngineEventsModule is a special class implementing VSE event handlers.
' It should have, in global declaration section, a line like this:
' Public WithEvents VSEEvents As VScriptEngine
Dim X As New VSEngineEventsModule
Private Sub RunVScritButton_Click()
Dim VSEngine As VScriptEngine
Dim IVScript As IUsbVerificationScript
Dim ScriptName, fileToOpen As String
ScriptName = ThisWorkbook.Sheets("Sheet1").Cells(2, 2)
If USBTracer Is Nothing Then
Set USBTracer = New UsbAnalyzer
If USBTracer Is Nothing Then
MsgBox "Unable to connect to USB Protocol Suite", vbExclamation
Exit Sub
End If
End If
fileToOpen = ThisWorkbook.Sheets("Sheet1").Cells(1, 2)
Set Trace = USBTracer.OpenFile( fileToOpen )
Set IVScript = Trace 'Get the IUsbVerificationScript interface.
Set VSEngine = IVScript.GetVScriptEngine( ScriptName )
' "Subscribe" for receiving VSE events.
' the X variable ( an instance of VSEngineEventsModule class ) will handle them.
Set X.VSEEvents = VSEngine
...
VSEngine.Tag = 12 ' Assign a tag for VSE object.
VSEngine.RunVScript ' Run verification script.
Set X.VSEEvents = Nothing ' "Unsubscribe" for receiving VSE events.
Set VSEngine = Nothing ' Release external
Set IVScript = Nothing ' objects.
End Sub
_IVScriptEngineEvents::OnVScriptReportUpdated
[id(1)] HRESULT OnVScriptReportUpdated([in] BSTR newLine,
[in] int TAG );
Fires when running verification script calls ReportText( newLine ) function.
|
Parameters |
|
|---|---|
|
newLine |
New portion of text reported by verification script |
|
TAG |
VSE object's tag |
Remarks
Make sure that C++ event handlers have __stdcall calling convention.
Example: C++
HRESULT __stdcall OnVScriptReportUpdated (BSTR newLine, int TAG )
{
TRACE( "Line: %s, TAG: %d\n", newLine, TAG );
. . .
return S_OK;
}
Example: VBA
Public WithEvents VSEEvents As VScriptEngine
Public LineIndex As Integer
. . .
Private Sub VSEEvents_OnVScriptReportUpdated
(ByVal newLine As String, ByVal Tag As Long)
ThisWorkbook.Sheets("Sheet1").Cells(LineIndex, 1) = newLine
LineIndex = LineIndex + 1
End Sub
_IVScriptEngineEvents::OnVScriptFinished
[id(2)] HRESULT OnVScriptFinished ( [in] BSTR script_name,
[in] VS_RESULT result, [in] int TAG );
Fires when the verification script stops running.
|
Parameters |
|
|---|---|
|
script_name |
Name of the verification script |
|
result |
Result of the "verification"
|
|
TAG |
VSE object's tag |
Remarks
Make sure that C++ event handlers have __stdcall calling convention.
Example: C++
HRESULT __stdcall CComplTestSink::OnVScriptFinished
( BSTR script_name, VS_RESULT result, int TAG )
{
USES_CONVERSION;
TCHAR tmp[220];
sprintf( tmp, "Script completed, name : %s, result = %d, TAG = %d",
W2A(script_name), result, TAG );
. . .
return S_OK;
}
Example: VBA
Public WithEvents VSEEvents As VScriptEngine
. . .
Private Sub VSEEvents_OnVScriptFinished( ByVal script_name As String,
ByVal result As UWBAutomationLib.VS_RESULT, ByVal Tag As Long )
Dim ResString As String
ResString = "Script name : " & script_name & ", result = " & CStr(result) &
", TAG = " & CStr(Tag)
ThisWorkbook.Sheets("Sheet1").Cells(7, 2) = ResString
End Sub
_IVScriptEngineEvents::OnNotifyClient
[id(3)] HRESULT OnNotifyClient( [in] int eventId,
[in] VARIANT eventBody,
[in] int TAG );
Fires when running verification script calls NotifyClient() function.
|
Parameters |
|
|---|---|
|
EventId |
Event Id |
|
eventBody |
Body of event packed in a VARIANT object |
|
TAG |
VSE object's tag |
Remarks
The information packed in the event body is opaque for VSE, which only packs the information given to NotifyClient() function inside of a verification script into a VARIANT object and sends it to client applications.
(See Teledyne LeCroy PSG USB Verification Script Engine Manual for details about the NotifyClient() script function.)
Example: Teledyne LeCroy PSG USB Verification script
ProcessEvent()
{
. . .
NotifyClient( 2, [in.Index, in.Level, GetChannelName(), GetEventName(),
TimeToText( in.Time )] );
. . .
}
Example: VBA
Public WithEvents VSEEvents As VScriptEngine
. . .
Private Sub VSEEvents_OnNotifyClient( ByVal eventId As Long,
ByVal eventBody As Variant, ByVal Tag As Long )
Dim Col As Integer
Dim Item As Variant
ThisWorkbook.Sheets("Sheet1").Cells(LineIndex, 1) = eventId
If IsArray(eventBody) Then
Col = 3
For Each Item In eventBody
ThisWorkbook.Sheets("Sheet1").Cells(LineIndex, Col) = Item
Col = Col + 1
Next
Else
ThisWorkbook.Sheets("Sheet1").Cells(LineIndex, 2) = eventBody
End If
LineIndex = LineIndex + 1
End Sub