What files you need
You'll need the "iads.idl" file along with other support object idl's
such as "IadsTime.idl" since objects will be returned from the
automation interface.
Step 1:
Include the "iads.idl" in your project in order to have the midl
compiler generate the "iads.h" and "iads_c.h" files. We usually make a
separate directory in our project called COM then shove all the IDL
files in there. Then we turn on the "custom build" and type in the
midl compile statement. This was done so that midl isn't run everytime
we do a build.
use something like this in the "Commands" box:
midl $(InputPath) /I "..\Com\IDL"
use these in the "Outputs" box:
$(InputName).h
$(InputName)_i.c
Step 2:
Need to include "iads.h" somehwere....
Step 3:
Since you asked about accessing the configuration database, you'll need
to included these in your object
IApplication* mIads ;
IConfiguration* mConfig ;
alternative Smart pointer example:
CComPtr<IIadsApplication> mIads - can really cleanup the code below !!
Step 4:
In you object initialization section - make the objects
mIads = NULL ;
CLSID clsid ;
hr = ::CLSIDFromProgID(L"Iads.Application", &clsid) ;
if( hr == S_OK )
{
hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL,
__uuidof(IApplication), (void**)&mIads ) ;
if( hr != S_OK || mIads == NULL )
{
::OutputDebugString("** -Failed to get IADS pointer\n") ;
mIads = NULL ;
return 0 ;
}
}
mConfig = NULL ;
if( mIads != NULL )
{
hr = mIads->get_Configuration(&mConfig) ;
if( hr != S_OK || mConfig == NULL )
{
::OutputDebugString("** -Failed to get config pointer\n") ;
return 0 ;
}
}
Step 5:
Use the config interface to make a query
IQueryResults* qrs = NULL ;
HRESULT hr = mConfig->SqlQuery( L"Select * from
CurrentFlightInformation" , &qrs ) ;
if( hr != S_OK || qrs == NULL ) return E_FAIL ;
// Pull the return values
VARIANT v; v.vt = VT_I2 ;v.iVal = 0 ;
IQueryResult* qr ;
hr = qrs->Item(v, &qr) ;
if( hr == S_OK && qr != NULL )
{
VARIANT vResult ;
v.iVal = 1 ;
hr = qr->Item(v, &vResult ) ;
if( hr == S_OK && vResult.vt != VT_EMPTY )
{
mFlight = vResult.bstrVal ;
::VariantClear(&vResult) ;
}
Step 6:
Cleanup...
HRESULT CMyObject::FinalRelease(void)
{
if( mConfig != NULL ) mConfig->Release() ;
if( mIads != NULL ) mIads->Release() ;
return S_OK ;
}
Prototyping with Accessing Iads Config steps you sent us, having
run-time troubles.
1) Please Confirm [Iads, IadsTime].idl :
I took both these files from
..\IADS\2004.11.18.ExampleSoftwareFromJim\ExampleCode\SDI
Are these correct files?
2) Breaks at mConfig->SqlQuery call:
I can at least step over all the calls down to this, including
get_Configuration, but SqlQuery breaks. I tried some other calls from
both Interfaces for Configuration&Application for comparison, the
call to CreateParameter also breaks , the others don't but I'm not
sure that means they work. An aside , calls with only "out" parms
don't crash, "in" does. I need to look further at all the IDL
defns myself.
//*********Test Calls start******
/* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Name
)(
IApplication * This,
/* [retval][out] */ BSTR *pVal);
BSTR bStr1;
hr = mIads->get_Name( &bStr1 ) ;
///* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE
IConfiguration_get_Application_Proxy(
// IConfiguration * This,
// /* [retval][out] */ IApplication **ppVal);
IApplication *iApp = NULL;
hr = mConfig->get_Application( &iApp ) ;
///* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CreateParameter
)(
// IConfiguration * This,
// /* [in] */ BSTR name,
// /* [retval][out] */ IParameter **ppVal);
IParameter *iParm = NULL;
BSTR aBstr =L"some string";
hr = mConfig->CreateParameter( aBstr, &iParm ) ;
//*********Test Calls end******
3) Environment Configuration:
I add the source these files to Project source directory: Iads_i.c,
IadsTime_i.c, Iads.idl, IadsTime.idl
Anything else I should need in environment? Registering?
4) CoCreate setups:
::CLSIDFromProgID(L"Iads.Application", &clsid) ;
::CoCreateInstance( clsid, NULL, CLSCTX_ALL,
__uuidof(IApplication), (void**)&mIads ) ;
Should clsid be a CLSID_Application, and what tells me that
"Iads.Application" is a correct entry?
Enough to start, thanks,
Randal
I'll answer your questions in turn:
1) I'm not sure about these files - but I sent the "iads.idl" to Ben.
Unfortunately these files aren't part of the release - yet. We'll get
the corrected in the next version. Having said this I don't think this
is your problem, see answers below
2) I believe the problem you're having is assigning a string to a
non-allocated BSTR(it's not a class), so when it's passed into the
interface it crashes. Following are some techniques to try:
The offending code ==> BSTR aBstr =L"some string";
BSTR aBstr = ::SysAllocString(L"some string") ; //check the help system
for all of the "SysAlloc" BSTR stuff - damn VB - sorry...
or
CComBSTR aBstr = L"some string" ; // This is an ATL BSTR wrapper class
derived from BSTR so it's compatible - need the #include <atl.h>
or
just put the string literal in the call as in my example - quickest way
to try things out
3) No need to register - IADS register's itself (the automaton
interface) when the client runs.
4) "clsid" is correct, it contains the necessary info from the
CLSIDFromProgID() call for the CoCreate(). "iads.application" is the
ProgId and is in the registry. So - yep it's required..
Hope this helps - let me know if there are any further troubles or just
general questions
Cordially
-Pat
'The following VB 6.0 app demonstrates use of the IADS automation
interface.
'The automation interface allows you to write specific applications in
VB to
'perform processes in IADS such as Post-Flight batch commanding,
'custom analysis plugins, custom derived functions, etc...
'This application can be brought up and shut down at any time without
affecting
'the operation of IADS. If IADS is not currenly running when this app
'starts, the creation of a reference to an the Application object will
automatically
'execute IADS and connect to it through the automation interface
'See comments throughout code or step though code in debugger (must
have IADS 3.5 or greater
'installed and "Iads ClientWorkstation Object Library" checked in your
VB Project->References menu)
Dim Iads As Application
Dim Aw As AnalysisWindow
Private Sub Form_Load()
On Error Resume Next
'Creates a local connection to the automation interface of IADS
currently
'Running on the local machine. If it's not running, it will execute
IADS and
'and then connect
Set Iads = New IadsAutomationLib.Application
Iads.
'Creates a Remote connection to IADS running on some other machine
on the
'network using CreateObjectEx in VbComExtras module
'Set Iads = CreateObjectEx("Iads.Application", "pat2x1500",
EARLY_BINDING)
' Temporary method to query when analysis windows are contructed
after login
' This will be removed when events have been added to the
automation interface
' (OnDesktopLoad)
Timer1.Interval = 1000
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
On Error GoTo errHandler
'Iterate through each analysis window on the user's currenly active
desktop
'and builds a list for the Aws dropDown, if needed
If (AwList.ListCount <> Iads.ActiveDesktop.AnalysisWindows.Count)
Then
AwList.Clear
Dim eachAw As AnalysisWindow
For Each eachAw In Iads.ActiveDesktop.AnalysisWindows
AwList.AddItem eachAw.Name
Next
End If
'Get a reference to the active (visible) analysis window on the
desktop
If (Aw Is Nothing) Then 'Can't combine below if statement because
VB doesn't shortcut if statements
'Set VBs cached notion of the active window
Set Aw = Iads.ActiveDesktop.ActiveAnalysisWindow
AwList.Text = Aw.Name 'Update dropdown text to new window
End If
'If currently active window changed, change the dropdown text
If (Aw.Name <> Iads.ActiveDesktop.ActiveAnalysisWindow.Name) Then
'Sets the dropdown text to the name of the active Analysis
window
Set Aw = Iads.ActiveDesktop.ActiveAnalysisWindow
AwList.Text = Aw.Name
End If
'Sets the current time textbox from the Aw's current time
Me.CurrentTime.Text = Aw.CurrentTime.TimeString
errHandler:
End Sub
'Use this technique to make a window invisible
Private Sub Hide_Click()
Aw.Visible = False
End Sub
'Use this technique to make a window visible (if it is currently
invisible)
Private Sub Show_Click()
Aw.Visible = True
End Sub
'Use this technique to send window to the Windows taskbar, thus hiding
it
Private Sub Minimize_Click()
Aw.WindowState = Minimized
End Sub
'Use this technique to restore window to its original size after
calling either Minimize or Maximize
Private Sub Restore_Click()
Aw.WindowState = Normal
End Sub
'Use this technique to enlarge window to full size of screen
Private Sub Maximize_Click()
Aw.WindowState = Maximized
End Sub
' Use this technique to overlay values on stripcharts within an
Analysis Window
' This can be used to show processed results of a computation such as
curve fit,
' model predicted results. or previous flight data
Private Sub CreateDataOverlay_Click()
'Get the start time the analysis window
Dim startTime As IIadsTime
Set startTime = Aw.CurrentTime
'Create references to a display, parameter, and a data overlay
Dim display As DataDisplay
Dim overlay As DataOverlay
Dim param As Parameter
'Set the display to the first display within the Aw
Set display = Aw.DataDisplays.Item(0)
'Get the active parameter in the display (one that is in foreground
if multiple)
Set param = display.ActiveParameter
'Add a data overlay to the active parameter within that display
Set overlay = param.DataOverlays.Add
' Work in progress....Add an event marker......
' overlay.Initialize EventMarker,
Iads.ActiveAnalysisWindow.CurrentTime,
display.ActiveParameter.CurrentTime, "Plugin Test.. Event Marker",
Nothing, 0
'Move time backwards by ten data points, given the SampleRate of
the parameter
startTime.RetractTime 10, param.SampleRate
'Instruct parameter to start at the time specified by startTime
'(ten data point backwards from the first visible point on the
stripchart)
param.CurrentTime = startTime
'Create an array of the values at this time, multiplying them by
1.2
Dim Data(10 - 1) As Double
Dim i As Integer
For i = 0 To 9
'Assign array element to parmameter value at the current time
'Then advance parameter's notion of current time by 1 data
point
Data(i) = param.Value(TimeAdvanceFoward) * 1.2
Next i
'Initialize an overlay as a custom type "MyCustomOverlayType",
who's values
'substitute for the original data (data and overlay will still both
be visible)
'
overlay.InitializeCustom "MyCustomOverlayType", True, startTime,
Data, "Plugin Test.."
overlay.AlphaBlend = 0.5 ' Visually blend overlay into original
data line by 50% (50% transparent)
overlay.DrawingStyle = ConnectedLines 'Overlay will be drawn as
connected lines
overlay.PenWidthModifier = 1 'Overlay line width is 1 pixel wider
than original line width
overlay.Miter = True 'Join overlay to original data
overlay.Color = RGB(0, 100, 0) 'Color of overlay is darkish-green
'Instruct the Analysis Window to tell all of it's child displays to
redraw
Aw.Redraw
End Sub
' Use this technique to modify chart speed of stripcharts within an
Analysis Window
Private Sub ChartSpeedDown_Click()
'Grab the user's requested ChartSpeed string from gui and
decrements value by 100
ChartSpeed.Text = Val(ChartSpeed.Text) - 100
'Instruct the Analysis Window to tell all of it's child stripchart
to
'display at the requested chartspeed
Aw.ChartSpeedMMPerSecond = Val(ChartSpeed.Text)
'Instruct the Analysis Window to tell all of it's child displays to
redraw
Aw.Redraw
End Sub
' Use this technique to modify chart speed of stripcharts within an
Analysis Window
Private Sub ChartSpeedUp_Click()
'Grab the user's requested ChartSpeed string from gui and
increments value by 100
ChartSpeed.Text = Val(ChartSpeed.Text) + 100
'Instruct the Analysis Window to tell all of it's child stripchart
to
'display at the requested chartspeed
Aw.ChartSpeedMMPerSecond = Val(ChartSpeed.Text)
'Instruct the Analysis Window to tell all of it's child displays to
redraw
Aw.Redraw
End Sub
' Use this technique to add a display to an Analysis Window
Private Sub CreateDataDisplay_Click()
'Add display to Aw and return a reference to new display (ignoring
return value here)
'The arguement can be either a ProgId from an ActiveX control
registered on
'your system or an instrinsic IADS dataDisplay className such as
'IadsDataDisplays.StripChart, IadsDataDisplays.CrossPlot,
IadsDataDisplays.DisplayPanel
'IadsDataDisplays.AlphaNumeric.... The intrinsic display ProgIds
are not
'registered on your system, so you can't use OleView to find them.
They are
'internal controls for now but eventually converted to fully
registered
'ActiveX controls
Aw.DataDisplays.Add ProgId.Text
End Sub
'Use this technique to instruct Analysis window to display data at a
'specific time within the data set
Private Sub TimeDown_Click()
'Create a reference to an IadsTime object
Dim t As IIadsTime
'Set it equal to the analysis window's current time
Set t = Aw.CurrentTime
'Subtract one second from the current time
t.RetractTime 1, 1#
'Tell analysis window to snap all of it's child displays to the new
time
Aw.CurrentTime = t
'Update gui with that time using it's string representation
Me.CurrentTime.Text = Aw.CurrentTime.TimeString
End Sub
'Use this technique to instruct Analysis window to scroll though data
to a
'specific time within the data set
Private Sub TimeUp_Click()
'Create a reference to an IadsTime object
Dim t As IIadsTime
'Set it equal to the analysis window's current time
Set t = Aw.CurrentTime
'Add one second to the current time
t.AdvanceTime 1, 1#
'Tell analysis window to snap all of it's child displays to the new
time
Aw.CurrentTime = t
'Update gui with that time using it's string representation
Me.CurrentTime.Text = Aw.CurrentTime.TimeString
End Sub