Valhalla Legends Forums Archive | Visual Basic Programming | Problem with Objects - *~Problem Resolved~*

AuthorMessageTime
Dyndrilliac
I'm writing a simple plugin engine in VB, but for some reason I keep getting Run-time Error '91', "Object variable or With block variable not set." I can't figure out why I'm getting the error. It's breaking on the error at the end of the f_LoadPlugins function. Here's my code for my TestApplication:[code]'// frmMain.frm

Public Sub f_PrintText(sText As String)
    lblText.Caption = sText
End Sub

Private Sub cmdPluginActivate_Click()
    Dim i As Integer, PluginName As String
    For i = 0 To UBound(mdlPlugin.o_Plugins)
        If ((cboPlugins.Text) = (o_Plugins(i).p_Version)) Then
            Call o_Plugins(i).Main
        End If
    Next
End Sub

Private Sub Form_Load()
    Dim i As Integer
    Call mdlPlugin.f_LoadPlugins
    For i = 0 To UBound(o_Plugins)
        cboPlugins.AddItem o_Plugins(i).p_Version()
    Next i
End Sub[/code][code]'// mdlPlugin.bas

Option Explicit

Public o_Plugins() As Object

Public Sub f_LoadPlugins()
    'On Error GoTo Error
    Dim s() As String, i As Integer, pId As String
   
    s() = f_GetFolderFiles(App.Path & "\Plugins", "*dll")

    If MsgBox("Have all your plugins been registered?", vbQuestion + vbYesNo, "Register") = vbNo Then
        For i = 0 To UBound(s)
            Shell "regsvr32 """ & s(i) & """", vbNormalFocus
        Next
    End If
   
    ReDim o_Plugins(0)
   
    For i = 0 To UBound(s)
        ReDim Preserve o_Plugins(i)
        pId = f_GetBaseName(s(i)) & ".Plugin"
        Debug.Print pId
        Debug.Print s(i)
        '// I'm using "Set" here.
        Set o_Plugins(i) = CreateObject(pId)
        o_Plugins(i).p_HostModule frmMain
    Next
   
    Exit Sub
'Error:
    'MsgBox "A critical error has occurred!" & vbCrLf & "  Error Number: " & Err.Number & vbCrLf & "  Error Description: " & Err.Description & vbCrLf & "  Source Plugin: " & mdlPlugin.o_Plugins(i).p_Version() & vbCrLf & "Please contact the plugin author for more information.", vbCritical + vbOKOnly, "f_LoadPlugins() Error!"
End Sub

Public Function f_GetFolderFiles(Folder As String, Optional Filter As String = ".*", Optional retFullPath As Boolean = True) As String()
  Dim FileNames() As String
  Dim Extension, FS As String
 
  If Not f_FolderExists(Folder) Then
        f_GetFolderFiles = FileNames()
        Exit Function
  End If
 
  Folder = IIf(Right$(Folder, 1) = "\", Folder, Folder & "\")
  If Left$(Filter, 1) = "*" Then Extension = Mid$(Filter, 2, Len(Filter))
  If Left$(Filter, 1) <> "." Then Filter = "." & Filter
 
  FS = Dir$(Folder & "*" & Filter, vbHidden Or vbNormal Or vbReadOnly Or vbSystem)
  While FS <> vbNullString
    If FS <> vbNullString Then f_Push FileNames(), IIf(retFullPath = True, Folder & FS, FS)
    FS = Dir$()
  Wend
 
  f_GetFolderFiles = FileNames()
End Function

Public Function f_FolderExists(Path As String) As Boolean
  If Len(Path) = 0 Then Exit Function
  If Dir$(Path, vbDirectory) <> vbNullString Then f_FolderExists = True
End Function

Public Function f_GetBaseName(Path As String) As String
    Dim s() As String
    Dim ub As String
    s = Split(Path, "\")
    ub = s(UBound(s))
    If InStr(1, ub, ".") > 0 Then
        f_GetBaseName = Mid$(ub, 1, InStrRev(ub, ".") - 1)
    Else
        f_GetBaseName = ub
    End If
End Function

Public Sub f_Push(sArray() As String, Value As Variant)
    On Error GoTo Error
    Dim i
    i = UBound(sArray)
    ReDim Preserve sArray(UBound(sArray) + 1)
    sArray(UBound(sArray)) = Value
    Exit Sub
Error:
    ReDim sArray(0)
    sArray(0) = Value
End Sub

Public Function f_ArrayIsEmpty(sArray() As String) As Boolean
    On Error GoTo Error
    Dim i As Integer
    i = UBound(sArray)
    f_ArrayIsEmpty = False
    Exit Function
Error:
    f_ArrayIsEmpty = True
End Function[/code]

And the TestPlugin's code:[code]'// clsPlugin.cls

Option Explicit

Private o_HostModule    As Object
Private s_PluginVersion As String

Public Property Let p_HostModule(o_NewModule As Object)
    Set o_HostModule = o_NewModule
End Property

Public Property Get p_Version() As String
    p_Version = s_PluginVersion
End Property

Public Sub Main()
    MsgBox "Success! Everything is running fine!", vbExclamation + vbOKOnly, "Plugin is loaded!"
    o_HostModule.f_PrintText (p_Version() & " is running fine!")
End Sub[/code]

I have the ExamplePlugin.dll file in my "Plugins" subdirectory.
June 26, 2005, 10:47 AM
Mangix
MSDN says [quote]You attempted to use an object property without a valid object. If you leave out the Set statement, an error will be generated on the reference to the object.

To correct this error

Specify a reference for the object variable.[/quote]

btw: are you sure you can dim an array as an object?

edit:on another note, you can make an object public however VB wont know what that object is. so you need to tell it what the object is :P.
June 26, 2005, 2:09 PM
KkBlazekK
[quote author=Mangix link=topic=11980.msg117581#msg117581 date=1119794950]
btw: are you sure you can dim an array as an object?
[/quote]You can declare any type as an array. What line does it have problems with since I don't actually have to forms.
June 26, 2005, 4:20 PM
Dyndrilliac
The program errors in this function at the bottom:[code]Public o_Plugins() As Object

Public Sub f_LoadPlugins()
    'On Error GoTo Error
    Dim s() As String, i As Integer, pId As String
   
    s() = f_GetFolderFiles(App.Path & "\Plugins", "*dll")

    If MsgBox("Have all your plugins been registered?", vbQuestion + vbYesNo, "Register") = vbNo Then
        For i = 0 To UBound(s)
            Shell "regsvr32 """ & s(i) & """", vbNormalFocus
        Next
    End If
   
    ReDim o_Plugins(0)
   
    For i = 0 To UBound(s)
        ReDim Preserve o_Plugins(i)
        pId = f_GetBaseName(s(i)) & ".Plugin"
        Debug.Print pId
        Debug.Print s(i)
        '// I'm using "Set" here.
        Set o_Plugins(i) = CreateObject(pId)
        o_Plugins(i).p_HostModule frmMain
    Next
   
    Exit Sub
'Error:
    'MsgBox "A critical error has occurred!" & vbCrLf & "  Error Number: " & Err.Number & vbCrLf & "  Error Description: " & Err.Description & vbCrLf & "  Source Plugin: " & mdlPlugin.o_Plugins(i).p_Version() & vbCrLf & "Please contact the plugin author for more information.", vbCritical + vbOKOnly, "f_LoadPlugins() Error!"
End Sub[/code]

Edit: Ok, I commented out the Error handler, and now it errors on the line where I'm using Set. It raises Run-time Error '429', "ActiveX Component can't create object." I looked this up on MSDN here. Apparently what this error really means is that the ProgId(pId) was not found or not supplied. More information revealed this: (MSDN) "You tried to place an ActiveX control on a form at design time or add a form to a project with an ActiveX control on it, but the associated information in the registry could not be found. " I don't get how this is happening, I made sure to perform a check allowing the users to register the .dll's in the registry.

I added a couple debug statements before the Set command to give me the values of "pId" and "s(i)" (in that order). Here's my results:[quote]ExamplePlugin.Plugin
C:\Documents and Settings\Matt\My Documents\Source Code\Visual Basic\Plugin Engine\Plugins\ExamplePlugin.dll[/quote]

I can't figure out what's wrong  :( >:( ??? :-[ :-\ :'(
June 26, 2005, 9:26 PM
Mangix
instead of CreateObject, use "New pId". eg: [code]Set o_Plugins(i) As New pId[/code]
June 27, 2005, 4:56 AM
Dyndrilliac
Why? CreateObject is far superior to VB's New keyword. It creates objects without a Type Library (that VB understands) and it creates objects that can recognize and comply with COM.
June 27, 2005, 6:24 AM
Adron
It sounds like you need to look at why your plugin isn't registering correctly...
June 27, 2005, 12:56 PM
Networks
I was really lazy to look through the source code...=\ but I am willing to give you my plugin loading procedure and hopefully it'll help you.

[code]
Public Sub Load_Plugins()
    Dim tmpPlugin As String
   
    ReDim Plugins(0)
   
    Dim i As Integer
    Dim strPath As String
   
    With frmMain
        .FPluginBox.Path = (App.Path & "\Plugins")
        .FPluginBox.Visible = False
        For i = 0 To .FPluginBox.ListCount - 1
            strPath = App.Path & "\Plugins\" & .FPluginBox.List(i)
            Shell "regsvr32 " & Chr(34) & strPath & Chr(34) & " -s"
        Next i
    End With
   
    If frmMain.FPluginBox.ListCount > 0 Then
        frmMain.RTB2.SelText = vbNewLine
    End If
   
    'Load Plugins
    For i = 0 To frmMain.FPluginBox.ListCount - 1
        strPath = App.Path & "\Plugins\" & frmMain.FPluginBox.List(i)
        'Debug.Print frmMain.FPluginBox.List(i)
        tmpPlugin = Split(frmMain.FPluginBox.List(i), ".dll")(0)
        Shell "regsvr32 " & Chr(34) & strPath & Chr(34) & " -s"
        Set Plugins(UBound(Plugins)).Plugin = CreateObject(tmpPlugin & ".clsMain")
        Plugins(UBound(Plugins)).Plugin_Name = tmpPlugin & ".dll"
        If Plugins(UBound(Plugins)).Plugin.SetHost(Me) = True Then
            ReDim Preserve Plugins(UBound(Plugins) + 1)
            AddC frmMain.RTB2, RGB(6, 110, 158), "Loaded Plugin: ", QBColor(7), frmMain.FPluginBox.List(i)
        Else
            AddC frmMain.RTB2, RGB(6, 110, 158), "Failed to load plugin: ", vbRed, frmMain.FPluginBox.List(i)
        End If
    Next i
End Sub
[/code]
June 28, 2005, 2:41 AM
Dyndrilliac
Thanks. I think I see what's wrong now, I'm not passing the "-s" argument to the regsvr32 application via shell. That might be what's causing my plugins not to be registered properly. I'll check that avenue out as soon as I get home and post the results. Thanks for all your help guys.

Edit: No go. Didn't help. Here's my updated code.

Edit #2: Everything's fixed  ;D ;) :) Thanks for all your guys' help.
June 28, 2005, 3:42 AM
Networks
The '-s' just registers it silently opposed to the box popping up.
June 28, 2005, 3:50 PM

Search