Hello All,
I am having trouble with controling how the instances of the process are managed when starting BO Designer (or Reporter same issue).
When using CreateObject or New in Visual Basic, it always creates a new instance of the Designer process that need to be closed at the end. If the user forget to close any current instance, another one is created and the API may not work very well (crash) in this case.
What I want to achieve is a reuse of any open application already running, or start a new one if none could be found.
I wrote a tiny VB program showing this but for some reason it doesn't work. I cannot reuse any application already started, using the GetObject and the Running Object Table (ROT).
This is a standard VB exe project with two buttons labelled "CreateObject" and "GetObject".
Do you have any idea why GetObject doesn't work?
Best Regards,
Olivier
-----------------------------------------------------------
Private Type GUIDs
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
'Declares needed to register object in the ROT
Private Const ACTIVEOBJECT_STRONG = 0
Private Const ACTIVEOBJECT_WEAK = 1
Private Declare Function CLSIDFromProgID Lib "ole32.dll" (ByVal ProgID As Long, rclsid As GUIDs) As Long
Private Declare Function CoDisconnectObject Lib "ole32.dll" (ByVal pUnk As IUnknown, pvReserved As Long) As Long
Private Declare Function RegisterActiveObject Lib "oleaut32.dll" (ByVal pUnk As IUnknown, rclsid As GUIDs, ByVal dwFlags As Long, pdwRegister As Long) As Long
Private Declare Function RevokeActiveObject Lib "oleaut32.dll" (ByVal dwRegister As Long, ByVal pvReserved As Long) As Long
Dim OLEInstance As Long
'The BO Designer application object
Const DESIGNER_NAME = "Designer.Application"
Dim Bod As Designer.Application
Private Sub CreateObjectButton_Click()
Set Bod = CreateObject(DESIGNER_NAME)
Bod.Visible = True
Bod.Window.State = dsMinimized
Call InitRot
MsgBox Bod.Version
End Sub
Private Sub GetObjectButton_Click()
Set Bod = GetObject(, DESIGNER_NAME)
Bod.Visible = True
Bod.Window.State = dsMinimized
MsgBox Bod.Version
Call Quit
End Sub
Private Sub InitRot()
'The magic happens here
'This code is responsible for creating the entry for ROT (Running Object Table)
Dim mGUID As GUIDs
Dim lp As Long
OLEInstance = 0
lp = CLSIDFromProgID(StrPtr(DESIGNER_NAME), mGUID)
If lp = 0 Then
lp = RegisterActiveObject(Bod, mGUID, ACTIVEOBJECT_WEAK, OLEInstance)
End If
End Sub
Private Sub Quit()
'Once we are done with the main program, lets clean up the ROT
'by removing the entry for our ActiveX Server
If OLEInstance <> 0 Then
RevokeActiveObject OLEInstance, 0
End If
CoDisconnectObject Bod, 0
End Sub
Private Sub Terminate()
RevokeActiveObject OLEInstance, 0
End Sub
I am having trouble with controling how the instances of the process are managed when starting BO Designer (or Reporter same issue).
When using CreateObject or New in Visual Basic, it always creates a new instance of the Designer process that need to be closed at the end. If the user forget to close any current instance, another one is created and the API may not work very well (crash) in this case.
What I want to achieve is a reuse of any open application already running, or start a new one if none could be found.
I wrote a tiny VB program showing this but for some reason it doesn't work. I cannot reuse any application already started, using the GetObject and the Running Object Table (ROT).
This is a standard VB exe project with two buttons labelled "CreateObject" and "GetObject".
Do you have any idea why GetObject doesn't work?
Best Regards,
Olivier
-----------------------------------------------------------
Private Type GUIDs
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
'Declares needed to register object in the ROT
Private Const ACTIVEOBJECT_STRONG = 0
Private Const ACTIVEOBJECT_WEAK = 1
Private Declare Function CLSIDFromProgID Lib "ole32.dll" (ByVal ProgID As Long, rclsid As GUIDs) As Long
Private Declare Function CoDisconnectObject Lib "ole32.dll" (ByVal pUnk As IUnknown, pvReserved As Long) As Long
Private Declare Function RegisterActiveObject Lib "oleaut32.dll" (ByVal pUnk As IUnknown, rclsid As GUIDs, ByVal dwFlags As Long, pdwRegister As Long) As Long
Private Declare Function RevokeActiveObject Lib "oleaut32.dll" (ByVal dwRegister As Long, ByVal pvReserved As Long) As Long
Dim OLEInstance As Long
'The BO Designer application object
Const DESIGNER_NAME = "Designer.Application"
Dim Bod As Designer.Application
Private Sub CreateObjectButton_Click()
Set Bod = CreateObject(DESIGNER_NAME)
Bod.Visible = True
Bod.Window.State = dsMinimized
Call InitRot
MsgBox Bod.Version
End Sub
Private Sub GetObjectButton_Click()
Set Bod = GetObject(, DESIGNER_NAME)
Bod.Visible = True
Bod.Window.State = dsMinimized
MsgBox Bod.Version
Call Quit
End Sub
Private Sub InitRot()
'The magic happens here
'This code is responsible for creating the entry for ROT (Running Object Table)
Dim mGUID As GUIDs
Dim lp As Long
OLEInstance = 0
lp = CLSIDFromProgID(StrPtr(DESIGNER_NAME), mGUID)
If lp = 0 Then
lp = RegisterActiveObject(Bod, mGUID, ACTIVEOBJECT_WEAK, OLEInstance)
End If
End Sub
Private Sub Quit()
'Once we are done with the main program, lets clean up the ROT
'by removing the entry for our ActiveX Server
If OLEInstance <> 0 Then
RevokeActiveObject OLEInstance, 0
End If
CoDisconnectObject Bod, 0
End Sub
Private Sub Terminate()
RevokeActiveObject OLEInstance, 0
End Sub