Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem importing library .dll in .NET using COM INTEROP 1

Status
Not open for further replies.

rha2000

Programmer
Aug 6, 2012
14
AR
I want to import a library .NET in C#, I want to integrate a VFP9 application using COM interop objects, this library has an abstract class "class1". Try to do it like this:

x = NEWOBJECT ("myclass")

DEFINE CLASS myclass AS session OLEPUBLIC

_Class1 IMPLEMENTS IN "Libreria.Class1"

....

ENDDEFINE

Is it possible IMPLEMENTS of an abstract class?

I tried to inherit from the abstract class like this:

DEFINE CLASS myclass OF "Libreria.dll" AS Libreria.class1


ENDDEFINE

does not work.

The only problem I work with an abstract class, not a common class.

Any idea?

Thank you.
 
IN VFPO the IMPLEMENTS clause is there to implement INTERFACES, not classes or abstract classes.
The concept of abstract classes does not exist in VFP.
You can't subclass any OLEPUBLIC class in VFP.
What you can do is define a class OLEPUBLIC and define a child class inheriting that class the normal way you inherit from any VFP classes, and then you can make that child class OLEPUBLIC itself.

Eg
Code:
DEFINE CLASS myparentclass as Custom OLEPUBLIC
...
ENDDEFINE

DEFINE CLASS mychildclass as myparentclass OLEPUBLIC
...
ENDDEFINE

As both definitions are in the same file the clause "OF sourcefile" is not needed here. What's for sure is, you can't specify a DLL as source file, only prg or vcx.

The only other way to add VFP code to an olecontrol is to base a vfp class on olecontrol. If you do this in a vcx class, you interactively get asked what ole conotrol you want to use. VFP adds a kind of container object around that ole control, and you can write code to olecontrol events or add methods, but you can't change the canvas of the control, you can't add vfp base controls to it, for example, you can only extend that ole control on the functional level.

Also you can't create visual OLE controls in VFP, though you can set a form olepublic, that can only can be used compiled as EXE and the form would only run in the _screen. The only way to integrate it into a dotNET application would be as a top level form in desktop, but it will not be a child form of a dotnet main form.

The main capability of VFP is to create COM Server DLLs, single- or multithreaded, for functional aspects, eg data access.

Bye, Olaf.
 
By the way: To implement an inerface in vfp you better don't write the IMPLEMENTS line manually, because you need to write out all the events the interface has, even if you don't want to implement anything in most events. The footprint of the vfp class definition must match the interface fully.

To easily have that you use the VFP object browser, click on the open icon in the toolbar, in the COM libraries tab of the open dialog choose the COM library or Browse for a dll or ocx or tlb (typelib). Eg choose Web Browser. The tree of OLE typelib information will then show SHDocVw as the root, expand and you'll see classes to properties. expand interfaces.

Now you can drag an interface node into a prg, if you have no prg open, now create a new empty prg.

If doing that for the DWebBrowserEvents I get the following code:
Code:
DEFINE CLASS myclass AS session OLEPUBLIC

	IMPLEMENTS DWebBrowserEvents IN "c:\windows\syswow64\ieframe.dll"

	PROCEDURE DWebBrowserEvents_BeforeNavigate(URL AS STRING, Flags AS Number, TargetFrameName AS STRING, PostData AS VARIANT, Headers AS STRING, Cancel AS LOGICAL @) AS VOID;
 				HELPSTRING "Fired when a new hyperlink is being navigated to."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_NavigateComplete(URL AS STRING) AS VOID;
 				HELPSTRING "Fired when the document being navigated to becomes visible and enters the navigation stack."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_StatusTextChange(Text AS STRING) AS VOID;
 				HELPSTRING "Statusbar text changed."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_ProgressChange(Progress AS Number, ProgressMax AS Number) AS VOID;
 				HELPSTRING "Fired when download progress is updated."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_DownloadComplete() AS VOID;
 				HELPSTRING "Download of page complete."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_CommandStateChange(Command AS Number, Enable AS LOGICAL) AS VOID;
 				HELPSTRING "The enabled state of a command changed"
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_DownloadBegin() AS VOID;
 				HELPSTRING "Download of a page started."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_NewWindow(URL AS STRING, Flags AS Number, TargetFrameName AS STRING, PostData AS VARIANT, Headers AS STRING, Processed AS LOGICAL @) AS VOID;
 				HELPSTRING "Fired when a new window should be created."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_TitleChange(Text AS STRING) AS VOID;
 				HELPSTRING "Document title changed."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_FrameBeforeNavigate(URL AS STRING, Flags AS Number, TargetFrameName AS STRING, PostData AS VARIANT, Headers AS STRING, Cancel AS LOGICAL @) AS VOID;
 				HELPSTRING "Fired when a new hyperlink is being navigated to in a frame."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_FrameNavigateComplete(URL AS STRING) AS VOID;
 				HELPSTRING "Fired when a new hyperlink is being navigated to in a frame."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_FrameNewWindow(URL AS STRING, Flags AS Number, TargetFrameName AS STRING, PostData AS VARIANT, Headers AS STRING, Processed AS LOGICAL @) AS VOID;
 				HELPSTRING "Fired when a new window should be created."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_Quit(Cancel AS LOGICAL @) AS VOID;
 				HELPSTRING "Fired when application is quiting."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_WindowMove() AS VOID;
 				HELPSTRING "Fired when window has been moved."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_WindowResize() AS VOID;
 				HELPSTRING "Fired when window has been sized."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_WindowActivate() AS VOID;
 				HELPSTRING "Fired when window has been activated."
	* add user code here
	ENDPROC

	PROCEDURE DWebBrowserEvents_PropertyChange(Property AS STRING) AS VOID;
 				HELPSTRING "Fired when the PutProperty method has been called."
	* add user code here
	ENDPROC

ENDDEFINE

Now you can add VFP code there. And to use this, you have to have a Webbrowser control running, have to instanciate the VFP eventhandler class and have to combine them via the EVENTHANDLER() function, in which you pass in both the Webbrowser object and the VFP object.

The eventhandler class implementing an interface is only usable this way inside VFP, eg to react to webbrowser events inside VFP.

You don't have any benefit from all this inside dotNET again, as you can't apply the EVENTHANDLER() function there.

I wonder if any language could take in any OLE class and extend it. as an ole class can be programmed in any language, how would that finally end? Each language needs it's own runtime and therefore also it's own initialisation stub inside a DLL o OCX starting not only the OLE class, but also the language runtime.

Bye, Olaf.
 
Hi Olaf

I will exemplify the problem:

I have one the library made ​​in C#, and I want to import it into VFP9 (using COM INTEROP).
The library "Library1.dll" has two classes, "ClassA" and "ClassC". The class "ClassA" is abstract and I have to redefine the method "Process"; and the class "ClassC" is a common class.

I used the option to drag and drop and get the following:

For class "ClassC":

DEFINE CLASS myclassC AS session OLEPUBLIC
IMPLEMENTS _ClassC IN "Library1.ClassC"
....
ENDDEFINE

objC=NEWOBJECT("myclassC")

With the class "ClassC" everything works fine.
--------------------------------------------------

Now with the class "ClassA":

DEFINE CLASS myclassA AS session OLEPUBLIC
IMPLEMENTS _ClassA IN "Library1.ClassA"
....
ENDDEFINE

objA=NEWOBJECT("myclassA")

But with the class "ClassA" I get the following Program Error: "Type Library Library1.ClassA not found ".

"ClassA" is defined as Abstract in C#, so I think it could be that the problem.
--------------------------------------------------

I have also tried inheriting from class "ClassA" in this way:

DEFINE CLASS mychildclass AS Library1.ClassA OLEPUBLIC
PROCEDURE Process() AS VOID
....
ENDPROC
ENDDEFINE

x=NEWOBJECT("mychildclass")

but I get the following error: "Class MYCHILDCLASS definition is not found." This gives me error even with the class "ClassC", so I think that it is the correct way to inherit.

--------------------------------------------------
Note: Do not discard that there may be an error in the export from C#, but at least let me know what would be the correct way to import an abstract class.

My question is:
- I can import from C# abstract class in VFP?
- Or is it better that I exported from C# a common class and an event to intercept from VFP? Could that be the solution?

regards
 
>"ClassA" is defined as Abstract in C#, so I think it could be that the problem.
Yes, the definitioon of an abstract class is you can't instanciate it, it can only be used as a template.

Also you still haven't understood the concept of VFP implementing an interface. It's not inheriting the interface, you merely can write an eventhandler in VFP, which then can be bound to an instance of the OLE class to be triggered by it's events. No more and no less. Your "myclassC" is not inheriting "Library1.ClassC", it's just an eventhandler, which only makes sense side by side to an instance of the ClassC to react to ClassC events.

I already told you there is no option in VFP to inherit from a DLL, you can only inherit from a PRG or a VCX or a VFP base class. The syntax "DEFINE CLASS mychildclass AS Library1.ClassA OLEPUBLIC" is not possible.

Bye, Olaf.
 
The answers I have been very useful.

thanks
 
To add to the concept of inheriting an OCX or COM class.
Even in C# this is only possible in limited ways as this shows:
OLE itself has no official concept of inheritance.

What's always possible of course is, you take an activeX control on your form and add to it aside of it. Or you make use of a COM Server and automate it, but no matter how you do it, you don't inherit it, you just instanciate and use it.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top