locked
Invoke or BeginInvoke cannot be called on a control until the window handle has been created. RRS feed

  • Question

  • i AM TRYING TO USE A THREAD TO UPDATE SOME CONTROL during runtime using invoke and i get this message.
    here is my scenario:im trying to build a performance monitor tool
    i have a mainform that is MDI parent and i create mdi child using this
     Private Sub MonitorChild() 
            Dim frm As Form 
            frm = New Monitor 
            frm.MdiParent = Me 
            frm.Width = Me.Width - 25 
            frm.Height = Me.Height - 90 
            frm.WindowState = FormWindowState.Maximized 
            Dim handle As IntPtr = frm.Handle 
            frm.Show() 
     
        End Sub 
    when a user creates a mdi child another form is provided that adds a gauge control during run time for the performnace counter. here is how i do it and this code basically adds few handler that helps to move the control inside mdi child and witin their parent conatiner like panel or groupbox.


    Public Structure PerfCounter
        Dim sCategory As String
        Dim sCounter As String
        Dim sInstance As String
        Dim interval As Integer
        Dim ctrl As Control
        Dim ctrlType As String
        Dim machineName As String
        Dim keepLooping As Boolean
    End Structure
    Private Sub AddAquagauge() 
            Dim aquagague As New AquaGauge 
            Dim perfmCounterStruct As New PerfCounter 
            
            With aquagague 
                .DialText = LegendTextBox.Text 
                If ThresHold1CheckBox.Checked Then 
                    .RecommendedValue = Threshold1NumericUpDown.Value 
                End If 
                If ThresholdCheckBox2.Checked Then 
                    .ThresholdPercent = Threshold2NumericUpDown.Value - Threshold1NumericUpDown.Value 
                End If 
                .MaxValue = maximumNumericUpDown.Value 
                .MinValue = minimumNumericUpDown.Value 
                .DialColor = ControlColorButton.ForeColor 
                .DialText = NameTextBox.Text 
     
     
                activepanel.Controls.Add(aquagague) 
                AddHandler .MouseDown, AddressOf Monitor.Hand_CustomDown 
                AddHandler .MouseMove, AddressOf Monitor.Hand_CustomMove 
                AddHandler .MouseUp, AddressOf Monitor.Hand_CustomUp 
     
            End With 
            With perfmCounterStruct 
                .ctrl = aquagague 
                .ctrlType = "AquaGauge" 
                .interval = PollingIntervalNumericUpDown.Value 
                .sCategory = ObjectComboBox.Text 
                .sCounter = CounterComboBox.Text 
                .sInstance = InstanceComboBox.Text 
                .machineName = MachineListComboBox.Text 
                .keepLooping = True 
     
            End With 
            Dim counterthread As New Threading.Thread(AddressOf Monitor.ConunterReaderThread) 
     
            counterthread.Start(perfmCounterStruct) 
     
        End Sub 
     
    the thread that im calling is in the monitor form class which is the MDi Child.

    and the following code is where I get the error. its the Thread procedure.
    Public Structure ControlTypeAndValue 
        Dim value As Single 
        Dim type As String 
        Dim ctrl As Control 
     
    End Structure 
    #Region "Counter Thread and Delegate" 
     
     
        Public Sub ConunterReaderThread(ByVal countersProperty As PerfCounter) 
            Dim pCounter As PerformanceCounter 
     
            Dim ctrlAndVal As ControlTypeAndValue 
            'Dim str As String = Me.Handle.ToString 
     
     
            With countersProperty 
                pCounter = New PerformanceCounter 
                pCounter.CategoryName = .sCategory 
                pCounter.CounterName = .sCounter 
                pCounter.InstanceName = .sInstance 
                pCounter.MachineName = .machineName 
                ctrlAndVal.type = .ctrlType 
                ctrlAndVal.ctrl = .ctrl 
            End With 
            pCounter.NextValue() 
     
            Do While countersProperty.keepLooping 
     
                ctrlAndVal.value = pCounter.NextValue 
                'CType(ctrlAndVal.ctrl, AquaControls.AquaGauge).Value = pCounter.NextValue 
     This is the Section Where i Recive the Error
                Invoke(New setValueHandler(AddressOf setValue), ctrlAndVal) 
                'Invoke(New setValueHandler(AddressOf setValue), pCounter.NextValue) 
            Loop 
     
     
        End Sub 
     
        Private Delegate Sub setValueHandler(ByVal ctrlAndVal As ControlTypeAndValue) 
        'Private Delegate Sub setValueHandler(ByVal ctrlAndVal As Single) 
        Private Sub setValue(ByVal ctrlAndVal As ControlTypeAndValue) 
            'Private Sub setValue(ByVal ctrlAndVal As Single) 
     
            If ctrlAndVal.type = "Aquagauge" Then 
                CType(ctrlAndVal.ctrl, AquaControls.AquaGauge).Value = ctrlAndVal.value 
     
            ElseIf ctrlAndVal.type = "Cylinder" Then 
            ElseIf ctrlAndVal.type = "TraceGraph" Then 
            ElseIf ctrlAndVal.type = "Led" Then 
            ElseIf ctrlAndVal.type = "Status Light" Then 
            End If 
     
     
     
        End Sub 
    #End Region 


    Any help Guys?
    i was thinking if the handle for the mdi child was not created but when i pull up me.hadle.tostring i can get the value for the monitor form class (mdi child)

    Thursday, March 5, 2009 4:31 PM

Answers

  • i added the thread procedure inside the parent Mdi and problem solved, but i don;t know why it was not working under MDI CHIld.
    • Marked as answer by OK24 Sunday, March 8, 2009 8:47 PM
    Sunday, March 8, 2009 8:47 PM

All replies

  • Any way that you can start the thread in the Load or Shown event of the Form?  That might be the most reasonable way to solve the problem.

    Accessing the handle property can force creation of the handle.  This suggest another (although in my opinion worse) potential fix.  That would be to perform a dummy access to the Handle property prior to calling Invoke.


    Thursday, March 5, 2009 11:36 PM
  • well that didn't help either
    Friday, March 6, 2009 4:45 PM
  • here is the Error detail


    this is the detail of error

    System.InvalidOperationException was unhandled
      Message="Invoke or BeginInvoke cannot be called on a control until the window handle has been created."
      Source="System.Windows.Forms"
      StackTrace:
           at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)    at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)    at CompCam.Monitor.ConunterReaderThread(PerfCounter countersProperty) in D:\Monitor\HealthMonitor\Forms\Monitor.vb:line 116    at CompCam.ControlProperties._Closure$__3._Lambda$__3(Object a0) in D:\Monitor\HealthMonitor\Forms\ControlProperties.vb:line 188    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)    at System.Threading.ExecutionContext.runTryCode(Object userData)    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)    at System.Threading.ThreadHelper.ThreadStart(Object obj)
      InnerException:



    Friday, March 6, 2009 10:18 PM
  • i added the thread procedure inside the parent Mdi and problem solved, but i don;t know why it was not working under MDI CHIld.
    • Marked as answer by OK24 Sunday, March 8, 2009 8:47 PM
    Sunday, March 8, 2009 8:47 PM