Author Topic: Passing reactors/callbacks to COM object and calling them from the COM object  (Read 4728 times)

0 Members and 1 Guest are viewing this topic.

SIDESHOWBOB

  • Guest
I tried passing a function to my COM object as an argument, with the hope that the COM object might be handed an IDispatch* which I could call ...
Code - Auto/Visual Lisp: [Select]
  1. (defun hi () (princ "hi\n"))
  2. (vlax-invoke-method calculation 'callbacktest 'hi)
  3. ; error: lisp value has no coercion to VARIANT with this type:  HI
but vlax-invoke-method seems to expect a VARIANT rather than a function for its argument. 

Is there a way to do this does anyone know?

Daniel Eiszele

  • Newt
  • Posts: 85
Maybe pass your autocad application object as well as a string representing the lisp function you wish to create a callback to and then use late binding (or early binding if you have the autocad type library linked), to call application.document.utility.sendcommand("function name"). You could also pass the utility object directly.  This is untested but I am sure it will pass an Idispatch interface you can cast to the relevant interface.

BlackBox

  • King Gator
  • Posts: 3770
AFAIK- it's not vlax-invoke-method that is expecting a variant, but the Calculation Method in your example above.

Perhaps this is only loosly related to the topic, but at least when calling a Method, one may get different returns depending on the syntax of the calling statement, I.e., vlax-invoke, etc. Not sure if this has any role in calling any given Method, per-se.

HTH
"How we think determines what we do, and what we do determines what we get."

SIDESHOWBOB

  • Guest
I don't think my callbacktest is expecting a variant, here's the declaration:

Code - C++: [Select]
  1. interface ICalculation : IDispatch{
  2.         [id(7), helpstring("method callbacktest")] HRESULT callbacktest([in] IDispatch* callback);
  3. };
  4.  

SIDESHOWBOB

  • Guest
Calling vlax-invoke instead is a nice idea though I get
Code - Auto/Visual Lisp: [Select]
  1. ; error: argument type mismatch: HI
... will have a go with Daniel's suggestion

SIDESHOWBOB

  • Guest
Daniel - I have nearly got your suggestion working, thank you!!  (The only difference being that SendCommand is a member of Document, not Utility). 

Is there a way to prevent the command being echoed in autocad though?  One use for a callback I have is setting a progress bar, so it won't look great to see
(acet-ui-progress-safe n) appear 100 times in the command window.

SIDESHOWBOB

  • Guest
Another issue I have just found is that the commands sent this way seem to be queued until my call to (vlax-invoke-method) is over.  Is there any way to have them executed immediately?

Daniel Eiszele

  • Newt
  • Posts: 85
Daniel - I have nearly got your suggestion working, thank you!!  (The only difference being that SendCommand is a member of Document, not Utility). 

Is there a way to prevent the command being echoed in autocad though?  One use for a callback I have is setting a progress bar, so it won't look great to see
(acet-ui-progress-safe n) appear 100 times in the command window.

Yes, I remembered that after I replied.  You can use Document.EvaluateLisp() to send your commands without echoing to the command line. (It may also remedy your second problem also?)
« Last Edit: March 19, 2012, 05:46:59 PM by Daniel Eiszele »

SIDESHOWBOB

  • Guest
There doesn't seem to be a method on Application or Document called EvaluateLisp.

Where are these all documented?  I found this link http://www.kxcad.net/autodesk/autocad/AutoCAD_ActiveX_and_VBA_Reference/idh_application_object.htm which mentioned a method Eval() but that's for VBA not Lisp.

Daniel Eiszele

  • Newt
  • Posts: 85
Ahh... I do most of my hacking for Bricscad and found the function by accident by interrogating my IDE's intellisense for the document object.  It seems that the function isn't even documented in the Bricscad Help Files.  I have however found reference to something called the "Visual Lisp ActiveX Module" which looks promising for Autocad use.  The only thing is it seems to be undocumented also, which means a bit of googling and probably a lot of trial and error!  There are probably arx functions that you could reference if you are confident doing this but nothing that is pure COM so far as I understand.

BlackBox

  • King Gator
  • Posts: 3770
For Visual LISP documentation, consult the VLIDE's Apropos, and VBAIDE's developer documentation. Both Visual LISP and VBA can access the ActiveX API.
"How we think determines what we do, and what we do determines what we get."

SIDESHOWBOB

  • Guest
Thanks RenderMan but I'm looking for the reverse really - wanting to call some visual lisp functions from ActiveX/COM, not vice versa.

SIDESHOWBOB

  • Guest
Looks like if I can't callback synchronously over COM I'll have to pop up my own progress bar window.

Is there a call that tells autocad to at least handle window events so it doesn't appear to freeze up while my dll is calculating?

Daniel Eiszele

  • Newt
  • Posts: 85
Looks like if I can't callback synchronously over COM I'll have to pop up my own progress bar window.

Is there a call that tells autocad to at least handle window events so it doesn't appear to freeze up while my dll is calculating?

The synchronous call may be possible using the visual lisp activex module but if that's too much effort (and it probably is), have you considered converting your activex dll to a Com addin and do away with the lisp completely?

As to the second issue, surely if you are displaying a progress bar it shouldn't matter if autocad appears to "freeze" as the bar informs the user it is still working?

SIDESHOWBOB

  • Guest
Daniel thanks again for the pointers - but I have to ask

The Visual lisp activex module - what is that and where to find docs?

What is a COM addin (from an autocad perspective) and what extra functionality would that buy me given I can already make COM calls to autocad from my c++?