none
Refresh TextBox e ListBox RRS feed

  • Domanda

  • Salve a tutti, ho creato un programmo in visual basic che copia una stringa dal browser Firefox e successivamente la incolla su di una TextBox.
    Questo procedimento continua a farlo fino a che la stringa non corrisponde ad una stringa predefinita, e quando sono uguali continuo ad andare avanti, se sono diverse, le aggiunge su di una ListBox.

    Funziona tutto a meraviglia, tuttavia quando incollo la stringa sulla TextBox e la aggiungo alla lista, non me le fa vedere in tempo reale.

    Le mostra solamente quando il programma termina, cioè quando le 2 stringhe sono uguali, come posso risolvere?

    Grazie in anticipo!

    domenica 12 agosto 2012 01:42

Risposte

  • Ciao Vesco,
    probabilmente il codice che esegui lo stai eseguendo all'interno del thread
    principale della tua applicazione.
    Così facendo, stai bloccando la coda dei messggi di Windows e, qualsiasi
    cosa tu faccia in un controllo (come, ad esempio, aggiungere un elemento
    alla lista), non viene gestito se non nel momento in cui termina il tuo codice
    (motivo per cui ti fa vedere il tutto alla fine del programma).
    Il tuo lavoro di ricerca dovrebbe essere fatto in un thread separato in modo
    da lasciare libera l'interfaccia.
     
     
    • Proposto come risposta Ruggiero Lovreglio domenica 12 agosto 2012 10:38
    • Contrassegnato come risposta Irina Turcu giovedì 6 settembre 2012 15:37
    domenica 12 agosto 2012 10:03
    Moderatore
  • Ciao Vesco,
    puoi utilizzare la classe Task che è adatta a questo scopo (puoi trovare
    Alla pressione del tasto, crei un nuovo task che esegue esattamente il codice
    che stai eseguendo ora ma lo fa in un thread separato.
    Unica cosa che devi tenere presente è che ti troverai in un thread che non
    è quello in cui i controlli sono stati creati. Le applicazioni .NET sono
    STA (Single Thread Apartment), quindi, non potrai direttamente modificare
    i controlli stessi (la lista, ad esempio).
    Se sei in Windows Form (per favore dicci in che tecnologia stai sviluppando),
    puoi utilizzare diverse strade. Una di queste è l'utilizzo di InvokeRequired
    e Invoke() come mostrato in questi due link:
     
    in generale ti basta cercare "cross threading operation controls vb.net"
    su un motore di ricerca per trovare soluzioni.
     
    Per WPF, invece, devi usare il dispatcher (anche qui se cerchi "Dispatcher
    WPF" trovi quello che cerchi).
     
     
    • Contrassegnato come risposta Irina Turcu giovedì 6 settembre 2012 15:37
    domenica 12 agosto 2012 14:53
    Moderatore

Tutte le risposte

  • Ciao,

    non è molto chiaro quello che vuoi realizzare. Potresti spiegare meglio? magari sarebbe tutto più semplice se spiegassi a cosa dovrebbe servire l'applicazione che stai creando.

    Un saluto


    Ruggiero Lovreglio
    www.lovreglio.tk

    domenica 12 agosto 2012 02:07
  • L'applicazione è  non fa altro che prendere una determinata stringa selezionandola con 3 click del mouse, e copiandola(tasto destro copia) successivamente la incolla su di una textbox1 ( textbox1.text=clipboard.paste() ), poi la confronta con una stringa su di un'altra textbox2: se sono uguali si ferma, se sono diverse va avanti a fare altre cose, e la aggiunge su una listbox.

    Il problema è che quando la incolla sulla textbox1, o la aggiunge sulla lista, non riesco a vederla.

    La vedo solamente quando il programma termina, cioè quando le due stringhe sono ugual


    domenica 12 agosto 2012 02:38
  • Ciao,

    prova a postare il codice così è possibile vedere se ci sono problemi nella strutturazione dei codici.


    Ruggiero Lovreglio
    www.lovreglio.tk

    domenica 12 agosto 2012 09:12
  • Ciao Vesco,
    probabilmente il codice che esegui lo stai eseguendo all'interno del thread
    principale della tua applicazione.
    Così facendo, stai bloccando la coda dei messggi di Windows e, qualsiasi
    cosa tu faccia in un controllo (come, ad esempio, aggiungere un elemento
    alla lista), non viene gestito se non nel momento in cui termina il tuo codice
    (motivo per cui ti fa vedere il tutto alla fine del programma).
    Il tuo lavoro di ricerca dovrebbe essere fatto in un thread separato in modo
    da lasciare libera l'interfaccia.
     
     
    • Proposto come risposta Ruggiero Lovreglio domenica 12 agosto 2012 10:38
    • Contrassegnato come risposta Irina Turcu giovedì 6 settembre 2012 15:37
    domenica 12 agosto 2012 10:03
    Moderatore
  • Ok, dunque se fosse questo il problema la ricerca dovrei effettuarla su di un nuovo thread, qualche consiglio su come potrei farla? Visto che la ricerca viene effettuata in seguito alla pressione di un pulsante?
    domenica 12 agosto 2012 11:06
  • Ciao Vesco,
    puoi utilizzare la classe Task che è adatta a questo scopo (puoi trovare
    Alla pressione del tasto, crei un nuovo task che esegue esattamente il codice
    che stai eseguendo ora ma lo fa in un thread separato.
    Unica cosa che devi tenere presente è che ti troverai in un thread che non
    è quello in cui i controlli sono stati creati. Le applicazioni .NET sono
    STA (Single Thread Apartment), quindi, non potrai direttamente modificare
    i controlli stessi (la lista, ad esempio).
    Se sei in Windows Form (per favore dicci in che tecnologia stai sviluppando),
    puoi utilizzare diverse strade. Una di queste è l'utilizzo di InvokeRequired
    e Invoke() come mostrato in questi due link:
     
    in generale ti basta cercare "cross threading operation controls vb.net"
    su un motore di ricerca per trovare soluzioni.
     
    Per WPF, invece, devi usare il dispatcher (anche qui se cerchi "Dispatcher
    WPF" trovi quello che cerchi).
     
     
    • Contrassegnato come risposta Irina Turcu giovedì 6 settembre 2012 15:37
    domenica 12 agosto 2012 14:53
    Moderatore
  • Se posso dirti la verità è che non c'ho capito molto dei link che mi hai mandato, anche perchè sono veramente alle prime armi con questo linguaggio.

    Da quel che ho capito è che devo far eseguire la procedura  Button1_Click ad un altro thread, cioè nella funzione Private Sub Button1_Click devo creare un nuovo tread, posto il codice per aiutarvi nell'aiutarmi :)

    Public Class Form1
        Declare Function mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dX As Int32, ByVal dY As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32) As Boolean
        Const MOUSEEVENTF_MOVE As Int32 = &H1 ' mouse move
        Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2 ' left button down
        Const MOUSEEVENTF_LEFTUP As Int32 = &H4 ' left button up
        Const MOUSEEVENTF_RIGHTDOWN As Int32 = &H8 ' right button down
        Const MOUSEEVENTF_RIGHTUP As Int32 = &H10 ' right button up
        Const MOUSEEVENTF_MIDDLEDOWN As Int32 = &H20 ' middle button down
        Const MOUSEEVENTF_MIDDLEUP As Int32 = &H40 ' middle button up
        Const MOUSEEVENTF_ABSOLUTE As Int32 = &H8000 ' absolute move
        Const MOUSEEVENTF_WHEEL As Int32 = &H800 ' wheel button rolled
    
        Dim str1 As String
        Dim str2 As String
        Dim trovato = False
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            System.Threading.Thread.Sleep(1000)
            TextBox1.Clear()
        End Sub
    
        Sub PremiSx() 'left click
            mouse_event(&H2, 0, 0, 0, 0)
            mouse_event(&H4, 0, 0, 0, 0)
        End Sub
    
        Sub PremiDx() 'right click
            mouse_event(&H8, 0, 0, 0, 0)
            mouse_event(&H10, 0, 0, 0, 0)
        End Sub
    
        Private Sub SpostaClickaSx(ByVal X As Integer, ByVal Y As Integer)
            Dim p As New Point(X, Y)
            Cursor.Position = (p)
            System.Threading.Thread.Sleep(1000)
            PremiSx()
        End Sub
    
        Private Sub SpostaClickaDx(ByVal X As Integer, ByVal Y As Integer)
            Dim p As New Point(X, Y)
            Cursor.Position = (p)
            System.Threading.Thread.Sleep(1000)
            PremiDx()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            TextBox1.Clear()
            Dim i As Integer
            SpostaClickaSx(1489, 666) 'mission
            For i = 0 To 3 'chapter 1
                SpostaClickaSx(1071, 592) 'left arrov
            Next i
            SpostaClickaSx(1035, 276) '"Viper"
            SpostaClickaSx(1032, 361) 'start mission
            For i = 0 To 2
                SpostaClickaSx(1529, 507) 'three times click
            Next i
            SpostaClickaSx(872, 603) 'click on Leethax
            SpostaClickaSx(1223, 488) 'click on preview
    
            Dim p2 As New Point(1222, 448)
            Cursor.Position = p2
            PremiSx()
            PremiSx()
            PremiSx()
            SpostaClickaDx(1222, 448)
            SpostaClickaSx(1287, 481)
            'copied string
    
            SpostaClickaSx(1226, 473) 'ok
            SpostaClickaSx(1219, 563) 'close
    
            System.Threading.Thread.Sleep(2000)
    
            TextBox1.Text = Clipboard.GetText
            'paste into textbox
    
            str1 = TextBox1.Text
            str2 = TextBox2.Text
    
            ListBox1.Items.Add(str1)
    
            If StrComp(str1, str2) = 0 Then
                trovato = True
                MsgBox("Ho trovato queelo che cercavi, cioè: " & TextBox2.Text)
            Else
                SpostaClickaSx(1489, 666) 'ponte di volo
                SpostaClickaSx(1489, 666) 'mission
                SpostaClickaSx(1035, 393) 'abort mission
                SpostaClickaSx(1165, 419)
                SpostaClickaSx(1489, 666) 'ponte di volo
                Call Button1_Click(sender, e)
            End If
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
        End Sub
    
    
        Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
            Close()
        End Sub
    End Class

    domenica 12 agosto 2012 22:07
  • Ciao Vesco,
    cosa è che non ti è chiaro?
    L'utilizzo dei task, il perchè devi usare un thread diverso o l'utilizzo
    dell'invoke?
    Proprio perchè sei alle prime armi e, se hai la volontà di imparare a programmare,
    ti consiglio di studiare un pò gli argomenti.
    Per quanto riguarda i task, puoi anche fare riferimento a MSDn (cisono anche
    degli esempi) semplicemente cercando "Task MSDN".
    In sostanza devi prendere il codice che hai nel button click e farlo eseguire
    da un task.
     
     
    lunedì 13 agosto 2012 05:36
    Moderatore
  • Ok, grazie ci proverò!
    lunedì 13 agosto 2012 12:58
  • Ok, io ho provato a lavorarci su, modificando il sorgente in questa maniera:

    Imports System.Threading.Tasks
    Imports System.Threading
    
    Public Class Form1
        Declare Function mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dX As Int32, ByVal dY As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32) As Boolean
        Const MOUSEEVENTF_MOVE As Int32 = &H1 ' mouse move
        Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2 ' left button down
        Const MOUSEEVENTF_LEFTUP As Int32 = &H4 ' left button up
        Const MOUSEEVENTF_RIGHTDOWN As Int32 = &H8 ' right button down
        Const MOUSEEVENTF_RIGHTUP As Int32 = &H10 ' right button up
        Const MOUSEEVENTF_MIDDLEDOWN As Int32 = &H20 ' middle button down
        Const MOUSEEVENTF_MIDDLEUP As Int32 = &H40 ' middle button up
        Const MOUSEEVENTF_ABSOLUTE As Int32 = &H8000 ' absolute move
        Const MOUSEEVENTF_WHEEL As Int32 = &H800 ' wheel button rolled
        Dim str1 As String
        Dim str2 As String
        Dim trovato = False
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            System.Threading.Thread.Sleep(1000)
            TextBox1.Clear()
        End Sub
    
        Sub PremiSx() 'left click
            mouse_event(&H2, 0, 0, 0, 0)
            mouse_event(&H4, 0, 0, 0, 0)
        End Sub
    
        Sub PremiDx() 'right click
            mouse_event(&H8, 0, 0, 0, 0)
            mouse_event(&H10, 0, 0, 0, 0)
        End Sub
    
        Private Sub SpostaClickaSx(ByVal X As Integer, ByVal Y As Integer)
            Dim p As New Point(X, Y)
            Cursor.Position = (p)
            System.Threading.Thread.Sleep(1000)
            PremiSx()
        End Sub
    
        Private Sub SpostaClickaDx(ByVal X As Integer, ByVal Y As Integer)
            Dim p As New Point(X, Y)
            Cursor.Position = (p)
            System.Threading.Thread.Sleep(1000)
            PremiDx()
        End Sub
    
    
        Private Strt As System.Threading.Thread
    
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Strt = New System.Threading.Thread(AddressOf MyThread1)
            Strt.Start()
        End Sub
        Sub MyThread1()
            'TextBox1.Clear()
            Dim i As Integer
            SpostaClickaSx(1489, 666) 'mission
            For i = 0 To 3 'chapter 1
                SpostaClickaSx(1071, 592) 'left arrov
            Next i
            SpostaClickaSx(1035, 276) '"Viper"
            SpostaClickaSx(1032, 361) 'start mission
            For i = 0 To 2
                SpostaClickaSx(1529, 507) 'three times click
            Next i
            SpostaClickaSx(872, 603) 'click on Leethax
            SpostaClickaSx(1223, 488) 'click on preview
    
            Dim p2 As New Point(1222, 448)
            Cursor.Position = p2
            PremiSx()
            PremiSx()
            PremiSx()
            SpostaClickaDx(1222, 448)
            SpostaClickaSx(1287, 481) 'copied string
    
            SpostaClickaSx(1226, 473) 'ok
            SpostaClickaSx(1219, 563) 'close
    
            TextBox1.Text = Clipboard.GetText 'paste into textbox
    
            str1 = TextBox1.Text
            str2 = TextBox2.Text
            AccessControl()
            ' ListBox1.Items.Add(str1)
    
            If StrComp(str1, str2) = 0 Then
                trovato = True
                MsgBox("Ho trovato queelo che cercavi, cioè: " & TextBox2.Text)
            Else
                SpostaClickaSx(1489, 666) 'ponte di volo
                SpostaClickaSx(1489, 666) 'mission
                SpostaClickaSx(1035, 393) 'abort mission
                SpostaClickaSx(1165, 419)
                SpostaClickaSx(1489, 666) 'ponte di volo
                'Call Button1_Click(sender, e)
            End If
    
        End Sub
    
    
        Private Sub AccessControl()
            If Me.InvokeRequired Then
                Me.Invoke(New MethodInvoker(AddressOf AccessControl))
            Else
    
                ListBox1.Items.Add(str1)
                TextBox1.Clear()
            End If
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
        End Sub
    
        Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
            Close()
        End Sub
    End Class

    Ma ora il problema è che quando cerco di inserire la stringa vedo che nella listbox si formano linee vuote, e controllando il valore di str1 in fase di debug ho scoperto che è nullo e dandomi questo errore:"per valutare la funzione è necessario che tutti i thread siano in esecuzione"

    martedì 14 agosto 2012 17:37
  • Non è un buon metodo multithread quello che hai scritto perché utilizza str1
    attributo della form all'interno del thread.
     
    Cosa succederebbe se venissero eseguiti due thread contemporanei? Avresti
    l'accesso in scrittura/lettura di due thread in una stessa variabile che
    non è buono.
     
    Non vedo perché l'hai utilizzata quando il metodo AccessControl potrebbe
    prevedere dei parametri (la stringa stessa).
     
     
    martedì 14 agosto 2012 18:55
    Moderatore
  • Okok credo di aver risolto, vorrei avere un parere vostro, per sapere se la soluzione apportata è corretta:
      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim task = New Threading.Tasks.Task(New Action(AddressOf ricerca))
            task.Start()
        End Sub
    
        Private Sub ricerca()
            If InvokeRequired Then
                Me.Invoke(New MethodInvoker(AddressOf ricerca))
            Else
                TextBox1.Clear()
                Dim i As Integer
                SpostaClickaSx(1489, 666) 'mission
                For i = 0 To 3 'chapter 1
                    SpostaClickaSx(1071, 592) 'left arrov
                Next i
                SpostaClickaSx(1035, 276) '"Viper"
                SpostaClickaSx(1032, 361) 'start mission
                For i = 0 To 2
                    SpostaClickaSx(1529, 507) 'three times click
                Next i
                SpostaClickaSx(872, 603) 'click on Leethax
                SpostaClickaSx(1223, 488) 'click on preview
    
                Dim p2 As New Point(1222, 448)
                Cursor.Position = p2
                PremiSx()
                PremiSx()
                PremiSx()
                SpostaClickaDx(1222, 448)
                SpostaClickaSx(1287, 481) 'copied string
    
                SpostaClickaSx(1226, 473) 'ok
                SpostaClickaSx(1219, 563) 'close
    
                TextBox1.Text = Clipboard.GetText 'paste into textbox
    
                str1 = TextBox1.Text
                str2 = TextBox2.Text
    
                ListBox1.Items.Add(str1)
    
                If StrComp(str1, str2) = 0 Then
                    trovato = True
                    MsgBox("Ho trovato queelo che cercavi, cioè: " & TextBox2.Text)
                Else
                    SpostaClickaSx(1489, 666) 'ponte di volo
                    SpostaClickaSx(1489, 666) 'mission
                    SpostaClickaSx(1035, 393) 'abort mission
                    SpostaClickaSx(1165, 419)
                    SpostaClickaSx(1489, 666) 'ponte di volo
                    'Call Button1_Click(sender, e)
                End If
    
            End If
        End Sub

    mercoledì 15 agosto 2012 16:27
  • Ciao Vesco,
    in questo modo stai eseguendo tutto il codice nel thread principale (come
    Il metodo Invoke altro non fa che richiamare il delegate come se ti trovassi
    nel thread principale.
    Se guardi su MSDN () le possibili firme del metodo Invoke, vedrai che ne
    esiste una che permette il passaggio di uno o più parametri (http://msdn.microsoft.com/it-it/library/a1hetckb).
    Ti basta definire il metodo che aggiorna la lista con un parametro stringa
    ed utilizzare la firma opportuna
     
    Tra le altre cose, nell'esempio riportato proprio nel link su MSDN, si parla
    di una listbox.
     
     
    mercoledì 15 agosto 2012 16:52
    Moderatore
  • Ciao Vesco,

    per favore potresti, se hai risolto, chiudere il thread marcando la risposta corretta.

    In questo modo chi cercherà soluzioni a problemi analoghi al tuo saprà che il thread è chiuso

    martedì 28 agosto 2012 13:19
    Moderatore
  • Ciao Vesco,

    Ho evidenziato le risposte che hai ricevuto da Massimo, al pensiero che possano servire come un riferimento utile per altri membri che magari si sono imbattuti in un caso simile. Se vuoi riaprire la discussione dopo aver provato quanto suggerito/ consigliato, facci sapere che ostacoli stai ancora incontrando.

    Saluti,


    Irina Turcu - Microsoft

    [Manifesto] Regole e Aspetti generali all'uso dei forum MSDN

    Questo contenuto è distribuito “as is” e non implica alcuna responsabilità da parte di Microsoft. L'azienda offre questo servizio gratuitamente, allo scopo di aiutare gli utenti e approfondire la loro conoscenza dei prodotti e tecnologie Microsoft.

    LinkedIn

    giovedì 6 settembre 2012 15:41