Oprettet tir. d. 06. september 2011 kl. 10:35:44

angelenglen
angelenglen (7.306 point. Point ude: 200)

Start form i ny thread

I min applikation har jeg en form (formExtra) udover min main-form (formMain).
Denne ekstra form ønsker jeg at åbne i en ny thread, men jeg kan ikke finde ud af hvordan jeg gør.

Det er vigtigt at jeg efterfølgende kan ændre fx baggrundsfarve på en label (Label1) i den ekstra form, fra min main-form.
Det er desuden vigtigt at jeg kan lukke formen igen, fra min main-form.

Af fejlbeskeder jeg har fået indtil nu er bl.a.:
"Starting a second message loop on a single thread is not a valid operation."
:-(

Skrevet tir. d. 06. september 2011 kl. 15:08:07| #1

arne_v
arne_v (1.016.169 point)
Du skal lave alt win form fra event traaden.

Skal du fra en anden traad lave noget GUI, saa brug Invoke til at faa det udfoert paa event traaden.

Skrevet tir. d. 06. september 2011 kl. 17:23:24| #2

angelenglen
angelenglen (7.306 point)
Jeg er lidt ny inden for threading, så jeg forstår ikke helt det du siger.

Har du evt. nogle hints til hvordan det gøres, sådan rent kodemæssigt?

Skrevet tir. d. 06. september 2011 kl. 17:41:42| #3

arne_v
arne_v (1.016.169 point)
Jeg lavede engang et simpelt klokke eksempel:

Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading

Public Class MainForm
    Inherits Form
    Private time As Label
    Private start As Button
    Private abort As Button
    Private t As Thread

    Public Sub New()
        time = New Label()
        start = New Button()
        abort = New Button()
        SuspendLayout()
        time.Location = New Point(50, 50)
        time.Size = New Size(300, 50)
        time.Font = New Font(FontFamily.GenericSerif, 16F)
        start.Location = New Point(50, 150)
        start.Size = New Size(200, 50)
        start.Name = "Start Button"
        start.Text = "Start clock"
        AddHandler start.Click, AddressOf StartClick
        abort.Location = New Point(50, 250)
        abort.Size = New Size(200, 50)
        abort.Name = "Abort Button"
        abort.Text = "Abort clock"
        AddHandler abort.Click, AddressOf AbortClick
        ClientSize = New Size(400, 350)
        Controls.Add(time)
        Controls.Add(start)
        Controls.Add(abort)
        Name = "Main Form"
        Text = "Main Form"
        ResumeLayout(False)
    End Sub
    Public Sub Run()
        While True
            If time.InvokeRequired Then
                time.Invoke(DirectCast(Sub() time.Text = DateTime.Now.ToString(), Action))
            Else
                Update()
            End If
            Thread.Sleep(1000)
        End While
    End Sub
    Public Sub StartClick(sender As Object, e As EventArgs)
        t = New Thread(AddressOf Run)
        t.Start()
    End Sub
    Public Sub AbortClick(sender As Object, e As EventArgs)
        t.Abort()
    End Sub
    <STAThread> _
    Public Shared Sub Main(args As String())
        Application.Run(New MainForm())
        Application.Exit()
        Environment.Exit(0)
    End Sub
End Class

Skrevet ons. d. 07. september 2011 kl. 10:27:18| #4

angelenglen
angelenglen (7.306 point)
har lige prøvet den, men får fejl i følgende linie:

time.Invoke(DirectCast(Sub() time.Text = DateTime.Now.ToString(), Action))

Too few type arguments to 'System.Action(Of T)'

Skrevet ons. d. 07. september 2011 kl. 11:08:38| #5

angelenglen
angelenglen (7.306 point)
Jeg prøvede at ændre din Run() sub til:

    Public Sub Run()
        While True
            If time.InvokeRequired Then
                time.Invoke(DirectCast(Sub()
                                          time.Text = DateTime.Now.ToString()
                                      End Sub, MethodInvoker))
            Else
                Update()
            End If
            Thread.Sleep(1000)
        End While
    End Sub

Umiddelbart får det programmet til at virke, men jeg kan ikke gennemskue hvordan jeg kan få det til at virke som jeg vil: åbne en form i en ny tråd, og kunne ændre indholdet i denne nye form efterfølgende.

Skrevet ons. d. 07. september 2011 kl. 13:34:13| #6

angelenglen
angelenglen (7.306 point)
Har lige leget lidt med det, tror jeg har fået det til at gøre som jeg vil nu :-)

Skrevet ons. d. 07. september 2011 kl. 14:50:08| #7

angelenglen
angelenglen (7.306 point)
hmm er stødt ind i problemer :-/


Hele projektet er at jeg har en browser i min mainform, denne browser viser skiftevis noget video, eller noget html-indhold.

Så vil jeg have en "ticker" eller "marquee" om man vil, til at køre hen over skærmen over videoen.

Det er denne "ticker" jeg skal have kørende i sin egen tråd, da browseren ellers sløver tickeren meget ned, så snart den laver noget intenst, som fx at vise video, animationer eller overgangs-effekter.

Umiddelbart er det lykkedes mig at få oprettet min form i en ny tåd, og få den til at indeholde min ticker.

Men jeg har lidt bøvl med efterfølgende at styre formens placering (tickeren skal kunne flyttes).
selve tickeren er en ScrollerMarquee som jeg fandt her:
http://www.vbforums.com/ (...)
den virker som sådan fint, og jeg kan sagtens ændre på selve ticker-objektets egenskaber såsom tekst og farve.
Det er selve formen jeg ikke kan flytte.

Når jeg forsøger at flytte formen, er der pludselig to af dem.
Én der indeholder min ticker, og en der ikke gør.

Her er lidt udsnit af min kode, håber det giver mening... jeg har ikke ryddet op i det, så noget er måske lidt irrelevant..
()


i min main-form har jeg:


Public Class frmMain
    Public TickerForm As Form
    Private TickerThread As Thread
    Public TickerScroller As ScrollingMarquee

    Public Sub InitializeTickerForm()
        doInitializeTickerForm(TickerForm, TickerScroller)
    End Sub

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Thread.Sleep(100) 'giv lige ticker-formen 0,1 sekundt til at initialisere, inden vi checker for InvokeRequired.

        If TickerForm.InvokeRequired Then
            TickerForm.Invoke(DirectCast(Sub()
                TickerForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
                                                  TickerForm.ShowInTaskbar = False
                                            'TickerForm.Visible = False
                                            End Sub, MethodInvoker))
        End if
End Sub




følgende funktioner har jeg liggende i et Module:


    Public Sub doInitializeTickerForm(ByRef TargetForm As Form, ByRef TargetScroller As ScrollingMarquee)
        Try
            TargetForm = New Form()
            TargetScroller = New ScrollingMarquee()
            TargetForm.SuspendLayout()
            TargetScroller.Parent = TickerForm
            TargetScroller.Dock = DockStyle.Fill
            TargetScroller.MarqueeText = "test"
            TargetScroller.ScrollSpeed = 1
            TargetForm.Controls.Add(TargetScroller)
            TargetForm.Location = New Point(0, 0)
            TargetForm.Size = New Size(1000, 150)
            TargetForm.ResumeLayout(False)
            TargetForm.Show()
            TargetForm.BringToFront()
            TargetForm.TopMost = True
            Application.Run(TargetForm)
        Catch ex As Exception

        End Try
    End Sub


Private TickerSettingsErrorCounter As Integer = 0 'anti-infinite-loop
    Public Sub ApplySettingsToTicker()
        If TickerSettings.ContainsKey("height") Then
            TickerSettingsErrorCounter = 0
            'settings er indlæst, brug dem:

            TickerForm.Size = New Size(frmMain.ClientSize.Width, TickerSettings("height"))
            If TickerSettings("placering") = "top" Then
                TickerForm.Location = New Point(0, 0)
            Else
                TickerForm.Location = New Point(0, frmMain.ClientSize.Height - TickerSettings("height"))
            End If
            frmMain.TickerScroller.Location = New Point(0, 0)
            frmMain.TickerScroller.Font = New Font(TickerSettings("fontfamily"), TickerSettings("fontsize"), FontStyle.Regular, GraphicsUnit.Pixel)
            frmMain.TickerScroller.BackColor = ColorTranslator.FromHtml(TickerSettings("backgroundcolor"))
            frmMain.TickerScroller.ForeColor = ColorTranslator.FromHtml(TickerSettings("fontcolor"))
            frmMain.TickerScroller.ScrollSpeed = TickerSettings("scrollspeed")
            Select Case TickerSettings("backgroundrepeat")
                Case "center"
                    frmMain.TickerScroller.BackgroundImageLayout = ImageLayout.Center
                Case "none"
                    frmMain.TickerScroller.BackgroundImageLayout = ImageLayout.None
                Case "stretch"
                    frmMain.TickerScroller.BackgroundImageLayout = ImageLayout.Stretch
                Case "tile"
                    frmMain.TickerScroller.BackgroundImageLayout = ImageLayout.Tile
                Case Else '"zoom"
                    frmMain.TickerScroller.BackgroundImageLayout = ImageLayout.Zoom
            End Select
            If File.Exists(TickerSettings("backgroundimage")) Then
                Try
                    frmMain.TickerScroller.BackgroundImage = Image.FromFile(TickerSettings("backgroundimage"))
                Catch ex As Exception
                    Logger.LogInfo(ex)
                End Try
            End If

        Else
            'settings er ikke indlæst, forsøg at læse dem og prøv igen.
            If TickerSettingsErrorCounter < 1 Then
                TickerSettingsErrorCounter = TickerSettingsErrorCounter + 1
                LoadTickerSettings()
                ApplySettingsToTicker()
            End If
        End If
    End Sub




    Private Sub ShowTicker(ByVal TickerDBID As Integer, ByVal TickerText As String, ByVal TickerRSS As String)
        'TickerRSS er ikke implementeret endnu...
        ApplySettingsToTicker()
        frmMain.TickerScroller.MarqueeText = TickerText
        If TickerForm.InvokeRequired Then
            TickerForm.Invoke(DirectCast(Sub()
                                            TickerForm.Tag = TickerDBID
                                            TickerForm.Visible = True
                                            TickerForm.BringToFront()
                                            TickerForm.TopMost = True
                                        End Sub, MethodInvoker))
        Else
            TickerForm.Update()
        End If
    End Sub






Den sidste ShowTicker() fyres af fra en timer, hvis visse betingelser er opfyldt.

Det er når den fyres af, at der pludselig er to forms.
Meget mystisk.

Skrevet tor. d. 08. september 2011 kl. 03:31:25| #8

arne_v
arne_v (1.016.169 point)
Var det ikke bedre med 1 form med 2 panels end 2 forms?

Skrevet tor. d. 08. september 2011 kl. 11:00:39| #9

angelenglen
angelenglen (7.306 point)
Nej, for formen med min ticker ligger oven på formen med browseren.

Desuden, ville jeg ikke have det samme problem med at tickeren bliver langsom, mens browseren arbejder?

Skrevet tor. d. 08. september 2011 kl. 14:53:40| #10

angelenglen
angelenglen (7.306 point)
Eller mener du at jeg kan oprette to paneler, smide browseren i den ene, og tickeren i den anden.
- og så flytte panel nummer to, til at ligge oven på en del af det første panel, så tickeren vises oven på browseren?

Jeg har bare svært ved at forestille mig at det ændrer på at browseren sløver tickeren, når browseren laver noget, fx viser video... - for de vil jo stadig køre i samme tråd, eller?

Skrevet fre. d. 09. september 2011 kl. 15:29:51| #11

angelenglen
angelenglen (7.306 point)
Damn, har nu prøvet i flere dage, og kan bare ikke få det til at virke :-/

Kan det virkelig passe at det er så svært at åbne en ny form i en ny tråd?
Ligemeget hvad jeg har prøvet indtil nu, bliver min tickers hastighed påvirket at krævende aktiviteter i browseren på min mainform :-(

Skrevet tor. d. 06. oktober 2011 kl. 13:11:10| #12

angelenglen
angelenglen (7.306 point)
Er blevet truet til at lukke mine spørgsmål, så accepterer bare denne, selvom jeg ikke har nået at teste det :-/

Skrevet tor. d. 06. oktober 2011 kl. 16:47:36| #13

arne_v
arne_v (1.016.169 point)
Det er godt at faa spoergsmaal afsluttet paa en god maade. Det er ikke godt bare at lukke.

Hvem har truet dig?

Skriv et indlæg




Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] [img]link til billede[/img]
Web- og emailadresser omdannes automatisk til links

Log ind

   

   

Seneste spørgsmål

visual basic 2010

Oprettet den 22. maj 2012 kl. 12.29
omer1345 giver 30 point for svar | Giv et svar »

GridView med fast linkbillede, der fører til et...

Oprettet den 21. maj 2012 kl. 15.27
neesgaard giver 100 point for svar | Giv et svar »

VCard på ASP.NET overført til Outlook´s kontaktpersoner

Oprettet den 20. maj 2012 kl. 18.45
per2edb giver 200 point for svar | Giv et svar »



   




Tips & Tricks fra PC World

Teaser billede

Læserne: Her er vores værste it-indkøb

Det er ikke al it-udstyr, som er det rene guld. Her er nogle af læsernes skrækhistorier.


Anmeldelser fra PC World

Teaser billede

Test: Mobil med Ferrari-design - og en Trabant-motor

Motorola har begået endnu en smartphone med lækkert design og potentiale til at være blandt de bedste. Men den når ikke i mål. Se her hvorfor.


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Sådan siger du farvel til Facebook

Læs her, hvordan du dropper Facebook og i stedet anvender nogle brugervenlige alternativer, så du stadig kan være social på nettet.


Nyheder fra Computerworld

Teaser billede

Galleri: De fedeste håndholdte gennem 40 år

Her har du de mest banebrydende håndholdte computere gennem alle tider.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger