Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. file info. rss. print.
USING AN OLEPUBLIC CLASS TO IMPLEMENT A COM INTERFACE

Anyone interested in a licensing their VFP app may want to consider using QLM from Interactive Studios. It relies upon a single DLL to generate and verify license keys. The simplicity of their approach to licensing is what attracted me to their product. Our company distributes an application to feedlot clients which contains proprietary algorithms and databases. We needed a simple way to expire the app after a period of time, in case the client relationship has ended, similair to the trial usage concept.

Although IS does not support Foxpro at this time, I felt it would work for us and downloaded their free trial version for experimentation. The initial problem being that Foxpro could not communicate with their dll directly. However, a unique feature of VFP is the ability to implement a COM interface via an OLEPUBLIC class. This VFP class when correctly defined can inherit the methods and properties exposed in QLM's IsLicense30.dll.



The trick is to design a class that matches the exact methods of the dll. As it turns out this isn’t much of a trick at all, since all one has to do is open the object in VFP’s object browser and then drag and drop the desired interface into an edit window. Foxpro does the real work of encapsulating the object’s interace into a VFP class. Save this class in your project as prg file and your ready to have some fun.

Here is a code snippet for the class:

DEFINE CLASS myclass AS session OLEPUBLIC
IMPLEMENTS IIsLicenseMgr IN "IsLicense30.IsLicenseMgr"

PROCEDURE IIsLicenseMgr_Initialize(ProductID AS Integer, ProductName AS STRING, MajorVersion AS Integer, MinorVersion AS Integer, EncryptionKey AS STRING, PersistenceKey AS STRING) AS VOID;
HELPSTRING "Initialize the license key"
	* add user code here
ENDPROC

PROCEDURE IIsLicenseMgr_ValidateLicense(LicenseKey AS STRING) AS STRING;
 	HELPSTRING "Validate the license"
	* add user code here
ENDPROC


PROCEDURE IIsLicenseMgr_GetStatus() AS Integer;
 	HELPSTRING "Get the last status."
	* add user code here
ENDPROC

ENDDEFINE


Note that the class contains an IMPLEMENTS clause. This apparently enables the class to inherit from the parent dll. One thing I found necessary to add was #define statements in my class for each constant in the dll. This too was an easy task, just drag and drop the constants collection from the object browser into your class and drop it beneath the implements clause.

To instantiate the class you need to specify the library name with its class name, and the program where your Fox class resides. For my QLM class it looks like this:

Newobject("IsLicense30.IsLicenseMgr","LicenseMngr.prg")   


Somehow, kind of magically, Foxpro at this point loads an object reference with the methods, events, and properties of the parent DLL. I built a function from the supplied VB6 code example with a few tweaks here and there to handle validation for the license key.

Function iValidateLicense(LicenseKey As Character) As Integer

#Define EKeyPermanent	2
#Define EKeyDemo	4
#Define EKeyInvalid	8
#Define EKeyProductInvalid	16
#Define EKeyVersionInvalid	32
#Define EKeyExpired	64
#Define EKeyTampered	128

#Define EKeyMachineInvalid	256
#Define EKeyNeedsActivation	512
#Define PermanentGeneric	71
#Define Generic	71
#Define Evaluation	69
#Define Activation	65
#Define ComputerName	67
#Define UserDefined	85

Local isvalid As Integer
isvalid = 0

License = Newobject("IsLicense30.IsLicenseMgr","LicenseMngr.prg")

License.DefineProduct( 2, "Break even", 1, 0, "CLOVER", "{6B1D53A6-6725-4E01-AEBF-696EA6BE281A}" )

Local errorMsg As String
Local nStatus As Integer

errorMsg = License.ValidateLicense(LicenseKey)
nStatus = License.GetStatus()

Do Case
Case IsTrue(nStatus, EKeyInvalid) Or ;
		IsTrue(nStatus, EKeyProductInvalid) Or ;
		IsTrue(nStatus, EKeyVersionInvalid) Or ;
		IsTrue(nStatus, EKeyMachineInvalid) Or ;
		IsTrue(nStatus, EKeyTampered)

	Messagebox (errorMsg)
	isvalid = 0

Case (IsTrue(nStatus, EKeyDemo))

	If (IsTrue(nStatus, EKeyExpired)) Then
		Messagebox (errorMsg)
		isvalid = 0
	Else

		Messagebox (errorMsg)
		isvalid = License.DaysLeft()
	Endif

Case (IsTrue(nStatus, EKeyPermanent))

	Messagebox ("License OK")
	isvalid = 9999
Endcase

Return isvalid
Endfunc

Function IsTrue( nVal1 As Integer, nVal2 As Integer) As Boolean
If ((Bitand(nVal1,nVal2) = nVal1) Or (Bitand(nVal1,nVal2) = nVal2)) Then
	IsTrue = .T.
	Return IsTrue
Else
	IsTrue = .F.
	Return IsTrue
Endif
Endfunc




This technique would probably work with just about any COM compliant object.

Hope someone finds this useful.

ABOUT THE AUTHOR: DENNIS JONES

DENNIS JONES I'm life long Kansas native living in the small town of Abilene, home of the Eisenhower Library and once famous for being the end of the Chisolm Trail. My experience in programming began after working for many years as a computer operator. When the mainframe was retired in 97 I began my present employ with a feedlot consulting firm where I manage databases used for feed analysis "Quality Control" and cattle performance stats. My favorite hobby is hiking with my Weimaraner and bird watching.

FEEDBACK

jozel regorgo @ 1/30/2008 9:55:19 AM
fox pro coding

dcompy@yahoo.com @ 2/12/2008 11:27:49 AM
can you send me prg to run?
thank you



Your Name: 
Your Feedback: 

Spam Protection:
Enter the code shown: