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 Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to access to classes in a DLL file 3

Status
Not open for further replies.

kenwall123

IS-IT--Management
Mar 28, 2012
13
US
Hi
for some reasons I have to program an application with foxpro 7.
I have a dll file which use com port to receive data from serial port.
it has class with the name "pack" which has two properties ("portOpen" and "portSettings")
and one event OnData. I can access to this dll in VB6 by adding this in project>reference.....
I don't know how I can use this and add this dll to my form in VFP7 and call the class and access to its properties and event.
PLz Help me ....plz
 
First of all, you need to know the class name. You mentioned "Pack", but it's unlikely that's the full name of the class. It's more likely to be something like "pack.application" or "someprogram.pack" or something in that form.

But let's assume for now the name is "Pack".

Once you know the name, use CREATEOBJECT() to instantiate it. For example:

loPack = CREATEOBJECT("pack")

loPack will now be a variable that holds an object reference to the class. So, to reference its properties and methods, you would refer to these as, for example, pack.PortOpen or pack.PortSettings. This applies for as long as the loPack variable remains in scope.

By the way, the DLL will also need to be registered on your computer and that of the user. I assume you know how to do that.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Having to add this DLL in VB into project>reference, this looks like a COM/OLE/ActiveX DLL.

You could try what Mike says, you could also try to simply add an oleobject class onto a form. This would then trigger a dialog listing all COM classes registered on the system. If you don't finde the pack class there, you'll have to register it via regsvr32,
and then it should appear.

Good Luck.

Bye, Olaf.
 
Thank you Mike
your instruction is helpful.as you said I should write loPack=CREATEOBJECT('OnlineWeightDLL.pack')
and what should I do with that event ("OnData")?

thank you again, that's very kind of you:)
 
You can only write code into the OnData event, if you create a class based on OnlineWeightDLL.pack, via

CREATE CLASS myPack Of myvcx.vcx As Olecontrol
Then choosing OnlineWeightDLL.pack

If OnlineWeightDLL.pack is not in that list, it's not an OCX but just a COM Server class.

Then what you can do is create an eventhandler class implementing the/an interface of the OnlineWeightDLL.pack with it's events.

open the object browser for that, click on the upper left toolbar icon to open a dialo for choosing COM libraries. In the "Com libraries" tab OnlineWeightDLL.pack might be listed, easier than browsing that list is to use the browse button and navigate to your DLL file.

Now in the main object browser window open the main node, it's interfaces subnote to find the Ipackevents interface (most probably, could also be named different).

Now create a new prg and drag the interface node into the program editor.

This will create code defining an event handler class:

Code:
DEFINE CLASS PackEventhandler AS session OLEPUBLIC
   IMPLEMENTS Ipackevents IN "pack.dll"

   PROCEDURE Ipackevents_OnData(parameters) AS ...;
             HELPSTRING "Fired when database arrives."
      * add user code here
   ENDPROC
..
ENDDEFINE

Here you can add your code for the OnData event. Don't delete any procedure just because you only want to add code to the ondata events. It's important all events are implemented, this is kind of a contract with much "fineprint", even if you only want to use the OnData event.

But sorry, we're not yet finished.

To put this together you need now to use CREATEOBJECT() two times, once as you already know, and once more for the eventhandler object:

Code:
loPack=CREATEOBJECT('OnlineWeightDLL.pack') 

SET PROCEDURE TO yournew.prg ADDITIVE
loPackEvents=CREATEOBJECT('PackEventhandler')

* finally bind the one to the other
Eventhandler(loPack,loPackEvents)

At the point of callin Eventhandler, the "contract" I mentioned above is made between the loPack object and the loPackEvents eventhandler and all the events of oPack are connected with the methods (procedures within the DEFINE CLASS prg) of the loPackEvents object.

More in general is to be found in the help chapter on DEFINE CLASS in the subtopic explaining the IMPLEMENTS clause. and the topics referenced in "See Also". If you want to know more and dive in deeper, here's that starting point:


It's complicated, as VFP itself can only implement events of COM classes. In VFP itsef you can't create events of classes, only methods. We live by the events we are given by the base classes.

Bye, Olaf.
 
Hi Olaf
thanks for your tutorial but it makes me confused!!
I attached 2 pics.the first one is what I see on object browser in VFP and the second is what I write in VB.
would you mind helping me solve this problem. step by step.
as you can see I have to set the settings for portsetting and portopen and after that I can start to read Ondata event.
that's very king of you again.

thank you

 
OK, you're at this step:

Now in the main object browser window open the main node, it's interfaces subnote to find the Ipackevents interface (most probably, could also be named different).

Now create a new prg and drag the interface node into the program editor.

So don't expand the classes node, but the interfaces node on the left side to see the interfaces. You need to drag an interface to VFP to implement an eventhandler class.

Bye, Olaf.
 
Oh Thank you....
finally I find out the solution....
what is the next step?
I think I should set the portsettings and portopen... that's it?
 
Reread please, I told you all the steps you need to do up to the point to get the Eventhandler running. It's up to you to program in the OnData event whatever you need.

To say the least: Yes you need to use the OCX the same way as in VB, you set Portsettings and set Portopen to .T. and then OnData happens.

Bye, Olaf.
 
You could also post the code, which was generated, as you dragged the interface node to an empty prg editor window.

Then we could see what's in the interface and would need to be done on that level.

Just because I asked you to reread, doesn't mean I'm not willing to guide you further, I just don't see the need to repeat something already said.

Bye, Olaf.
 
dear olaf
I copy-paste the code I have received by drag and drop .....
and the second is the code for event I think...
what should I write in order to set the settings and receive from event ?
I can read this event in VB6 with this code:
Code:
    Private Sub sample_onData(minus As Boolean, ByVal weight As Variant)
Label1.Caption = IIf(minus, -weight, weight)
End Sub


Code:
    x=NEWOBJECT("myclass")

DEFINE CLASS myclass AS session OLEPUBLIC

	IMPLEMENTS _Pack IN "OnlineWeightDLL.Pack"

	PROCEDURE _Pack_put_PortSettings(eValue AS STRING @);
 				HELPSTRING "Sets/returns the baud rate, parity, data bit and stop bit parameters. "
	* add user code here
	
	ENDPROC

	PROCEDURE _Pack_get_PortSettings() AS STRING;
 				HELPSTRING "Sets/returns the baud rate, parity, data bit and stop bit parameters. "
	* add user code here
	ENDPROC

	PROCEDURE _Pack_put_PortOpen(eValue AS LOGICAL @);
 				HELPSTRING "Sets/returns the state of the communications port (open or closed). "
	* add user code here
	ENDPROC

	PROCEDURE _Pack_get_PortOpen() AS LOGICAL;
 				HELPSTRING "Sets/returns the state of the communications port (open or closed). "
	* add user code here
	ENDPROC

ENDDEFINE
Code:
    x=NEWOBJECT("myclass")

DEFINE CLASS myclass AS session OLEPUBLIC

	IMPLEMENTS __Pack IN "c:\windows\system32\onlineweightdll.dll"

	PROCEDURE __Pack_OnData(Minus AS LOGICAL @, Weight AS VARIANT) AS VOID;
 				HELPSTRING "Occurs when data arrives to the Serial communications port"
	* add user code here
	ENDPROC

ENDDEFINE
 
To be able to bond to the OnData event you obviousyly need the second class implementing __Pack (not _Pack).

Your VB code needs to go in there.

The VB Code
Label1.Caption = IIf(minus, -weight, weight)
in VFP would be
Thisform.Label1.Caption = Transfrom(IIF(minus, -weight, weight))
Wouldn't it?

You know foxpro? You know lables? You know like in VB they have a Caption property? You know Foxpro labels only display text, not numerical types? Then you know you need STR(), or TRANSFORM() to transform the numeric value to text, don't you?

You know foxpro forms?
You know you address foxpro controls on Forms via Thisform.Controlname and not Controlname only?
Then you knwo you need to add Thisform.Label1.Caption instead of Label1 Caption, don't you?

But since the Eventhandler is a seperate class and not a form, you will not be able to directly set some label caption, neither without nor with THISFORM, as THISFORM is onyl valid within form code. So instead you should store the received weight into a property of the Eventhandler class.

What you can also do is define another property you can set to a control object reference to display the weight, then the Eventhandler class can set that controls Value property to the weight, additional to setting it's own but invisible) weight property.

Code:
* store this in packevents.prg

DEFINE CLASS PackEventhandler AS session OLEPUBLIC
    Weight = .NULL. && internal property storing the last weight received in __Pack_Ondata, inited to .NULL. for no data received
    DisplayControl = .NULL. && property for a control object reference to use for output/display of the weight

    IMPLEMENTS __Pack IN "c:\windows\system32\onlineweightdll.dll"

    PROCEDURE __Pack_OnData(Minus AS LOGICAL @, Weight AS VARIANT) AS VOID;
                 HELPSTRING "Occurs when data arrives to the Serial communications port"
   
       This.Weight = IIf(minus, -weight, weight)
       IF !ISNULL(This.DisplayControl)
          This.DisplayControl.Value = This.Weight
       Endif
    ENDPROC
ENDDEFINE

Now in your form you need the other code I gave you already, and set DisplayControl to a Textbox you want to display the weight in.

This could be init of a form:
Code:
This.Addproperty("oPack",CREATEOBJECT('OnlineWeightDLL.pack'))

SET PROCEDURE TO packevents.prg ADDITIVE && or put this in main.prg, your program set main in the project manager

This.Addproperty("oPackEvents",CREATEOBJECT('PackEventhandler'))

* finally bind the one to the other
Eventhandler(This.oPack,This.oPackEvents)
* and for example to display weights in a Textbox of the form:
This.oPackEvents.DisplayControl = This.TextBox1

Previously I wrote loPack and loPackevents, variables, as you use the object and eventhandler in a form, they should be form properties, so the live as long as the form lieves, and not just as long as the variables get out of scope.

And finally, what you can also do is leave This.oPackEvents.DisplayControl Null and instead read the last weight arrived from This.oPackEvents.Weight.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top