activex problem, qfeed

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
ar
Reply | Threaded
Open this post in threaded view
|

activex problem, qfeed

ar
I have an activex control called CONTINUUMXLib. The control provides stock
quotes from a quote server. If I open this control in the Activex Control
Browser, I can then send the #connect message. I sign in to a logon dialog put
up by the control and then the message answers true. The control then puts out
events shown at the bottom of the brower eg

Event: #StatusMessage: #('24 sec since last update.')

I used the ActiveX Component Wizard to generate Smalltalk classes for the
control and then tried to just call the control as follows:

cc := CONTINUUMXLib_DContinuumClient new "initialize" .
cc connect

(tried with and without the initialize)

I just get Catastrophic failure (16rFFFF: Catastrophic failure) in

CONTINUUMXLib_DContinuumCient(ExternalStructure)>>hresultError: -2147418113
CONTINUUMXLib_DContinuumCient>>invokeId:flags:parms:retVal:
CONTINUUMXLib_DContinuumCient>>invokeId:flags:parms:
CONTINUUMXLib_DContinuumCient(IDispatch)>>invokeId:
CONTINUUMXLib_DContinuumCient>>connect

I may have also gotten as far as getting into the logon prompt via this call
at some point but i'm not sure.

I am COM newbie, I was just hoping to get away with being a dumb, ignorant
user of this control :)

Can anyone give me a clue? I dont know all the things that the browser must be
doing to host the control properly.

There are a bunch of other classes generated such as ..._DSnapShotSet which
fail the same way but I cant see those in the browser.

-ar
Dolphin 4.01.3 trial

ps. I have no source for the invokeId:flags:parms.... methods, are these part
of the set of methods which are only hidden in the trial?


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Eric Winger-5
Here's a couple comments which may help (or not)...Plus check out
http://www.object-arts.com/wiki/html/Dolphin/UsingActiveXComponents.htm 
for some more detail on using ActiveX components.

ar wrote:

> I have an activex control called CONTINUUMXLib. The control provides stock
> quotes from a quote server. If I open this control in the Activex Control
> Browser, I can then send the #connect message. I sign in to a logon dialog put
> up by the control and then the message answers true. The control then puts out
> events shown at the bottom of the brower eg
>
> Event: #StatusMessage: #('24 sec since last update.')
>
> I used the ActiveX Component Wizard to generate Smalltalk classes for the
> control and then tried to just call the control as follows:
>
> cc := CONTINUUMXLib_DContinuumClient new "initialize" .
> cc connect
>


Hmmm.... you might try something like:

IDispatch createObject: 'myserver.somethingelse'

where IDispatch is the automation interface & 'myserver.somethingelse'
is the application and program id of the server. Without more knowledge
of your ActiveX control, I can't help fill in the blanks. Perhaps
there's some documentation in your control.

Now perhaps the connect method is doing that for you. I don't know w/o
looking at the control's imported code.


> (tried with and without the initialize)
>
> I just get Catastrophic failure (16rFFFF: Catastrophic failure) in
>
> CONTINUUMXLib_DContinuumCient(ExternalStructure)>>hresultError: -2147418113
> CONTINUUMXLib_DContinuumCient>>invokeId:flags:parms:retVal:
> CONTINUUMXLib_DContinuumCient>>invokeId:flags:parms:
> CONTINUUMXLib_DContinuumCient(IDispatch)>>invokeId:
> CONTINUUMXLib_DContinuumCient>>connect
>


I believe this is basically telling you that the IDispatch interface has
no server connected to it. Once you get connected, you should have an
instance of an interface class which you can send messages to.


...


>
> ps. I have no source for the invokeId:flags:parms.... methods, are these part
> of the set of methods which are only hidden in the trial?
>

I found that most of the ActiveX & COM support method source's were
blocked in the trial edition. Once I purchased the software, they
automagically became unblocked.

Eric


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Christopher J. Demers
In reply to this post by ar
ar <[hidden email]> wrote in message
news:[hidden email]...
> I have an activex control called CONTINUUMXLib. The control provides stock
> quotes from a quote server. If I open this control in the Activex Control
> Browser, I can then send the #connect message. I sign in to a logon dialog
put
> up by the control and then the message answers true. The control then puts
out
> events shown at the bottom of the brower eg
...

I am currently using the Continuum ActiveX interface from Dolphin.  It took
some experimentation to get it working.  I don't remember the specific
reasons for the problems I encountered.  However I can show you what I have
that works.  I seem to recall that it had something to do with the fact that
Continuum was expecting to be used like a visual control on a VB form even
though it is not really visible.  My impression of their ActiveX wrapper was
that it was a bit of a "me too" affair for their C++ DLL.  There are some
fairly low-level aspects to it.

This is what I use:
====================
"Open"
 contClient := AXControlSite progId:
'ContinuumClientX.ContinuumClientCtrl.1'.
 contClient controlDispatch connectDirect: 'userid' password: 'password'
timeOut: 20000.
====================
"Read a quote from a snapshot.  This is out of context, but it should give
you some hints."
 timeOut := (TimeStamp current asSeconds) + 30.
 snap := AXControlSite progId: 'ContinuumX.SnapshotSetCtrl.1'.
 (snap controlDispatch open: self symbol)
  ifTrue: [snap controlDispatch init.
   [(TimeStamp current asSeconds < timeOut)
     ifFalse: [self errorText: 'Data timeout!'.
     "CJD 6-18-2001 If we get a timeout lets change servers and try again."
     self parent contClient controlDispatch  nextServer.
     ^isUpToDate
      ifTrue: [isUpToDate := false.
       self getData]
      ifFalse: [nil]].
    snap controlDispatch isRequestPending] whileTrue.
   snap controlDispatch enterRead.
   self timeStamp: TimeStamp current.
   self dayHighPrice: (snap controlDispatch retDouble: 1). "high"
   self dayLowPrice: (snap controlDispatch retDouble: 2).  "low"
   self price: (snap controlDispatch retDouble: 3). "trade"
   self volume: (snap controlDispatch retDouble: 10). "volume"
   snap controlDispatch leaveRead.
   snap controlDispatch close.
   snap close.
   isUpToDate := true.
   self saveDataToDatabase.
   self trigger: #dataUpdated]
  ifFalse: [self statusText: 'Data error!'. ^nil].
====================
"Close"
 contClient controlDispatch disconnect.
 contClient close.
 contClient := nil.
====================

Hopefully the code did not get too mangled.  Once you get the code right it
should work well with Dolphin.

Chris


ar
Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

ar
Thanks Eric and Christopher.

In both posts it seems like you are not suggesting using the actual smalltalk
classes which were generated. eg using IDispatch instead of the subclass
ContinuumClient. I guess you guys got involved with COM on Dolphin from before
it generated classes which I thought would shield me from the gory details.

Anyway I think you are both saying a similar thing about the control being
expected to be used like a visual control or that it doesnt have a server
connected to it, but I dont understand the implementation of com well enough
yet to know what that really means. (got my Inside Com and Understanding
Activex on order:) . Anyway I should probably be able to tinker with that code
Chris and get it to work ( I once got this to work in VSE a few years ago).
Thanks again.

-alan


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Christopher J. Demers
ar <[hidden email]> wrote in message
news:=3AVPC=[hidden email]...
> Thanks Eric and Christopher.
>
> In both posts it seems like you are not suggesting using the actual
smalltalk
> classes which were generated. eg using IDispatch instead of the subclass
> ContinuumClient. I guess you guys got involved with COM on Dolphin from
before
> it generated classes which I thought would shield me from the gory
details.
...

Disclaimer: I am no ActiveX in Dolphin expert, what I know has been gleaned
from a little experience.  I call upon the real experts to correct me or
clarify things. ;)

Actually it does magically use the classes you generated. ;)  When you
instantiate it Dolphin does some stuff behind the scenes and associates the
generated class with it.  I believe the classes help to make it faster, and
also allow you to fix methods (I had to fix at least one).  I don't think
the ActiveX generated package will automatically be considered a
prerequisite of your application package, so if you save the packages out
and load them into a new image you will need to make sure the ActiveX
generated package gets loaded.  Also when you deploy your application you
will need to make sure the ActiveX generated classes don't get stripped.
You can easily make it a manual prerequisite (package context menu,
properties).

Dolphin does shield you from many of the ActiveX gory details, however there
are limits to what it can automatically do for you.  Based on previous
conversations I have had in this group (should be in the archive) it seems
that ActiveX can have a strong VB bias.  ActiveX in Dolphin is not as easy
as it is in VB.  However with a little experience and once you know the ins
and outs one can quite readily use ActiveX in Dolphin.

Good luck,

Chris


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Blair McGlashan
In reply to this post by ar
Alan
  ...
  In both posts it seems like you are not suggesting using the actual
smalltalk
  classes which were generated. eg using IDispatch instead of the subclass
  ContinuumClient. I guess you guys got involved with COM on Dolphin from
before
  it generated classes which I thought would shield me from the gory
details.

It will shield you from the gory details to a reasonable extent, however it
will not prevent you from getting to them. Unlike VB, Dolphin allows one to
get down to the lowest levels of COM/Active-X, but on the other hand (and to
some extent in consequence) some tasks are more involved.

You will be better off using the generated classes than going through
IDispatch, but this will happen automatically anyway (see below).



Anyway I think you are both saying a similar thing about the control being
expected to be used like a visual control or that it doesnt have a server
connected to it, but I dont understand the implementation of com well enough
yet to know what that really means. (got my Inside Com and Understanding
Activex on order:) . Anyway I should probably be able to tinker with that
code
Chris and get it to work ( I once got this to work in VSE a few years ago).
Thanks again.


Chris is right. This particular control expects to be "hosted" as a full
OCX, even though it is non-visual. The "Catastrophic Failure" error is the
rather over-dramatic description for one of the standard error conditions
E_UNEXPECTED (try 'HRESULT fromInteger: (Win32Errors at: #E_UNEXPECTED)').
In this case I imagine it is reporting that it wasn't expecting the method
invocation before it had been "activated".

I haven't looked at the code Chris posted in detail, but I'm sure it
demonstrates how to programmatically host a visual control without actually
having to put the control into a view, though of course you could do that if
you wish, just as you'd have to drop the control onto a Form in VB in order
to use it.

You won't have wasted your time generating the interface wrapper classes,
since the control host's #controlDispatch method will answer the most
specific interface it can (falling back on IDispatch if the OCX's specific
default interface has not been generated). If the interfaces have not been
generated, then going through IDispatch is possible, but slower and
considerably more clunky.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Blair McGlashan
In reply to this post by ar
Alan

You wrote in message news:=3AVPC=[hidden email]...
> Thanks Eric and Christopher.
>
> In both posts it seems like you are not suggesting using the actual
smalltalk
> classes which were generated. eg using IDispatch instead of the subclass
> ContinuumClient. I guess you guys got involved with COM on Dolphin from
before
> it generated classes which I thought would shield me from the gory
details.

It will shield you from the gory details to a reasonable extent, however it
will not prevent you from getting to them (and perhaps being got at by them
:-)). Unlike VB, Dolphin allows one to get down to the lowest levels of
COM/Active-X, but on the other hand (and to some extent in consequence) some
tasks are more involved than in VB.

You will be better off using the generated classes than going through
IDispatch, but this will happen automatically anyway (see below).

> Anyway I think you are both saying a similar thing about the control being
> expected to be used like a visual control or that it doesnt have a server
> connected to it, but I dont understand the implementation of com well
enough
> yet to know what that really means. (got my Inside Com and Understanding
> Activex on order:) . Anyway I should probably be able to tinker with that
code
> Chris and get it to work ( I once got this to work in VSE a few years
ago).
> Thanks again.

Chris is right. This particular control expects to be "hosted" as a full
OCX, even though it is non-visual. The "Catastrophic Failure" error is the
rather over-dramatic description for one of the standard error conditions
E_UNEXPECTED (try 'HRESULT fromInteger: (Win32Errors at: #E_UNEXPECTED)').
In this case I imagine it is reporting that it wasn't expecting the method
invocation before it had been "activated".

I haven't looked at the code Chris posted in detail, but I'm sure it
demonstrates how to programmatically host a visual control without actually
having to put the control into a view, though of course you could do that if
you wish, just as you'd have to drop the control onto a Form in VB in order
to use it.

You won't have wasted your time generating the interface wrapper classes,
since the control host's #controlDispatch method will answer the most
specific interface it can (falling back on IDispatch if the OCX's specific
default interface has not been generated). If the interfaces have not been
generated, then going through IDispatch is possible, but slower and
considerably more clunky.

Regards

Blair


ar
Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

ar
In reply to this post by Christopher J. Demers
Chris,

>This is what I use:

Thanks, that code worked for me, using the AXControlSite. Now I'm trying to
get events. Here is my test code:

cc := AXControlSite progId:'ContinuumClientX.ContinuumClientCtrl.1' .
q := cc controlDispatch.
q when: #StatusMessage: perform: [ : text |Transcript cr; nextPutAll: text ].
q trigger: #StatusMessage: with: 'test' . "this works on 2nd evaluation (?)"
q connect.

I dont get the heartbeat event from the server. (like the browser does). What
am i missing?

-alan


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Blair McGlashan
Alan

You wrote in message news:GnQZPHc1Wd6nSC0m=+[hidden email]...
> ....
> Thanks, that code worked for me, using the AXControlSite. Now I'm trying
to
> get events. Here is my test code:
>
> cc := AXControlSite progId:'ContinuumClientX.ContinuumClientCtrl.1' .
> q := cc controlDispatch.
> q when: #StatusMessage: perform: [ : text |Transcript cr; nextPutAll:
text ].
> q trigger: #StatusMessage: with: 'test' . "this works on 2nd evaluation
(?)"
> q connect.
>
> I dont get the heartbeat event from the server. (like the browser does).
What
> am i missing?

The events are triggered off the "presenter" of the control site (start
browsing in AXControlSite>>connectSink). By default, as in this case, this
will be the AXControlSite itself. Therefore your #when:etc messages should
be sent to 'cc' rather than 'q'.

As background information there are 3 mechanisms by which one may receive
events from a control:
1) Specific/individual events, as defined in the default 'source' interface
of the control. These are they which you are trying to receive above. By
default the triggering of individual events is enabled.
2) A generic event, #axEvent:withArguments:, handlers of which receive all
the specific events with the name of the event being the first argument.
This is how the control browser receives all events from a control without
having to explicitly register handlers for each and every one of them. This
is mostly useful for generic hosts (such as the control browser). By default
the generic event is disabled, aAXControlBrowser>>updateControlInfo shows
how to enable it. See also AXControlBrowser>>onViewOpened (which registers a
handler for the generic event), and AXControlBrowser>>onEvent:withArguments:
(the generic event handler)
3) Property changing and changed notifications. This is a separate, generic,
mechanism by which OCXs request permission from their host to change the
value of a property, and subsequently notify observers that a property value
has been changed. Again see AXControlBrowser>>onViewOpened (which registers
handlers for the property change notifications) and
AXControlBrowser>>onPropertyChanging:accept: and
AXControlBrowser>>onPropertyChanged: (the handlers for the changing and
changed notifications respectively).

As for why you don't see any output on the Transcript at first, this is
because the output is buffered and is only displayed when the buffer is
flushed. Emiting a cr flushes the buffer automatically, so send #cr last
rather than first.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

Christopher J. Demers
In reply to this post by ar
ar <[hidden email]> wrote in message
news:GnQZPHc1Wd6nSC0m=+[hidden email]...
> Thanks, that code worked for me, using the AXControlSite. Now I'm trying
to
> get events. Here is my test code:
>
> cc := AXControlSite progId:'ContinuumClientX.ContinuumClientCtrl.1' .
> q := cc controlDispatch.
> q when: #StatusMessage: perform: [ : text |Transcript cr; nextPutAll:
text ].
> q trigger: #StatusMessage: with: 'test' . "this works on 2nd evaluation
(?)"
> q connect.
>
> I dont get the heartbeat event from the server. (like the browser does).
What
> am i missing?

Sorry for the delay, I just came back from a visit to Florida.
Unfortunately I can not help you with this as I have not used qfeed events.
My program does not use the streaming feature, but rather polls snapshots
for different stocks at preset intervals.  My understanding is that you can
only stream data for one symbol at a time with qfeeds.  Hopefully Blair's
comments will help you.

Good luck,

Chris


Reply | Threaded
Open this post in threaded view
|

Re: activex problem, qfeed

ar-2
I am getting a message, 'HRESULT Error: Type mismatch' when calling a
generated method in  a _DTRecordSet. The method is defined as:

getRecString: nRecord fIx: fIx
        "Answer the <BSTR> result of invoking the COM Object's GetRecString()
method."

        ^(self invokeId: 28 with: nRecord with: fIx)

My call is:

self getRecString: 0 flx: 3

nRecord and flx are definitely supposed to be integers (indexes)

For some reason, the doc I have for this method does not match:

bool TRecordSet::GetRecString(RECIX r, FLDIX f, LPTSTR lpStr, int maxCount);

I cant account for the difference but I'm pretty sure that the generated st
code above is the correct wrapping of this function.

btw does Steve Waring still hang out here (fellow Dolphin/Qfeed user who has
gone a lot further with it than I )