Results 1 to 10 of 10

Thread: Adding controls dynamically at runtime causing problems

  1. #1

    Thread Starter
    Frenzied Member stateofidleness's Avatar
    Join Date
    Jan 2009
    Posts
    1,780

    Adding controls dynamically at runtime causing problems

    Hey fellas,
    So what I'm trying to do is build 16 forms dynamically at runtime (all will be identical). These 16 forms each will display a camera, which is using an ActiveX control made by a 3rd party. I am able to create the forms correctly and provide all necessary parameters for each control, but since I have to declare my own AddHandler event which checks if the camera connected, I need to somehow reference the ActiveX control at runtime, but I can't tell it which form it's on because it says it's not declared.

    Here is the code I'm using, Line 83 is where error occurs (in the Status Event)

    vb.net Code:
    1. Option Strict On
    2. Public Class MainForm
    3.  
    4.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    5.         'Setup the layout of all 16 cameras at run time
    6.         Me.Width = Screen.PrimaryScreen.WorkingArea.Width
    7.         BeginCameraLayout()
    8.     End Sub
    9.  
    10.     Private Sub BeginCameraLayout()
    11.         Dim screens As Integer
    12.         Dim count As Integer = 1
    13.         Dim camWidth As Integer = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
    14.  
    15.         For screens = 1 To 16
    16.             'This adds the necessary controls to the camera forms
    17.             Dim liveStatusLabel As New Label
    18.             Dim f As New Form
    19.             f.Controls.Add(liveStatusLabel)
    20.             'Format the new form's properties before displaying
    21.             f.Width = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
    22.             f.Height = CInt((Screen.PrimaryScreen.WorkingArea.Height - Me.Height) / 4)
    23.             f.ShowInTaskbar = False
    24.             f.ShowIcon = False
    25.             f.ControlBox = False
    26.             f.Text = "Camera " & screens
    27.             f.MinimizeBox = False
    28.             f.Show()
    29.             f.Controls.Add(AddVideoScreen(screens)) 'Call to create the ActiveX control
    30.             Select Case screens
    31.                 Case 1, 2, 3
    32.                     f.Top = Me.Height
    33.                     f.Left = (camWidth * count) - camWidth
    34.                     count += 1
    35.                 Case 4
    36.                     f.Top = Me.Height
    37.                     f.Left = (camWidth * count) - camWidth
    38.                     count = 1
    39.                 Case 5, 6, 7
    40.                     f.Top = Me.Height + f.Height
    41.                     f.Left = (camWidth * count) - camWidth
    42.                     count += 1
    43.                 Case 8
    44.                     f.Top = Me.Height + f.Height
    45.                     f.Left = (camWidth * count) - camWidth
    46.                     count = 1
    47.                 Case 9, 10, 11
    48.                     f.Top = Me.Height + f.Height + f.Height
    49.                     f.Left = (camWidth * count) - camWidth
    50.                     count += 1
    51.                 Case 12
    52.                     f.Top = Me.Height + f.Height + f.Height
    53.                     f.Left = (camWidth * count) - camWidth
    54.                     count = 1
    55.                 Case 13, 14, 15
    56.                     f.Top = Me.Height + f.Height + f.Height + f.Height
    57.                     f.Left = (camWidth * count) - camWidth
    58.                     count += 1
    59.                 Case 16
    60.                     f.Top = Me.Height + f.Height + f.Height + f.Height
    61.                     f.Left = (camWidth * count) - camWidth
    62.             End Select
    63.         Next
    64.     End Sub
    65.  
    66.     Private Function AddVideoScreen(ByVal screen As Integer) As AxVIDEOCONTROLLib.AxVideoControl
    67.         Dim vcLive As New AxVIDEOCONTROLLib.AxVideoControl
    68.         vcLive.Dock = DockStyle.Fill
    69.         vcLive.DLLPath = Application.StartupPath & "\TL4516UL.dll"
    70.         vcLive.UserName = "live"
    71.         vcLive.Password = "live"
    72.         vcLive.IPAddress = "100.100.100.100"
    73.         vcLive.Port = 53705
    74.         vcLive.CameraID = screen
    75.         vcLive.Connect()
    76.         AddHandler vcLive.Status, New AxVIDEOCONTROLLib._DVideoControlEvents_StatusEventHandler(AddressOf vcLive_Status)
    77.         Return vcLive
    78.     End Function
    79.  
    80.     Private Sub vcLive_Status(ByVal sender As Object, ByVal e As AxVIDEOCONTROLLib._DVideoControlEvents_StatusEvent)
    81.         If ((e.strMessage = "Status:Connection Established") OrElse e.strMessage.Contains("Error")) Then
    82.             If (e.strMessage = "Status:Connection Established") Then
    83.                f.vcLive.PlayLive() 'This line throws error. 'f' is not declared          
    84.             End If
    85.         End If
    86.     End Sub
    87.  
    88. End Class


    Also, if I comment out the error line, just to test, I get this error:

    A first chance exception of type 'System.Windows.Forms.AxHost.InvalidActiveXStateException' occurred in AxInterop.VIDEOCONTROLLib.dll

    on the line referencing the .dll path. I am thinking it may be because after the first iteration, the .dll is in use and therefore future iterations can't use it, causing the error. I'm trying to take a very OOP approach to this project (keeping things in their own subs and whatnot) but the referencing and scope is throwing me off quite a bit.

  2. #2
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Adding controls dynamically at runtime causing problems

    Why not create a form at design time with everything all hooked up, then at run time, simply create new instances of the form?

    then you could skip the call to f.Controls.Add(AddVideoScreen(screens))
    And your status event would be contained in the form, then you could simply use Me. to get to the form instance as needed.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Adding controls dynamically at runtime causing problems

    Of course it doesn't know f, you haven't declared it. You've only declared a variable named f in the BeginCameraLayout method, which is a local variable and thus does not exist in any other method.

    First of all, I think your AddHandler line is a bit strange. It seems you are creating an event delegate manually, which you shouldn't have to. Doesn't this work:
    vb.net Code:
    1. AddHandler vcLive.Status, AddressOf vcLive_Status

    I'm not sure if it makes a difference, but it might.

    Anyway, if that works, the 'sender' parameter in the vcLive_Status method should be the AxVideoControl object that raised the event. So, you can simply cast it, and use its methods:
    vb.net Code:
    1. Dim vcLive = DirectCast(sender, AxVIDEOCONTROLLib.AxVideoControl)
    2. vcLive.PlayLive()

    About the other error, I'm hoping it doesn't occur after you use this code, because I've no idea what could cause that.


    EDIT
    While my solution should work, and explains what is going wrong, techgnome's solution is better. Just put the control on a form during design-time and handle its event on that form.

    EDIT2
    But, you may get into 'trouble' with the CameraID integer. Instead of passing it when creating the camera control (which you now do during design-time probably, or still in code but only once), you can make your form accept the ID as an argument in its contstructor, or as a public property (or both).
    vb.net Code:
    1. Public Class CameraForm
    2.    Inherits Form
    3.  
    4.    Public Sub New(ByVal cameraId As Integer)
    5.       Me.InitializeComponent()   'this is always required
    6.      
    7.       vcLive.CameraID = cameraId   'vcLive is the name of the camera control on the form
    8.  
    9.       'set other properties here, such as size and position
    10.    End Sub
    11.  
    12.    '...
    13. End Class
    Now, you just pass the id when you create the form:
    vb.net Code:
    1. For screen As Integer = 1 To 16
    2.    Dim f As New CameraForm(screen)  'pass it here
    3.    'you don't need to set 38 gazillion properties here, you can set them in the forms constructor instead
    4.    'of course you still CAN set the properties here, it's just not as 'elegant' :)
    5.    f.Show()
    6. Next

  4. #4

    Thread Starter
    Frenzied Member stateofidleness's Avatar
    Join Date
    Jan 2009
    Posts
    1,780

    Re: Adding controls dynamically at runtime causing problems

    ahh much appreciated guys.
    I actually started out with a "template" form to use for all 16 cameras, but then wasn't sure if I'd need to create 16 of these forms or what.

    As I may have different views (4 cameras 2x2, 16 cameras 4x4 etc), I would just set up my For loop accordingly? The properties of the form will change if I do this though which is why I can't declare them on the Form in design time. The .Top, .Left, .Width and .Height properties will all change depending on how many are showing.

    How can I still dynamically create these forms (based off the form in Designer View) and still dynamically set their properties?

  5. #5
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Adding controls dynamically at runtime causing problems

    You can set the properties that are always fixed (ShowInTaskbar, ShowIcon, ControlBox, etc, just a few I could see quickly) during design-time, or in the forms constructor or Form_Load event. You can then, after declaring a new form or after calling its Show method, set the other properties like you are doing now. It doesn't really matter though, you could also set all the properties like you are doing now. It just seems more appropriate to have most of these properties (well, as much as possible) in the form class itself so you don't clutter up your form creation code with stuff you can set elsewhere.

  6. #6
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Adding controls dynamically at runtime causing problems

    Same as you are now:
    Code:
        Private Sub BeginCameraLayout()
            Dim screens As Integer
            Dim count As Integer = 1
            Dim camWidth As Integer = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
    
            For screens = 1 To 16
                Dim f As New cameraTemplateForm
                'Format the new form's properties before displaying
                f.Width = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
                f.Height = CInt((Screen.PrimaryScreen.WorkingArea.Height - Me.Height) / 4)
                f.Text = "Camera " & screens
    
                'Set these at Design time in the template form
                'f.ShowInTaskbar = False
                'f.ShowIcon = False
                'f.ControlBox = False
                'f.MinimizeBox = False
    
                f.Show()
    
                Select Case screens
                    Case 1, 2, 3
                        f.Top = Me.Height
                        f.Left = (camWidth * count) - camWidth
                        count += 1
                    Case 4
                        f.Top = Me.Height
                        f.Left = (camWidth * count) - camWidth
                        count = 1
                    Case 5, 6, 7
                        f.Top = Me.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                        count += 1
                    Case 8
                        f.Top = Me.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                        count = 1
                    Case 9, 10, 11
                        f.Top = Me.Height + f.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                        count += 1
                    Case 12
                        f.Top = Me.Height + f.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                        count = 1
                    Case 13, 14, 15
                        f.Top = Me.Height + f.Height + f.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                        count += 1
                    Case 16
                        f.Top = Me.Height + f.Height + f.Height + f.Height
                        f.Left = (camWidth * count) - camWidth
                End Select
            Next
        End Sub
    easy as that...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  7. #7

    Thread Starter
    Frenzied Member stateofidleness's Avatar
    Join Date
    Jan 2009
    Posts
    1,780

    Re: Adding controls dynamically at runtime causing problems

    ah very cool, here's what i got:

    In my MainForm:

    vb Code:
    1. Option Strict On
    2. Public Class MainForm
    3.  
    4.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    5.         Me.Width = Screen.PrimaryScreen.WorkingArea.Width
    6.         'Setup the layout of all 16 cameras at run time
    7.         BeginCameraLayout()
    8.     End Sub
    9.  
    10.     Private Sub BeginCameraLayout()
    11.         Dim screens As Integer
    12.         Dim count As Integer = 1
    13.         Dim camWidth As Integer = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
    14.  
    15.         For screens = 1 To 16
    16.             'Add Camera Forms and lay them out correctly
    17.             Dim f As New CameraForm
    18.             f.Width = CInt(Screen.PrimaryScreen.WorkingArea.Width / 4)
    19.             f.Height = CInt((Screen.PrimaryScreen.WorkingArea.Height - Me.Height) / 4)
    20.             f.Show()
    21.             Select Case screens
    22.                 Case 1, 2, 3
    23.                     f.Top = Me.Height
    24.                     f.Left = (camWidth * count) - camWidth
    25.                     count += 1
    26.                 Case 4
    27.                     f.Top = Me.Height
    28.                     f.Left = (camWidth * count) - camWidth
    29.                     count = 1
    30.                 Case 5, 6, 7
    31.                     f.Top = Me.Height + f.Height
    32.                     f.Left = (camWidth * count) - camWidth
    33.                     count += 1
    34.                 Case 8
    35.                     f.Top = Me.Height + f.Height
    36.                     f.Left = (camWidth * count) - camWidth
    37.                     count = 1
    38.                 Case 9, 10, 11
    39.                     f.Top = Me.Height + f.Height + f.Height
    40.                     f.Left = (camWidth * count) - camWidth
    41.                     count += 1
    42.                 Case 12
    43.                     f.Top = Me.Height + f.Height + f.Height
    44.                     f.Left = (camWidth * count) - camWidth
    45.                     count = 1
    46.                 Case 13, 14, 15
    47.                     f.Top = Me.Height + f.Height + f.Height + f.Height
    48.                     f.Left = (camWidth * count) - camWidth
    49.                     count += 1
    50.                 Case 16
    51.                     f.Top = Me.Height + f.Height + f.Height + f.Height
    52.                     f.Left = (camWidth * count) - camWidth
    53.             End Select
    54.         Next
    55.     End Sub
    56.  
    57. End Class


    In my CameraForm:

    vb Code:
    1. Public Class CameraForm
    2.     Private Sub CameraForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    3.         camera.DLLPath = Application.StartupPath & "\TL4516UL.dll"
    4.         camera.Connect()
    5.         'AddHandler camera.Status, AddressOf camera_Status
    6.         AddHandler camera.Status, New AxVIDEOCONTROLLib._DVideoControlEvents_StatusEventHandler(AddressOf camera_Status)
    7.     End Sub
    8.  
    9.     Private Sub camera_Status(ByVal sender As Object, ByVal e As AxVIDEOCONTROLLib._DVideoControlEvents_StatusEvent)
    10.         MsgBox(e.ToString & " " & e.strMessage)
    11.         If ((e.ToString = "Status:Connection Established") OrElse e.ToString.Contains("Error")) Then
    12.             If (e.ToString = "Status:Connection Established") Then
    13.                 Dim cam As New AxVIDEOCONTROLLib.AxVideoControl
    14.                 cam = DirectCast(sender, AxVIDEOCONTROLLib.AxVideoControl)
    15.                 cam.PlayLive()
    16.             End If
    17.         End If
    18.     End Sub
    19. End Class


    Here is the product:



    For some reason the AddHandler event isn't firing. I've tried both declarations and neither one will make it fire.
    Attached Images Attached Images  

  8. #8
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Adding controls dynamically at runtime causing problems

    don't use the AddHandler.... plop the control right onto the form then double click it, and set the event handler code just like any other control you are using... the reason to use add handler is if you want to dynamically link code to a controls (or a lot of controls to one event handler)... this is one case where it may not be working right for some reason.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  9. #9
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Adding controls dynamically at runtime causing problems

    It seems you are not setting a whole load of properties on the AxVideoPlayer control that you were setting before (CameraID, Username, Password, IPAddress, etc). Not sure if that is related.

    Anyway, you don't need to use AddHandler when you added your control during design-time. Just handle its Status event as you would handle a button's Click event. That said, AddHandler should work just fine too, so that can't cause your problem.

  10. #10

    Thread Starter
    Frenzied Member stateofidleness's Avatar
    Join Date
    Jan 2009
    Posts
    1,780

    Re: Adding controls dynamically at runtime causing problems

    as I have no documentation with the correct usage of the .dll, I'm kinda shooting in the dark. Removing the Addhandler and doing it through design-view worked a charm. The event is now firing as expected.
    The problem I'm having is I don't think I am supposed to create a new connection for each camera with separate logins etc..

    I think I am supposed to connect using:

    camera.DLLPath = Application.StartupPath & "\TL4516UL.dll"
    camera.IPAddress = "100.100.100.100"
    camera.Port = 53705
    camera.UserName = "admin"
    camera.Password = "admin"

    I think I need to set all that and then connect, and while connected get a different cameraID for each ActiveX control.. I'm just not sure how to do that

    Pseudo of what I think should be done

    Set properties for the connection
    Connect
    Load 16 Form instances
    Load a different CameraID for each form

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