v10.50 v10.55 Alpha v10.54 Alpha v10.53 Alpha v10.52 Alpha v10.51 Alpha
v10.50 v10.55 Alpha v10.54 Alpha v10.53 Alpha v10.52 Alpha v10.51 Alpha

Analyzer Events Callback Interface

_IAnalyzerEvents dispinterface

In order to retrieve the events from the USB Protocol Suite application, you must implement the _IAnalyzerEvents interface.

Since this interface is the default source interface for the UsbAnalyzer object, there is a very simple implementation from such languages as Visual Basic, VBA, VBScript, WSH, etc.

C++ implementation used in the examples below implements a sink object by deriving it 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 which is to be handled:

C++
class CAnalyzerSink : public IDispEventImpl<IDC_SRCOBJ, CAnalyzerSink>

{

BEGIN_SINK_MAP(CAnalyzerSink)

	//Make sure the Event Handlers have __stdcall calling convention

	SINK_ENTRY(IDC_SRCOBJ, 1, OnTraceCreated)

	SINK_ENTRY(IDC_SRCOBJ, 2, OnStatusReport)

END_SINK_MAP()

. . .

}

Then, after you establish the connection with the server, you need to advise your implementation of the event interface:

C++
hr = CoCreateInstance( CLSID_UsbAdvisor, NULL, 

                          CLSCTX_SERVER, IID_IUsbAnalyzer, (LPVOID *)&m_poUsbAnalyzer );

	m_poAnalyzerSink = new CAnalyzerSink();

	// Make sure the COM object corresponding to pUnk implements IProvideClassInfo2 or

	// IPersist*. Call this method to extract info about source type library if you

	// specified only 2 parameters to IDispEventImpl 

	hr = AtlGetObjectSourceInterface(m_poUsbAnalyzer, &m_poAnalyzerSink->m_libid, 

		&m_poAnalyzerSink->m_iid, &m_poAnalyzerSink->m_wMajorVerNum, 

&m_poAnalyzerSink->m_wMinorVerNum);

        if ( FAILED(hr) )

return 1;

	// connect the sink and source, m_poUsbAnalyzer is the source COM object

	hr = m_poAnalyzerSink->DispEventAdvise(m_poUsbAnalyzer, &m_poAnalyzerSink->m_iid);

if ( FAILED(hr) )

return 1;

_IAnalyzerEvents::OnTraceCreated

C++
HRESULT OnTraceCreated (
[in] IDispatch* trace );

Fired when a trace is created. This event is a result of an IAnalyzer::StartRecording or IAnalyzer::StopRecording method call.

Parameters


trace

Address of a pointer to the UsbTrace object primary interface.

Remarks

Make sure the event handlers have __stdcall calling convention.

Example: VBScript

Visual Basic
<OBJECT 

ID = Analyzer 

CLASSID = "clsid:0B179BB3-DC61-11d4-9B71-000102566088" >

</OBJECT>

<P ALIGN=LEFT ID=StatusText></P>

<SCRIPT LANGUAGE="VBScript">

<!--

Dim CurrentTrace

Sub Analyzer_OnTraceCreated(ByRef Trace)

On Error Resume Next

Set CurrentTrace = Trace

If Err.Number <> 0 Then

MsgBox Err.Number & ":" & Err.Description

End If

StatusText.innerText = "Trace '" & CurrentTrace.GetName & "' created"

End Sub

-->

</SCRIPT>

Example: C++

C++
HRESULT __stdcall OnTraceCreated( IDispatch* trace )

{

IUsbTrace* usb_trace;

HRESULT hr;

hr = trace->QueryInterface( IID_IUsbTrace, (void**)&usb_trace );

if (FAILED(hr)) 

{

_com_error er(hr);

if (er.Description().length() > 0)

    ::MessageBox( NULL, er.Description(), _T("UsbAnalyzer client"), MB_OK );

else

    ::MessageBox( NULL, er.ErrorMessage(),_T("UsbAnalyzer client"), MB_OK );

return hr;

               }

	. . . 

return hr;

	}

_IAnalyzerEvents::OnStatusReport

C++
HRESULT OnStatusReport (
[in] short subsystem, 
[in] short state, 
[in] long percent_done );

Fires when there is a change in Analyzer state or there is a change in progress (percent_done) of the Analyzer state.

Parameters


subsystem

Subsystem sending event has the following values:

RECORDING_PROGRESS_REPORT ( 1 ) – recording subsystem

GENERATION_PROGRESS_REPORT ( 2 ) – recording subsystem

state

Current Analyzer state; has the following possible values:

If subsystem is RECORDING_PROGRESS_REPORT:

ANALYZERSTATE_IDLE

(-1 ) Idle

ANALYZERSTATE_WAITING_TRIGGER

( 0 ) Recording in progress, Analyzer is waiting for trigger

ANALYZERSTATE_RECORDING_TRIGGERED

( 1 ) Recording in progress, Analyzer triggered

ANALYZERSTATE_UPLOADING_DATA

( 2 ) Uploading in progress

ANALYZERSTATE_SAVING_DATA

( 3 ) Saving data in progress

ANALYZERSTATE_RT_UPLOADING_DATA

( 8 ) Recording and uploading data concurrently

If subsystem is GENERATION_PROGRESS_REPORT:

ANALYZERSTATE_GEN_IDLE

( 400 ) Generator is idle

ANALYZERSTATE_GEN_DOWLOADING

( 401 ) Generator is downloading object code

ANALYZERSTATE_GEN_GENERATING

( 402 ) Generator is working

ANALYZERSTATE_GEN_PAUSED

( 403 ) Generator is paused

percent_done

Shows the progress of currently performing operation (valid only if subsystem is RECORDING_PROGRESS_REPORT):

  • When Analyzer state is ANALYZERSTATE_IDLE, this parameter is not applicable.

  • When Analyzer state is ANALYZERSTATE_WAITING_TRIGGER or ANALYZERSTATE_RECORDING_TRIGGERED, this parameter shows Analyzer memory utilization.

  • When Analyzer state is ANALYZERSTATE_UPLOADING_DATA or ANALYZERSTATE_RT_UPLOADING_DATA , this parameter shows the percent of data uploaded.

  • When Analyzer state is ANALYZERSTATE_SAVING_DATA, this parameter shows the percent of data saved.

  • When Analyzer state is  ANALYZERSTATE_UPLOADING_DATA_DONE, this parameter is equal to Uploaded MBytes.

Remarks

Make sure the event handlers have __stdcall calling convention.

Example: VBScript

Visual Basic
<OBJECT 

ID = Analyzer 

CLASSID = "clsid:0B179BB3-DC61-11d4-9B71-000102566088" >

</OBJECT>

<P ALIGN=LEFT ID=StatusText></P>

<SCRIPT LANGUAGE="VBScript">

<!--

Function GetRecordingStatus(ByVal State, ByVal Percent)

Select Case State

Case -1: GetRecordingStatus = "Idle"

Case  0: GetRecordingStatus = "Recording - Waiting for trigger"

Case  1: GetRecordingStatus = "Recording - Triggered"

Case  2: GetRecordingStatus = "Uploading"

Case  3: GetRecordingStatus = "Saving Data"

Case Else: GetRecordingStatus = "Invalid recording status"

End Select

GetRecordingStatus = GetRecordingStatus & ", " & Percent & "% done"

End Function

Dim RecordingStatus

Sub Analyzer_OnStatusReport(ByVal System, ByVal State, ByVal Percent) 

Select Case System

Case 1  RecordingStatus = GetRecordingStatus( State, Percent )

End Select

End Sub

-->

</SCRIPT>

Example: C++

C++
#define	RECORDING_PROGRESS_REPORT		( 1 )

#define	ANALYZERSTATE_IDLE			( -1 )

#define	ANALYZERSTATE_WAITING_TRIGGER		( 0 )

#define	ANALYZERSTATE_RECORDING_TRIGGERED	( 1 )

#define	ANALYZERSTATE_UPLOADING_DATA		( 2 )

#define	ANALYZERSTATE_SAVING_DATA		( 3 )

HRESULT __stdcall OnStatusReport( short subsystem, short state, long percent_done )

{

switch ( subsystem )

{

case RECORDING_PROGRESS_REPORT:

UpdateRecStatus( state, percent_done );

break;

}

TCHAR buf[1024];

_stprintf( buf, _T("%s"), m_RecordingStatus );

::SetWindowText( m_hwndStatus, buf );

		return S_OK;

}

	void UpdateRecStatus( short state, long percent_done )

	{

TCHAR status_buf[64];

switch ( state )

{

case ANALYZERSTATE_IDLE: 

_tcscpy( status_buf, _T("Idle") );

break;

case ANALYZERSTATE_WAITING_TRIGGER: 

_tcscpy( status_buf, _T("Recording - Waiting for trigger") );

break;

case ANALYZERSTATE_RECORDING_TRIGGERED: 

_tcscpy( status_buf, _T("Recording - Triggered") );

break;

case ANALYZERSTATE_UPLOADING_DATA: 

_tcscpy( status_buf, _T("Uploading") );

break;

case ANALYZERSTATE_SAVING_DATA: 

_tcscpy( status_buf, _T("Saving data") );

break;

default: 

_tcscpy( status_buf, _T("Unknown") );

break;

}

_stprintf( m_RecordingStatus, _T("%s, done %ld%%"), status_buf, percent_done );