Solved

Using ActiveX DLL's as plug-ins to VB6 app.

Posted on 2004-10-06
15
408 Views
Last Modified: 2013-11-18
Hi!

Can ActiveX DLL's be used as plug-ins to VB6 application?

Lets say I have an application which draws the graph of some mathematical function.
It increments the X value from 1 to 10000, and for each X it calls some mathematical function which is stored in a DLL.

Here's the example:

DLL:
 - project name: TestDLLPlugInProject
 -   Class name: TestDLLPlugInClass
 - the code for that class:
'---------------------------------------------------------
Public Function GetY(ByVal X As Single) As Single
    GetY = 1000 * Sin(X)
End Function
'---------------------------------------------------------



Application:
 - create command button
 - add reference to TestDLLPlugInProject.DLL
'---------------------------------------------------------
Private Sub Command1_Click()
    Dim Test As TestDLLPlugInClass
    Set Test = New TestDLLPlugInClass
   
    Dim x As Single
    Dim y As Single
   
    For x = 1 To 10000
        y = Test.GetY(x)
        Me.PSet (x, y)
    Next x
End Sub
'----------------------------------------------------------


My question is:   Can I have more DLL's, where each of them has TestDLLPlugInClass and GetY function, but each of them performs different math operations.
So the final user can simply select which DLL they want to use, and get different results each time.
They could also be able to create their own DLL's, and use them instead of mine.

An example of different DLL's would be:
'----------------------------------------------------------
Public Function GetY(ByVal X As Single) As Single
    GetY = 1000 * Cos(X)
End Function
'----------------------------------------------------------
'----------------------------------------------------------
Public Function GetY(ByVal X As Single) As Single
    If X < 500 then GetY = 100
    If X >= 500 then GetY = 200
End Function
'----------------------------------------------------------

How do I do this if this is even possible?

Thanks in advance!
0
Comment
Question by:dbrckovi
  • 6
  • 3
  • 3
  • +1
15 Comments
 
LVL 10

Expert Comment

by:anv
ID: 12235166
yes u can have...different DLL's

only thing is u need refernce each of the Get functions ?Using the object of that particular class of the specified DLL's

:))
0
 
LVL 10

Assisted Solution

by:anv
anv earned 80 total points
ID: 12235223
say if u have included two DLL's in ur project

DLL1 and DLL2 having function GETX in both of them..

declare two variables or objects referencing the class for both the DLL's

dim obj1 as DLL1.Class1
dim Obj2 as DLL2.CLass2

to use the fucntions do following

obj1.GetX
obj2.GetX


Hope This will make u understand the thing..
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12235251
I know how to create more DLL's each with different class name, and reference them all, but this is not the point.
This way I can't let the user to write their own DLL and use it instead of mine.

I tried something like this:

 - I have changed original DLL with this:   GetY = 1000    and compiled it to TestDLLPlugInProject2.DLL       (Class names in both DLL's are the same)

 - in my main project I have added a FileListBox, and now the form's code looks like this:
'------------------------------------------------
Dim ActiveDLL As String

Private Sub Command1_Click()
    Dim Test As TestDLLPlugInClass
    Set Test = New TestDLLPlugInClass
   
    Dim x As Single
    Dim y As Single
   
    Me.Cls
    For x = 1 To 10000
        y = Test.GetY(x)
        Me.PSet (x, y)
    Next x
End Sub

Private Sub File1_Click()
    Dim SelectedDLL As String
       
    SelectedDLL = File1.List(File1.ListIndex)
   
    If SelectedDLL = ActiveDLL Then
        MsgBox "File already loaded"
    Else
        Shell "regsvr32 -u " & App.Path & "\" & ActiveDLL, vbNormalFocus
        Shell "regsvr32 " & App.Path & "\" & SelectedDLL, vbNormalFocus
        ActiveDLL = SelectedDLL
    End If

End Sub

Private Sub Form_Load()
    File1 = App.Path
    ActiveDLL = "TestDLLPlugInProject.dll"
End Sub
'------------------------------------------------------------------------------------------

When I run it and click on a button, I get a graph produced by GetY function from first DLL.
When I click on another DLL in FileLiestBox, I'd like VB6 to re-reference to GetY in another DLL. So if I click on a button I'd get a straight Line. (Y=1000)

For now Regsvr32 successfully registers and unregisters the DLL's, but clicking on a button, still draws sinusoide.
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12235293
anv:

I'm not trying to add reference to more than one DLL at Design-time. I know how to do it.

I want to add reference to a DLL at Run-Time.
Winamp can do it. Can I do it in VB too?

Note that my example is only my approach, which may be wrong, but there has to be some way to do it, becouse many applications use DLL's as plug-ins.

I'm asking this here, becouse I ran out of ideas.

Thanks!
0
 
LVL 10

Expert Comment

by:anv
ID: 12235386
cannot u use optional parameters or
Param array instead of a single parameter

so u can get to know as per the parameters what sould ur funtion do .. depending on the parameter values..

0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12235543
Yes I can, but this is not the point.

The point is to create VB6 application which can use DLL's created by user and reference to them at Run-Time.
This function is only an example, which I used to make it simple.

Another example would be the following:
'-----------------------------------------------------------------------------
Let's say I have created a chess game. The main application manages the board, buttons, rules, timer and provides an interface for a human player.
Now I'd like to create more computer opponents.

Artifitial Intelligence (lets say. personality) for each computer player would be in a different DLL.
Now when User selects some computer player (DLL), the game would load that DLL and use the code from that DLL to determine the next computer's move.

My main intention is to enable the user to create their own computer player, with it's own logic and intelligence, add it to already existing players, and play against it.
This opens a possibility for two or more users to create their own "BOT's" and make them compete against each other to see who wrote better AI.
Possibilities are endless.

The only problem is how to make VB6 application reference the DLL at run-time, and use it just as if it was referenced through Project -> References at Design-Time?



P.S. I'm not actualy writing a chess game, but chess is the closest thing with which we all are familliar.
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12235967
And now I feel like a jackass. :-)

I've been trying to figure this out by myself for months, but no luck, and as soon as I openned this question I managed to answer it.

I was reding some articles about this topic but couldn't find anything usefull until I tried CreateObject. Something I used thousands of times before to create Office objects, but I didn't think of using it
for loading DLL's.

I can't belive it's so simple.
Just register the DLL and call:         Set something = CreateObject("TestDLLProject.TestDLLClass","")     to create the class object
                                             OR  Set something = Nothing                                                              to destroy it.

No design-time references needed. I just have to know Project name, class name and functions in that class.


I guess, I'll have to ask someone in CS to delete this question. Sorry anv.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 10

Accepted Solution

by:
fds_fatboy earned 400 total points
ID: 12236105
I have several applications out that allow users to write plugins. The way I do it is to provide a standard interface that the plugin implement. This also needs a calling mechanism. I have a user-customisable validation routine which uses rules to validate data before it gets written to the database. To simplify things a little: rule is made up of  2 expressions (operands) and an operator (equality or inequality). The expressions are small scripts and can contain functions here is are 2 examples:

stdValidPlugin.stdRules::yearsdiff(DateBirth,statusdate)
stdValidPlugin.stdRules::MinimumAge(ClientSchemeID)

How it works:

First the users write a DLL that implements this (named IValidFunctionPlug):
Public Function RunFunction(FunctionName As String, _
                            vntParameters As Variant) As Variant
End Function

The interface must be simplistic

Inside their DLL plugin object:

Implements IValidFunctionPlug
...

Private Function IValidFunctionPlug_RunFunction(FunctionName As String, Parameters As Variant) As Variant
    On Error GoTo ErrorHandler

    Select Case LCase(FunctionName)
        Case "isninumber"
             IValidFunctionPlug_RunFunction = IsNINumber(Parameters)
        Case "convertnull"
             IValidFunctionPlug_RunFunction = ConvertNull(Parameters)
        Case "minimumage"
             IValidFunctionPlug_RunFunction = MinumumAge(Parameters)
        Case "maximumage"
             IValidFunctionPlug_RunFunction = MaximumAge(Parameters)
        Case "isnull"
             IValidFunctionPlug_RunFunction = ValueIsNull(Parameters)
        Case "today"
             IValidFunctionPlug_RunFunction = TodaysDate()
        Case "yearsdiff"
             IValidFunctionPlug_RunFunction = DateTimeDiff("yyyy", Parameters)
        Case "monthsdiff"
...
        Case Else
            Err.Raise 5, , "'" & MstrFunctionName & "' is not a recognised function name."
    End Select
...

Yes - its a big case statement. The case statement passes the function call on to the author's (user's) code - nasty but it works.

The user compiles it and it the object is registered.

In my app code the expression parser is recursive. It evaluates each part of the expression as it goes along.
When it comes to evaluating the function call it splits the string into two parts on "::"
    PluginReference = "stdValidPlugin.stdRules"
    FunctionReference = "yearsdiff(DateBirth,statusdate)"


Then I use code like this
    Dim Result As Variant
    Dim FunctionName As String
    Dim objPlugin As IValidFunctionPlug
    Dim vntParameters() As Variant
...

'The Function Name and parameters are extracted from FunctionReference and parameters evaluated.  The parameters can conttain reference to data or, can be further function calls - hence the recursive nature. The values are placed into a variant array: vntParameters
...

   Set objPlugin  = CreateObject(PluginReference)  ' latebound - but we know the interface
   Result = objPlugin.RunFunction(FunctionName, vntParameters)
...

Anyway sorry it was so longwinded. I tried to simplify as musch as I could. I hope it helps.
0
 
LVL 10

Expert Comment

by:fds_fatboy
ID: 12236122
I should have known - that took me about half an hour to type into the box and you've worked it out yourself two minutes after I started typing. Anyway I hope the calling mechanism stuff helps a little.
0
 

Assisted Solution

by:DingleBerry9876543210
DingleBerry9876543210 earned 20 total points
ID: 12242098
I think this should be kept, some mighty jucy info here I recon.
Dingle Berry
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12245835
fds_fatboy:
Really informative post. I would have accepted it immediately without going to CS.

You know what?
I'm so happy this works after so much time of frustration that I'll give the points anyway.
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12245844
DingleBerry9876543210:

For participating! :-)
0
 
LVL 10

Expert Comment

by:fds_fatboy
ID: 12246689
:-)
0
 

Expert Comment

by:DingleBerry9876543210
ID: 12249494
Who howdy! My first expert points! Thank ya!
I will have a big cold one come quiten time and tost ya!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now