- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need help with the COMCREATEOBJECT
In the Autidice example the call to the excel object is the following :
CALL COMCREATEOBJECT ("Excel.Application.8", excelapp, status)
How do I know what name to put into the COMCREATEOBJECT call if it is something else than excel
CALL COMCREATEOBJECT ("?????????????", excelapp, status)
In the Autidice example the call to the excel object is the following :
CALL COMCREATEOBJECT ("Excel.Application.8", excelapp, status)
How do I know what name to put into the COMCREATEOBJECT call if it is something else than excel
CALL COMCREATEOBJECT ("?????????????", excelapp, status)
Link Copied
22 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have to know the COM interface of the application you're interested in. There's no universal answer to this question.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks
But this is my problem.
The Application is called RSTAB. There is also a Type library called RSTAB.tlb
In my code I wrote
CALL COMCREATEOBJECT ("RSTAB", app, status)
but this does not work.
How do I find out the COM interface ???
Somehow I am really stuck
But this is my problem.
The Application is called RSTAB. There is also a Type library called RSTAB.tlb
In my code I wrote
CALL COMCREATEOBJECT ("RSTAB", app, status)
but this does not work.
How do I find out the COM interface ???
Somehow I am really stuck
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
COMCREATEOBJECT is similar to CreateObject in VB and takes the same argument.
Provided your COM object is registered, the object name can be found in the registry under HKCRCLSIDProgID
It is likely to be something similar to "RSTAB.Whatever", so searching fro "RSTAB." in regedit would be a good start.
The CLSID you need is found under HKCRRSTAB.WhateverCLSID (not that this helps :)!!! )
Dan
Provided your COM object is registered, the object name can be found in the registry under HKCRCLSID
It is likely to be something similar to "RSTAB.Whatever", so searching fro "RSTAB." in regedit would be a good start.
The CLSID you need is found under HKCRRSTAB.WhateverCLSID (not that this helps :)!!! )
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alternatively, you can open the type library the the OLE/COM viewer that comes with DevStudio and look to see what the dispinterface(s) is(are) called.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Judd
thanks for your help
In the registry I can find "RSTAB.Position" and "RSTAB.Application"
So when I call
CALL COMCREATEOBJECT ("RSTAB.Position", app, status)
the integer variable app should have a number other than 0.
Is this correct ?
When I open the OLE/COM Viewer I can find the type library RSTAB.tlb.
What do you mean by dispinterface ?
Please also see my posting from yesterday.
many thanks
Klaus
thanks for your help
In the registry I can find "RSTAB.Position" and "RSTAB.Application"
So when I call
CALL COMCREATEOBJECT ("RSTAB.Position", app, status)
the integer variable app should have a number other than 0.
Is this correct ?
When I open the OLE/COM Viewer I can find the type library RSTAB.tlb.
What do you mean by dispinterface ?
Please also see my posting from yesterday.
many thanks
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
The dispinterfaces are the 'dispatch interfaces', the bits of the COM object you can 'see' (methods, properties and events).
From what you've found I suspect your main interface is called 'Application' and is probably the one you want to use (I could be wrong though!).
So COMCREATEOBJECT ("RSTAB.Application", app, status) (or your own code) should give app .NE. 0
(you could use COMCreateObjectByProgID from DFCOM too? is that what you are using?)
Either way, I think app should contain the address of the interface (essentially, the COM object).
If you are doing this from FORTRAN remember that you must call COMInitialize before you start with any other COM related calls.
Dan
The dispinterfaces are the 'dispatch interfaces', the bits of the COM object you can 'see' (methods, properties and events).
From what you've found I suspect your main interface is called 'Application' and is probably the one you want to use (I could be wrong though!).
So COMCREATEOBJECT ("RSTAB.Application", app, status) (or your own code) should give app .NE. 0
(you could use COMCreateObjectByProgID from DFCOM too? is that what you are using?)
Either way, I think app should contain the address of the interface (essentially, the COM object).
If you are doing this from FORTRAN remember that you must call COMInitialize before you start with any other COM related calls.
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Judd
thanks a lot for your help
I think I am one step further now.
I coded :
CALL COMINITIALIZE(status)
CALL COMCREATEOBJECT ("RSTAB.Position", app, status)
The call to COMCREATEOBJECT (...) opens the RSTAB Program and closes it again thus app = 0.
So this code is okay I guess.
But the program RSTAB is already running so I do not have to Create it.
Somehow I have to connect it to my Program.
I think I need something like COMGETOBJECT(...)
The VB code is as follows
----------------------------------------------
Dim RSApp As RSTAB.IrsApplication
Dim RSPos As RSTAB.Position
Dim RSTop As RSTAB.IrsTopology
Private Sub CommandButton1_Click()
Set RSPos = GetObject(, "RSTAB.Position") <============ ?????
Set RSApp = RSPos.rsGetApplication
RSApp.rsLockLicence
Set RSTop = RSPos.rsGetTopology
.
.
----------------------------------------------
Do you have another good tip for me ?
Klaus
thanks a lot for your help
I think I am one step further now.
I coded :
CALL COMINITIALIZE(status)
CALL COMCREATEOBJECT ("RSTAB.Position", app, status)
The call to COMCREATEOBJECT (...) opens the RSTAB Program and closes it again thus app = 0.
So this code is okay I guess.
But the program RSTAB is already running so I do not have to Create it.
Somehow I have to connect it to my Program.
I think I need something like COMGETOBJECT(...)
The VB code is as follows
----------------------------------------------
Dim RSApp As RSTAB.IrsApplication
Dim RSPos As RSTAB.Position
Dim RSTop As RSTAB.IrsTopology
Private Sub CommandButton1_Click()
Set RSPos = GetObject(, "RSTAB.Position") <============ ?????
Set RSApp = RSPos.rsGetApplication
RSApp.rsLockLicence
Set RSTop = RSPos.rsGetTopology
.
.
----------------------------------------------
Do you have another good tip for me ?
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
The call you need is:
COMGetActiveObjectByProgID (FORTRAN) or
COMGETACTIVEOBJECT (Win32 USEing DFCOM)
(I suspect you have the USE DFCOM statement in there
somewhere!).
COMGETACTIVEOBJECT has the same arguments as
COMCREATEOBJECT, that is prog_id, idispatch, status.
But you seem to have the right idea, when I've had
to do COM in FORTRAN I've always done it in VB first.
COM in FORTRAN is a little cumbersome sometimes,
but it is possible :)
HTH
Dan
The call you need is:
COMGetActiveObjectByProgID (FORTRAN) or
COMGETACTIVEOBJECT (Win32 USEing DFCOM)
(I suspect you have the USE DFCOM statement in there
somewhere!).
COMGETACTIVEOBJECT has the same arguments as
COMCREATEOBJECT, that is prog_id, idispatch, status.
But you seem to have the right idea, when I've had
to do COM in FORTRAN I've always done it in VB first.
COM in FORTRAN is a little cumbersome sometimes,
but it is possible :)
HTH
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
Another tip...COM calls generally return a HRESULT (hr), where hr == 0 means everything is OK.
Here is a useful function:
Call it with an error message of your own choosing everytime you get a HRESULT. It will give you a message box telling you exactly what went wrong and where. E.G.
Another tip...COM calls generally return a HRESULT (hr), where hr == 0 means everything is OK.
Here is a useful function:
*------------------------------------------------------------------------------ LOGICAL*4 FUNCTION CheckhRes(hRes, errorMsg) *------------------------------------------------------------------------------ USE dfcom USE user32 IMPLICIT NONE INTEGER(4) hRes CHARACTER (LEN = *) :: errorMsg INTEGER(4) ret CHARACTER (LEN = 512) :: Msg IF (hRes >= 0) THEN CheckhRes = .TRUE. RETURN END IF WRITE (Msg, '(A, "; OLE error hRes = 0x", Z8.8, "; Aborting")') TRIM(errorMsg), hRes ret = MessageBox(NULL, TRIM(Msg)//""c, "Error", MB_ICONSTOP) CheckhRes = .FALSE. RETURN END
Call it with an error message of your own choosing everytime you get a HRESULT. It will give you a message box telling you exactly what went wrong and where. E.G.
* -------------- * Initialise COM * -------------- CALL COMInitialize (hRes) bRet = CheckhRes(hRes, "Unable to initialise COM")
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dan
thanks again
My code is now :
------------------------------------
use RSTABCOM
use DFCOM
implicit none
integer*4 :: hRes, bRet, app
CALL COMINITIALIZE(hRes)
bRet = CheckhRes(hRes, "Unable to initialise COM")
CALL COMGetActiveObject ("RSTAB.Position", app, hRes)
bRet = CheckhRes(hRes, "Unable to RSTAB.Position")
stop
end
--------------------------------
where RSTABCOM is the module which I converted from the RSTAB.tlb using the Module Wizard
I belive, this should work from the point of Fortran code.
But it doesn't:
The CALL COMGetActiveObject(..) still return app = 0 and hRes < 0.
Does the error number which I get from your CheckhRes function tell me something ??
Maybe the problem is not on my side, maybe is is on the RSTAB side (the application I want to connect to).
You said something about viewing dispinterfaces using the COM Viewer.
When I do that I can find the RSTAB Type library.
When I open this library I can find lots of interfaces, but the branch of the dispinterfaces is empty.
Does this mean something ?
Also I am still not sure what kind of names I can put into the COMGetActiveObject( "???????",app,hRes) call.
Does the COM Viewer tell me this names od objects ??
Sorry for keeping you busy. I am programming Fortran for more than 15 years, but this COM World is new for me.
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is RSTAB? A DLL? An OCX? It looks like RS stands for record set? Is this some kind of licensed (DB) server?
Theroretically, if you can get the code working in VB it is just a matter of replicating it in FORTRAN, though as you've discovered, this is easier said than done.
DevStudio comes with an application called Error Lookup (look on your start menu) that you can use to interpret the error code you are getting back from COMGetActiveObject. This should give you a n idea what is failing...
FORTRAN is not an easy language where COM is concerned, it may be easier to use VB for COM and have a FORTRAN DLL for your calculations.
Nothing looks wrong with your code, though you do need CALL COMUninitialize( ) at the end, I'm assuming you building your application against the RSTAB.lib file.
"Also I am still not sure what kind of names I can put into the COMGetActiveObject( "???????",app,hRes) call.
Does the COM Viewer tell me this names od objects ??"
?????? Can be the ProgID of any COM object e.g. "RSTAB.Position", "RSTAB.IrsApplication", "RSTAB.IrsTopology".
From your VB sample, it looks like
"IrsApplication", "Position" and "IrsTopology" are your objects/interfaces.
The VB assumes that an RSTAB.Position object is already present. You can use VB IDE to view the objects/methods available in the RSTAB library (press F2 and select RSTAB in the libraries combo box, which displays by default). It is easier to understand than the OLE viewer. Your 'objects' are shown on the left, their methods, properties and events on the right.
Theroretically, if you can get the code working in VB it is just a matter of replicating it in FORTRAN, though as you've discovered, this is easier said than done.
DevStudio comes with an application called Error Lookup (look on your start menu) that you can use to interpret the error code you are getting back from COMGetActiveObject. This should give you a n idea what is failing...
FORTRAN is not an easy language where COM is concerned, it may be easier to use VB for COM and have a FORTRAN DLL for your calculations.
Nothing looks wrong with your code, though you do need CALL COMUninitialize( ) at the end, I'm assuming you building your application against the RSTAB.lib file.
"Also I am still not sure what kind of names I can put into the COMGetActiveObject( "???????",app,hRes) call.
Does the COM Viewer tell me this names od objects ??"
?????? Can be the ProgID of any COM object e.g. "RSTAB.Position", "RSTAB.IrsApplication", "RSTAB.IrsTopology".
From your VB sample, it looks like
"IrsApplication", "Position" and "IrsTopology" are your objects/interfaces.
The VB assumes that an RSTAB.Position object is already present. You can use VB IDE to view the objects/methods available in the RSTAB library (press F2 and select RSTAB in the libraries combo box, which displays
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just to explain.
RSTAB is the name of a commercial program for static calculations.
I have the program installed and I have a type library called RSTAB.tlb.
I wrote lots of additional applications ( e.g. load generations, design of connections etc.) using Fortran which we use everyday in the office.
The data transfer between the RSTAB and my programs are done simply by ASCII files. In RSTAB I write e.g. the results of the calculation to a ASCII file and then I read this ASCII file by my own program.
Now the programmers of RSTAB did the possibility to use a COM Interface. As a example they gave me VB code from Excel macros. And it works fine with Excel VB.
Since all my code is in fortran I want to stay with fortran (also for some reasons I do not like VB it is to complicated).
As you said actually I just have to translate the VB code to fortran. And I think it is only a couple of lines which I have to add to my code.
But things are not so easy as it looks. As you see, the fortran code looks okay, but it does not work. Since I am new to COM I am not sure where to look for errors. Reading the manual does not help too much. The manuals are not good for learning a new method. I usually need some examples to understand.
When I enter the error number into the Error Lookup the message is " Interface not supported" .
I slowly belive, that the error is on the side of RSTAB and not on mine, also it works with VB.
Thanks again for your help and tips
Klaus
RSTAB is the name of a commercial program for static calculations.
I have the program installed and I have a type library called RSTAB.tlb.
I wrote lots of additional applications ( e.g. load generations, design of connections etc.) using Fortran which we use everyday in the office.
The data transfer between the RSTAB and my programs are done simply by ASCII files. In RSTAB I write e.g. the results of the calculation to a ASCII file and then I read this ASCII file by my own program.
Now the programmers of RSTAB did the possibility to use a COM Interface. As a example they gave me VB code from Excel macros. And it works fine with Excel VB.
Since all my code is in fortran I want to stay with fortran (also for some reasons I do not like VB it is to complicated).
As you said actually I just have to translate the VB code to fortran. And I think it is only a couple of lines which I have to add to my code.
But things are not so easy as it looks. As you see, the fortran code looks okay, but it does not work. Since I am new to COM I am not sure where to look for errors. Reading the manual does not help too much. The manuals are not good for learning a new method. I usually need some examples to understand.
When I enter the error number into the Error Lookup the message is " Interface not supported" .
I slowly belive, that the error is on the side of RSTAB and not on mine, also it works with VB.
Thanks again for your help and tips
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
I looked into some problems I once had with COM in FORTRAN, and it appears that there may be problems, which may be due to the COM implementation within CVF, when using methods of the interface which themselves return an
interface pointer.
(Methods on an object that return pointers to another object).
I had a lot of difficulty trying to determine if I had a pointer to the correct interface.
This seems to be what you are attempting (getting the Application object pointer from the Position object), however, this does not explain why your create object code does not work.
If possible, I'd revert to trying to create a new object rather than connecting to a n existing one, if possible. At least then you can see if the RSTAB application starts to run in the TAsk Manager at the correct time.
I'll have another think and try to come up with something.
Dan
I looked into some problems I once had with COM in FORTRAN, and it appears that there may be problems, which may be due to the COM implementation within CVF, when using methods of the interface which themselves return an
interface pointer.
(Methods on an object that return pointers to another object).
I had a lot of difficulty trying to determine if I had a pointer to the correct interface.
This seems to be what you are attempting (getting the Application object pointer from the Position object), however, this does not explain why your create object code does not work.
If possible, I'd revert to trying to create a new object rather than connecting to a n existing one, if possible. At least then you can see if the RSTAB application starts to run in the TAsk Manager at the correct time.
I'll have another think and try to come up with something.
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dan
thanks for the time you are spending on my problem.
The RSTAB application is running. Also the COM Object is not made by me so I cannot change it. It belongs to the RSTAB Program. All I want is to get information from RSTAB to my program.
It is basically the same, as if I want to get data out of an running Excel Application.
I'am in contact with the programers of RSTAB, but they do not know Fortran too much. The Rstab needs a lizenz to run. I do have this lizenz but maybe this is why the object get blocked to my call. In the VB code there is a call to check the lizenz ( RSApp.rsLockLicence ).
This call is after the call to getobject.
I dont't know.
I think I take a break and start all over again in some days.
Klaus
thanks for the time you are spending on my problem.
The RSTAB application is running. Also the COM Object is not made by me so I cannot change it. It belongs to the RSTAB Program. All I want is to get information from RSTAB to my program.
It is basically the same, as if I want to get data out of an running Excel Application.
I'am in contact with the programers of RSTAB, but they do not know Fortran too much. The Rstab needs a lizenz to run. I do have this lizenz but maybe this is why the object get blocked to my call. In the VB code there is a call to check the lizenz ( RSApp.rsLockLicence ).
This call is after the call to getobject.
I dont't know.
I think I take a break and start all over again in some days.
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dan
I contacted the developers of the RSTAB program to give me help on the COM Interface.
Here is their answers.
If you have time, I would like your comment on that :
************************************************
Dear Mr. Knebel,
I am software developer in the Dlubal's company and programmer of the COM interface. Mr. Rustler asked me to help you with RSTAB COM interface access from Fortran language. As the COM technology is declared a universal tool for comunnication between programming languages we have only tested Visual Basic and C++ to use our COM interface. What concerns Fortran I have done some research and found following article http://h18009.www1.hp.com/fortran/docs/vf-html/pg/pg13ptoi.htm.
To understand terms in the article I have to mention in brief some terms from the COM theory:
There is a special species of COM objects called automation objects. The automation objects support only one interface called dispatch interface and signed IDispatch (I would call it alse universal interface). This interface enables so called late binding which means that object methods can be tested at run time. Automation objects are called also scriptable objects. Script interprets can access at run time only dispatch interfaces thanks of their late binding capability.
In general COM objects can support arbitrary interfaces (including IDispatch) derived from IUnknown. To access general COM interfaces requires so called early binding which means that the interfaces are converted into client programming language binary images at compile time.
Fortran functions COMCreateObjectByProgID/COMGetActiveObjectByProgID deliver dipatch interface of the required object.
RSTAB does not support the IDispatch interface because it is due to its universality alse rather limiting. To use general interfaces implemented in RSTAB COM interface following functions are available in Fortran:
COMCreateObjectByGUID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmcrog.htm)
COMGetActiveObjectByGUID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmgtog.htm)
Parameter class ID clsid of type GUID can be obtained with the function COMCLSIDFromProgID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmsidp.htm). The class ID is unique external name of a COM object.
Parameter interface ID iid of type GUID is generated from the type library RSTAB.tlb by the Module Wizard in the form IID_'interface-name'.
So your code should be modified in the following way:
...
use DFWINTY
...
integer*4 :: status,pos,app,hres,bret,CheckhRes
GUID clsid
CALL COMINITIALIZE(hRes)
CALL COMCLSIDFromProgID ("RSTAB.Position", clsid, status)
CALL COMGetActiveObjectByGUID (clsid, IID_IrsPosition, pos, hres) ! Objekt : RSTAB.Position
write(*,*) pos
bRet = CheckhRes(hRes, "Unable to get RSTAB.Position")
CALL COMCLSIDFromProgID ("RSTAB.Application", clsid, status)
CALL COMGetActiveObjectByGUID (clsid, IID_IrsApplication, app, hres) ! Objekt : RSTAB.Application
write(*,*) app
bRet = CheckhRes(hRes, "Unable to get RSTAB.Application")
CALL COMUninitialize( )
...
I have no possibility to test the Fortran code so I can not guarantee that it will function immediately. If there is some problem to obtain RSTAB interface pointer let me know.
If you succee d to obtain the interface you can call interface methods which prototypes are generated by the Module Wizard from RSTAB.tlb file. Very important methods are those that return other interfaces which you can use to call again their methods etc.
Important:
When you finish to use COM interface you should call COMReleaseObject function. Which will in case of using CreateObject finish the hidden RSTAB.exe process.
****************************************************
Thanks
Klaus
I contacted the developers of the RSTAB program to give me help on the COM Interface.
Here is their answers.
If you have time, I would like your comment on that :
************************************************
Dear Mr. Knebel,
I am software developer in the Dlubal's company and programmer of the COM interface. Mr. Rustler asked me to help you with RSTAB COM interface access from Fortran language. As the COM technology is declared a universal tool for comunnication between programming languages we have only tested Visual Basic and C++ to use our COM interface. What concerns Fortran I have done some research and found following article http://h18009.www1.hp.com/fortran/docs/vf-html/pg/pg13ptoi.htm.
To understand terms in the article I have to mention in brief some terms from the COM theory:
There is a special species of COM objects called automation objects. The automation objects support only one interface called dispatch interface and signed IDispatch (I would call it alse universal interface). This interface enables so called late binding which means that object methods can be tested at run time. Automation objects are called also scriptable objects. Script interprets can access at run time only dispatch interfaces thanks of their late binding capability.
In general COM objects can support arbitrary interfaces (including IDispatch) derived from IUnknown. To access general COM interfaces requires so called early binding which means that the interfaces are converted into client programming language binary images at compile time.
Fortran functions COMCreateObjectByProgID/COMGetActiveObjectByProgID deliver dipatch interface of the required object.
RSTAB does not support the IDispatch interface because it is due to its universality alse rather limiting. To use general interfaces implemented in RSTAB COM interface following functions are available in Fortran:
COMCreateObjectByGUID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmcrog.htm)
COMGetActiveObjectByGUID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmgtog.htm)
Parameter class ID clsid of type GUID can be obtained with the function COMCLSIDFromProgID (see http://h18009.www1.hp.com/fortran/docs/vf-html/azsumm/rfcmsidp.htm). The class ID is unique external name of a COM object.
Parameter interface ID iid of type GUID is generated from the type library RSTAB.tlb by the Module Wizard in the form IID_'interface-name'.
So your code should be modified in the following way:
...
use DFWINTY
...
integer*4 :: status,pos,app,hres,bret,CheckhRes
GUID clsid
CALL COMINITIALIZE(hRes)
CALL COMCLSIDFromProgID ("RSTAB.Position", clsid, status)
CALL COMGetActiveObjectByGUID (clsid, IID_IrsPosition, pos, hres) ! Objekt : RSTAB.Position
write(*,*) pos
bRet = CheckhRes(hRes, "Unable to get RSTAB.Position")
CALL COMCLSIDFromProgID ("RSTAB.Application", clsid, status)
CALL COMGetActiveObjectByGUID (clsid, IID_IrsApplication, app, hres) ! Objekt : RSTAB.Application
write(*,*) app
bRet = CheckhRes(hRes, "Unable to get RSTAB.Application")
CALL COMUninitialize( )
...
I have no possibility to test the Fortran code so I can not guarantee that it will function immediately. If there is some problem to obtain RSTAB interface pointer let me know.
If you succee d to obtain the interface you can call interface methods which prototypes are generated by the Module Wizard from RSTAB.tlb file. Very important methods are those that return other interfaces which you can use to call again their methods etc.
Important:
When you finish to use COM interface you should call COMReleaseObject function. Which will in case of using CreateObject finish the hidden RSTAB.exe process.
****************************************************
Thanks
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
I read back a few posts and found you did actually tell me this - you said that RSTAB didn't have any dispatch interfaces when looked at though OLE view - I should have noticed!
It is fairly unusual in my experience to find a COM object without a dispatch interface - but since RSTAB doesn't, the code given should work fine.
Again though I might suggest that using COMCreateObjectByGUID would be preferrable to using COMGetActiveObjectByGUID, unless there is a pressing reason why RSTAB should be already running, or why you need to use the running object rather than create a new one (usually, a programme that needs a COM object will create one, use it and then destroy it, if you attach to an active object be careful about destroying it if something else needs to use it).
At the very least create your own object will given you more control - you should be able to watch a new RStab.exe process begin in Task Manager after you call the create routine, and see it end when you release the object.
Let me know how you get on.
Dan
I read back a few posts and found you did actually tell me this - you said that RSTAB didn't have any dispatch interfaces when looked at though OLE view - I should have noticed!
It is fairly unusual in my experience to find a COM object without a dispatch interface - but since RSTAB doesn't, the code given should work fine.
Again though I might suggest that using COMCreateObjectByGUID would be preferrable to using COMGetActiveObjectByGUID, unless there is a pressing reason why RSTAB should be already running, or why you need to use the running object rather than create a new one (usually, a programme that needs a COM object will create one, use it and then destroy it, if you attach to an active object be careful about destroying it if something else needs to use it).
At the very least create your own object will given you more control - you should be able to watch a new RStab.exe process begin in Task Manager after you call the create routine, and see it end when you release the object.
Let me know how you get on.
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dan
I think the ice is broken.
I just made a fast try and it looks good.
I will spend the weekend to work on it.
I do not understand your comment about create an object, use it and destroy it. Maybe I missunderstand what an OBJECT is.
RSTAB is an Window EXE Program (say like AUTOCAD). I use RSTAB to make calculations. Now I want that my own exe program gets the results of RSTAB by a COM interface rather than using a ASCII file. RSTAB has to be active (running). What does it help me to create an own object ?
Sorry for my stupidness
Klaus
I think the ice is broken.
I just made a fast try and it looks good.
I will spend the weekend to work on it.
I do not understand your comment about create an object, use it and destroy it. Maybe I missunderstand what an OBJECT is.
RSTAB is an Window EXE Program (say like AUTOCAD). I use RSTAB to make calculations. Now I want that my own exe program gets the results of RSTAB by a COM interface rather than using a ASCII file. RSTAB has to be active (running). What does it help me to create an own object ?
Sorry for my stupidness
Klaus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Klaus,
No need to apologise - there is no reason why you would know this if you've never done it before! RSTAB.exe is an exe, but it is also a COM object. You do not need to have RSTAB running before you start. If you use COMCreateObjectByGUID and that call succeeds, RSTAB will (should!) start running automatically (which you can see in task manager), when you call COMReleaseOBject, RSTAB will stop running.
If the COM interface to RSTAB is well designed you should be able to control it from FORTRAN - loading data, setting up problem, running calculations and retrieving results.
It sounds very much like our situation: we have a FORTAN calculation engine that is an EXE and a COM object. We have another EXE that is a GUI for the engine. The GUI.EXE does a CreateObject("Engine.Application") which starts an Engine.exe for it to use. If we start another GUI.EXE, it creates another Engine.exe object and starts running it.
Similarly I can use VB or VBA to create the same object and get another Engine.exe to work with in VB. In our case the GUI hides all the calls to the Engine - in the GUI I double click a database icon to load it, but if I was in VB I could call the method LoadMasterDatabase and pass the name of the database file to achieve the same results.
This is called OLE Automation - you are using OLE (COM) to automate the use of another programme (RSTAB).
If I guess at what you are trying to do you might have a better understanding:
1) You manually start RSTAB.
2) You configure a problem (load an input data file?).
3) You use RSTAB to solve the problem (click the 'solve' button?)
4) You then are trying to connect to RSTAB with FORTRAN to get the results and process them.
With OLE Automation you should be able to (from FORTRAN):
1) Create the RSTAB object (i.e. start RSTAB.exe)
2) Configure the problem (e.g. tell RSTAB to load the
input data file)
3) Tell RSTAB to solve the problem.
4) Get the results you are after.
I hope this helps,
Dan
No need to apologise - there is no reason why you would know this if you've never done it before! RSTAB.exe is an exe, but it is also a COM object. You do not need to have RSTAB running before you start. If you use COMCreateObjectByGUID and that call succeeds, RSTAB will (should!) start running automatically (which you can see in task manager), when you call COMReleaseOBject, RSTAB will stop running.
If the COM interface to RSTAB is well designed you should be able to control it from FORTRAN - loading data, setting up problem, running calculations and retrieving results.
It sounds very much like our situation: we have a FORTAN calculation engine that is an EXE and a COM object. We have another EXE that is a GUI for the engine. The GUI.EXE does a CreateObject("Engine.Application") which starts an Engine.exe for it to use. If we start another GUI.EXE, it creates another Engine.exe object and starts running it.
Similarly I can use VB or VBA to create the same object and get another Engine.exe to work with in VB. In our case the GUI hides all the calls to the Engine - in the GUI I double click a database icon to load it, but if I was in VB I could call the method LoadMasterDatabase and pass the name of the database file to achieve the same results.
This is called OLE Automation - you are using OLE (COM) to automate the use of another programme (RSTAB).
If I guess at what you are trying to do you might have a better understanding:
1) You manually start RSTAB.
2) You configure a problem (load an input data file?).
3) You use RSTAB to solve the problem (click the 'solve' button?)
4) You then are trying to connect to RSTAB with FORTRAN to get the results and process them.
With OLE Automation you should be able to (from FORTRAN):
1) Create the RSTAB object (i.e. start RSTAB.exe)
2) Configure the problem (e.g. tell RSTAB to load the
input data file)
3) Tell RSTAB to solve the problem.
4) Get the results you are after.
I hope this helps,
Dan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've never used COM before. It sounds to me like using COM is similar to calling exported subprograms from a DLL. What's the difference between using COM and DLLs? Is there a significant advantage one way or another?
Mike
Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Mike,
I haven't made it very clear, but COM is technically not the same as OLE and DLLs are(semantically anyway) very different.
COM (Component Object Model) is a way of exposing things from the COM object (which may be a DLL, an EXE or an OCX) in a standardised way. You can expose only the methods, properties and events of the object that you want the user to be able to get at (its a MS specific standardised method of encapsulation) (FYI its non-platform specific equivalent is CORBA).
The advantage of COM objects over ordinary DLLs is the standardisation of the interfaces. This means that you don't need the LIB file for a COM object, it contains all its own prototype info (allowing things like the module wizard to automatically produce an interface file). Object models (theoretically) make it easy to figure out how to 'make an object work'. If you are familiar with COM you can generally explore the object model to figure out how something is done by trial and error (often the approach used when automating Excel for instance!;o) )
Events are another advantage - if you want event based programs, which are usually easier to code.
Straight DLLs are generally faster to call than their COM equivalents, especially if the object is late-bound. Usually the difference is not significant.
OLE (Object linking and embedding) is now more usually known as 'Automation'. This is the process whereby an object is 'automated' through code, generally enabled through COM.
Ease of reuse is another touted advantage of COM, but not every DLL, for instance, is a candidate for a COM object.
Sometimes a straight DLL is the best option...one of the big pains with VB for instance is that you can't create a straight DLL with it.
IfI refer again to our own case, a COM object engine is of benefit to us because we control the engine in a number of different ways - we have an Executive service that runs a number of engines on fixed cycles, a GUI that runs a single instance of the engine, and Excel add-in that runs the engine using automation from VBA. We've also been known to write custom VB or Excel interfaces to meet customer requirements. All this is very easy to do with a COM object.
You could do it by calls to a DLL too, but it wouldn't be as easy.
So swings and roundabouts really - as with most things.
Dan
I haven't made it very clear, but COM is technically not the same as OLE and DLLs are(semantically anyway) very different.
COM (Component Object Model) is a way of exposing things from the COM object (which may be a DLL, an EXE or an OCX) in a standardised way. You can expose only the methods, properties and events of the object that you want the user to be able to get at (its a MS specific standardised method of encapsulation) (FYI its non-platform specific equivalent is CORBA).
The advantage of COM objects over ordinary DLLs is the standardisation of the interfaces. This means that you don't need the LIB file for a COM object, it contains all its own prototype info (allowing things like the module wizard to automatically produce an interface file). Object models (theoretically) make it easy to figure out how to 'make an object work'. If you are familiar with COM you can generally explore the object model to figure out how something is done by trial and error (often the approach used when automating Excel for instance!;o) )
Events are another advantage - if you want event based programs, which are usually easier to code.
Straight DLLs are generally faster to call than their COM equivalents, especially if the object is late-bound. Usually the difference is not significant.
OLE (Object linking and embedding) is now more usually known as 'Automation'. This is the process whereby an object is 'automated' through code, generally enabled through COM.
Ease of reuse is another touted advantage of COM, but not every DLL, for instance, is a candidate for a COM object.
Sometimes a straight DLL is the best option...one of the big pains with VB for instance is that you can't create a straight DLL with it.
IfI refer again to our own case, a COM object engine is of benefit to us because we control the engine in a number of different ways - we have an Executive service that runs a number of engines on fixed cycles, a GUI that runs a single instance of the engine, and Excel add-in that runs the engine using automation from VBA. We've also been known to write custom VB or Excel interfaces to meet customer requirements. All this is very easy to do with a COM object.
You could do it by calls to a DLL too, but it wouldn't be as easy.
So swings and roundabouts really - as with most things.
Dan
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page