WIN32OLE and Implements Interface Help Needed!

I am trying to control a Microstation application through its VBA api.
I am able
to connect to the object and control it but I am now trying to figure
out how to deal
with Microstation's event handling. In Microstation VBA you declare
that a class implements
an Event interface and make sure the class implements all the methods.
You then call
a method on the Application object

app = WIN32OLE.new('MicrostationDGN.Application.1')
app.visible = TRUE
app.AddSaveAsEventsHandler SaveHandler

I tried to create a class that implements the methods in 'ISaveAsEvents'

class SaveHandler

def AfterRedraw
end

def BeforeRedraw
end
end

but get a segmentation fault because of type mismatch

I also tried to use the WIN32OLE_EVENT class

ev = WIN32OLE_EVENT.new(app, 'IViewUpdateEvents')

=> No such interface supported

Here is a win32ole_pp of the 'AddSaveAsEventsHandler' method

#<WIN32OLE_METHOD:0x32c7ac4: AddViewUpdateEventsHandler
  name="AddViewUpdateEventsHandler",
  dispid=1610744231,
  helpstring="",
  helpcontext=2674,
  helpfile="C:\\PROGRA~1\\Bentley\\Program\\MICROS~1\\MicroStationVBA.chm",
  invoke_kind="FUNC",
  invkind=1,
  return_type="VOID",
  return_type_detail=["VOID"],
  return_vtype=24,
  size_opt_params=0,
  size_params=1,
  offset_vtbl=1720,
  visible?=true,
  event?=false,
  event_interface=nil,
  params=
   [#<WIN32OLE_PARAM:0x32ad494: EventHandler
      name="EventHandler",
      ole_type="IViewUpdateEvents",
      ole_type_detail=["PTR", "USERDEFINED", "IViewUpdateEvents"],
      default=nil,
      input?=true,
      output?=false,
      optional?=false,
      retval?=false>]>

···

*********

Here is an example that they show in the help file for Microstation.
the following is the class file

' This is the implementation of clsEventHandlers. It has Implements
statements declaring that it implements anevent interface.

Implements IViewUpdateEvents

'
' Methods for the IViewUpdateEvents
'
Private Sub IViewUpdateEvents_AfterRedraw(TheViews() As View,
TheModels() As ModelReference, ByVal DrawMode As MsdDrawingMode)
    If UBound(TheModels) < 0 Then
        ' This is a normal update. Everything is being redrawn
    End If
End Sub

Private Sub IViewUpdateEvents_BeforeRedraw(TheViews() As View,
TheModels() As ModelReference, ByVal DrawMode As MsdDrawingMode)

End Sub

******************

Here is how the initialize it. Everything not declared defaults to
the Application object

Private oEventHandlers As clsEventHandlers

Sub InstallHandlers()
    RemoveHandlers
    Set oEventHandlers = New clsEventHandlers
    AddViewUpdateEventsHandler oEventHandlers
End Sub

Sub RemoveHandlers()
    If Not oEventHandlers Is Nothing Then
        RemoveViewUpdateEventsHandler oEventHandlers
    End If
    Set oEventHandlers = Nothing
End Sub

Have you tried posting this on StackOverflow?

Not trying to be rude, but they answer highly specific questions all the
time.

- Cam

···

On Tuesday, May 3, 2016, Dominic Sisneros <dsisnero@gmail.com> wrote:

I am trying to control a Microstation application through its VBA api.
I am able
to connect to the object and control it but I am now trying to figure
out how to deal
with Microstation's event handling. In Microstation VBA you declare
that a class implements
an Event interface and make sure the class implements all the methods.
You then call
a method on the Application object

app = WIN32OLE.new('MicrostationDGN.Application.1')
app.visible = TRUE
app.AddSaveAsEventsHandler SaveHandler

I tried to create a class that implements the methods in 'ISaveAsEvents'

class SaveHandler

def AfterRedraw
end

def BeforeRedraw
end
end

but get a segmentation fault because of type mismatch

I also tried to use the WIN32OLE_EVENT class

ev = WIN32OLE_EVENT.new(app, 'IViewUpdateEvents')

=> No such interface supported

Here is a win32ole_pp of the 'AddSaveAsEventsHandler' method

#<WIN32OLE_METHOD:0x32c7ac4: AddViewUpdateEventsHandler
  name="AddViewUpdateEventsHandler",
  dispid=1610744231,
  helpstring="",
  helpcontext=2674,
  helpfile="C:\\PROGRA~1\\Bentley\\Program\\MICROS~1\\MicroStationVBA.chm",
  invoke_kind="FUNC",
  invkind=1,
  return_type="VOID",
  return_type_detail=["VOID"],
  return_vtype=24,
  size_opt_params=0,
  size_params=1,
  offset_vtbl=1720,
  visible?=true,
  event?=false,
  event_interface=nil,
  params=
   [#<WIN32OLE_PARAM:0x32ad494: EventHandler
      name="EventHandler",
      ole_type="IViewUpdateEvents",
      ole_type_detail=["PTR", "USERDEFINED", "IViewUpdateEvents"],
      default=nil,
      input?=true,
      output?=false,
      optional?=false,
      retval?=false>]>

*********

Here is an example that they show in the help file for Microstation.
the following is the class file

' This is the implementation of clsEventHandlers. It has Implements
statements declaring that it implements anevent interface.

Implements IViewUpdateEvents

'
' Methods for the IViewUpdateEvents
'
Private Sub IViewUpdateEvents_AfterRedraw(TheViews() As View,
TheModels() As ModelReference, ByVal DrawMode As MsdDrawingMode)
    If UBound(TheModels) < 0 Then
        ' This is a normal update. Everything is being redrawn
    End If
End Sub

Private Sub IViewUpdateEvents_BeforeRedraw(TheViews() As View,
TheModels() As ModelReference, ByVal DrawMode As MsdDrawingMode)

End Sub

******************

Here is how the initialize it. Everything not declared defaults to
the Application object

Private oEventHandlers As clsEventHandlers

Sub InstallHandlers()
    RemoveHandlers
    Set oEventHandlers = New clsEventHandlers
    AddViewUpdateEventsHandler oEventHandlers
End Sub

Sub RemoveHandlers()
    If Not oEventHandlers Is Nothing Then
        RemoveViewUpdateEventsHandler oEventHandlers
    End If
    Set oEventHandlers = Nothing
End Sub

--
Sent from Gmail Mobile

Hello,

ev = WIN32OLE_EVENT.new(app, 'IViewUpdateEvents')

=> No such interface supported

Could you try the following?

  ev = WIN32OLE_EVENT.new(app)

  event_interface=nil,

Hmm... I'm not sure... But it seems to me that Win32OLE can't find
event interface. Maybe, the event is not available in Win32OLE.

  Regards,
  Masaki Suketa

···

On Tue, May 03, 2016 at 11:46:34AM -0600, Dominic Sisneros wrote:

I don't think it is listed as an event type in ole. It doesn't implement
IConnectionPointContainer

ev = WIN32OLE_EVENT.new(app)

app.AddSaveAsEventsHandler ev

WIN32OLERuntimeError: (in OLE method `AddSaveAsEventsHandler': )
    OLE error code:0 in <Unknown>
      <No Description>
    HRESULT error code:0x80020005
      Type mismatch

I need a generic com object that implements IDispatch that I can subclass
and then cast to the interface I want

class Handler < ComDispatchObject

implements :{guid} # defines methods of Interface or uses methods_missing
to say it implements interface with guid

end

app.AddSaveAsEventsHandler Handler.new

···

On Fri, May 6, 2016 at 3:15 PM, Masaki Suketa <masaki.suketa@nifty.ne.jp> wrote:

Hello,
On Tue, May 03, 2016 at 11:46:34AM -0600, Dominic Sisneros wrote:
> ev = WIN32OLE_EVENT.new(app, 'IViewUpdateEvents')
>
> => No such interface supported

Could you try the following?

  ev = WIN32OLE_EVENT.new(app)

> event_interface=nil,

Hmm... I'm not sure... But it seems to me that Win32OLE can't find
event interface. Maybe, the event is not available in Win32OLE.

  Regards,
  Masaki Suketa

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hello,

I don't think it is listed as an event type in ole. It doesn't implement
IConnectionPointContainer

ev = WIN32OLE_EVENT.new(app)

app.AddSaveAsEventsHandler ev

WIN32OLERuntimeError: (in OLE method `AddSaveAsEventsHandler': )
    OLE error code:0 in <Unknown>
      <No Description>
    HRESULT error code:0x80020005
      Type mismatch

I need a generic com object that implements IDispatch that I can subclass
and then cast to the interface I want

class Handler < ComDispatchObject

Try to use WIN32OLE_EVENT#handler= method.

  class Hanlder
    # If app fire `XXXEvent` and `onXXXEvent` method is defined in
    # Handler class, then WIN32OLE_EVENT call the method.
    def onXXXEvent
      puts "XXXEvent fired!!!"
    end
  end

  ev = WIN32OLE_EVENT.new(app)
  ev.handler = Handler.new

  Regards,
  Masaki Suketa

···

On Tue, May 10, 2016 at 04:21:59PM -0600, Dominic Sisneros wrote: