Results 1 to 12 of 12

Thread: Simple AcitveX DLL QUESTION (I hope)

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11

    Simple AcitveX DLL QUESTION (I hope)

    In this code:

    Code:
    Option Explicit
    
    ' PROPERTIES':
    Private m_comm As MSComm
    Private m_num As Long
    Private m_str As String
    
    ' METHODS:
    Public Sub function1()
        m_str = "Str1"
        m_num = 1
    End Sub
    
    Public Sub function2(ByVal var As String)
        m_str = "Str2"
        m_num = 2
        m_comm.CommPort = 1                   <-------!!!! ERROR!!!!!
    End Sub
    Error: "Object variable or With block variable not set (Error 91)"


    Why I can't assign the value ?????

    Thanks

  2. #2
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758
    m_comm is an object and must be assigned to something before it can be used. Somewhere in your class you need to assign an instance of the MSComm control to your m_comm variable.

    Typically a property Get/Set is used

    VB Code:
    1. Public Property Get Communications() as MSCommLib.MSComm
    2.    Set Communications = m_comm
    3. End Property
    4.  
    5. Public Property Set Communications(CommControl as MSCommLib.MSComm
    6.    Set m_comm = CommControl
    7. End Property
    8.  
    9. Private Sub Class_Terminate()
    10.     Set m_comm = nothing
    11. End Sub

  3. #3

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    Thank you brucevde for the answer.

    But I don't understood this:

    GET/SET Properties are used to communicate with the class; they are used to READ a private member variable and to WRITE a private member varable from outside the class (i.e: from the exe application that "call" the class).

    But in my case I'm WRITING the private member variable from within the class => I don't understand the error.


    I hope u'll reply me.

    MatteoXMad

  4. #4
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758
    MSComm is a control and must be put on a form same as a textbox, label etc.. You cannot create a new instance of the MSComm control within your class - you need a form. This means you need some method of telling your class which control you want it to use, thus the Property Get/Set.

    This is no different than your exe application calling your class. Let's say your class is named clsCommPort and you code these lines.

    Dim objCommPort as clsCommPort
    objCommPort.Function1

    You will receive the error 91 in your exe because you have not created an instance of the class object. You must add the line Set objCommPort = New clsCommPort.

  5. #5

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    After your answer I tried many solutions, without a correct result.

    PROJECT ActiveX DLL named Class1:

    VB Code:
    1. Option Explicit
    2.  
    3. ' PROPERTIES':
    4. Private m_comm As MSComm
    5. Private m_num As Long
    6. Private m_str As String
    7.  
    8. Public Sub function1(ByVal var As String)
    9.     MsgBox var
    10.     m_str = "Str1"
    11.     m_num = 1
    12.     m_comm.CommPort = 1                   '<-------!!!! ERROR!!!!!
    13. End Sub
    14.  
    15. Public Property Get Communications() As MSCommLib.MSComm
    16.    Set Communications = m_comm
    17. End Property
    18.  
    19. Public Property Set Communications(CommControl As MSCommLib.MSComm)
    20.    Set m_comm = CommControl
    21. End Property

    PROJECT Standard EXE (that call Class1):

    VB Code:
    1. Private Sub Command1_Click()
    2.     Dim class As New Class1
    3.     class.function1 ("pippo")
    4. End Sub

    An error occur immediatly with GET/SET Properties...

    :-(
    Help me!

    MatteoXMad

  6. #6
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758
    Since you are creating a DLL you are probably getting the error "Private objects cannot be used in Public..." , the rules are different for ActiveX DLLs. You need to declare your Property Get/Set as the generic Object and then test to make sure the client is passing a control of the correct type.

    PROJECT ActiveX DLL named Class1:
    -- Note that this project must reference the Microsoft MSComm Control component.

    VB Code:
    1. Option Explicit
    2.  
    3. ' PROPERTIES':
    4. Private m_comm As MSComm
    5. Private m_num As Long
    6. Private m_str As String
    7.  
    8. Public Sub function1(ByVal var As String)
    9.     MsgBox var
    10.     m_str = "Str1"
    11.     m_num = 1
    12.     m_comm.CommPort = 1  
    13. End Sub
    14.  
    15. Public Property Get Communications() As Object  '<---Changed to As Object
    16.    Set Communications = m_comm
    17. End Property
    18.  
    19. Public Property Set Communications(CommControl As Object) '<---Changed to As Object
    20.    If Typeof CommControl Is MSCommLib.MSComm Then '<---Check if the class is passed the proper cotnrol
    21.         Set m_comm = CommControl
    22.    Else
    23.          Err.Raise -1,,"Requires a Microsoft Comm Control" '<--Raise an error to the client app
    24.    End if
    25. End Property


    PROJECT Standard EXE (that call Class1): - You still have not told the Class which instance of the Comm control it should use.

    VB Code:
    1. Private Sub Command1_Click()
    2.     Dim class As New Class1
    3.     Set class.Communications = Form1.MSComm1 '<--- Tell the class to use the Comm control on Form1.
    4.     class.function1 ("pippo")
    5. End Sub

  7. #7

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    Thank u very much for your replies. I'll try as soon as possible.

    MatteoXMad

  8. #8

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    Code:
    Thank you very much for your help, the code you gave me works.
    
    You are GREAT, really!
    
    So this is the CONCLUSION:
    
    If an EXE Application wants to call the function connect() of the ActiveX DLL and this function use some components
    (i.e. MSComm)  =>  also the EXE App. MUST reference those components!!!
    
     
                             ------------------
      ------------ connect() |                |
      |          |---------->|  ActiveX DLL   |
      | EXE App. |           |                |
      |          |<----------|   MSComm       |
      ------------           |     |          |
                             ------|-----------
                                   |
                                   |----> serial line
    
    
    There's no way to do this without using references in the EXE App.????
    
    
    Thanks again
    
    
    MatteoXMad

  9. #9
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758
    Never say never. I probably should have mentioned this before but there is a way to have the ActiveX DLL handle everything. This hides the fact that you are using the MSComm control from the EXE application. You could easily upgrade the DLL with a different control in the future without affecting the EXE.

    Add a Form to your DLL project that contains an MSComm control, my example below names it frmCommunications.
    When a new instance of your Class is created load an instance of the form (it doesn't have to be visible).
    Your class could use its instance of the form to call the control directly.
    The Get/Set properties in the first example can be removed from the class.

    You might have problems if two programs are using the DLL at the same time.

    VB Code:
    1. 'Private m_comm As MSComm '<---No longer required
    2. Private m_num As Long
    3. Private m_str As String
    4. Private frmMyComm as frmCommunications
    5.  
    6. Public Sub function1(ByVal var As String)
    7.     MsgBox var
    8.     m_str = "Str1"
    9.     m_num = 1
    10.     frmMyComm.MSComm1.CommPort = 1  '<--Call the control directly
    11. End Sub
    12.  
    13. Private Sub Class_Initialize
    14.    Set frmMyComm = New frmCommunications  '<--initialize the class instance of the form
    15.    Load frmMyComm
    16. End Sub
    17.  
    18. Private Sub Class_Terminate
    19.    Unload frmMyComm '<-- make sure everything is cleaned up
    20.    Set frmMyComm = Nothing
    21. End Sub

    Standard EXE (that call Class1) does not need to reference the MSComm control and can simply be called by this function (hey that's what you had originally).

    VB Code:
    1. Private Sub Command1_Click()
    2.     Dim class As New Class1
    3.     class.function1 ("pippo")
    4. End Sub

    Hope this gives you more ideas.

  10. #10

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    Thank u again for the answer. I'll try to use the code u give me as soon as possible. It looks like that it'll work.

    So we've understood that to use objects inside a class, we must include these in a form.

    Do u know c++? It works different, really?

    Bye

    Mad

  11. #11
    PowerPoster
    Join Date
    Oct 2002
    Location
    British Columbia
    Posts
    9,758
    So we've understood that to use objects inside a class we must include these in a form
    That should be "to use controls inside a class we must include these in a form." Any COM object can be used in a class.

    I am familiar with C++ but my career took me down the VB path. I would have trouble writing any windows program in C nowadays. Its been so long (6+ years).

  12. #12

    Thread Starter
    New Member
    Join Date
    Nov 2002
    Posts
    11
    Why? Objects or controls are so different?
    Maybe, when we speak about controls, we are referring to ActiveX and COM architecture?

    Bye

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width