Descrizione :
Un mio esempio pratico abbastanza completo basato sul Controllo WebBrowser.
+ Articolo :
Questo Articolo nasce da alcune discussioni su Forum Tecnici a cui ho partecipato con vari suggerimenti.
Ho deciso di riunire questi suggerimenti in qualcosa che avesse anche un minimo di "scopo pratico".
Inoltre le modifiche e aggiunte rispetto al codice originario sono parecchie.
Lo scopo è costruire una Windows Form basata sul WebBrowser che permetta la ricerca e il salvataggio veloce di immagini online, basandosi sul motore di Google Images.
Le immagini vengono cercate in base ad una o più Keywords e su Form sono presenti anche tutti i Controlli che servono a gestire le Keywords in modo ordinato.
Le immagini desiderate non vengono semplicemente salvate come thumbnails ( le stesse ottenute da Google ), ma il codice risale al link originale di ogni file e se possibile lo scarica alla fonte.
La selezione avviene con un menu contestuale.
Completa il tutto il salvataggio e caricamento delle Keywords usate in un file di testo.
La struttura dell'unica Form necessaria "FormMain" è semplice.
Tutte le proprietà sono assegnate via codice perciò non occorre alcuna particolare impostazione a Design.
I Controlli necessari sono :
--> Button : btn_salva
--> TextBox : txt_keywords
--> Button : btn_ok
--> CheckedListBox : chl_keywords
--> WebBrowser : wbr_google
La figura seguente rende bene l'idea della struttura e del funzionamento :
--> Codice FormMain :
Public Class FormMain Private percorso As String = Application.StartupPath & "\" Private cartellaAppunti As String = percorso Private cartellaImmaginiSalvate As New IO.DirectoryInfo(percorso & "ImmaginiSalvate\") Private nomeFileAppunti As String = "APPUNTI.txt" Private SelectedImageUrl As String Private urlGoogleImages As String = "http://www.google.com/images?&q=" Private keywords As New List(Of String) Private selectedKeywords As New List(Of String) 'Menu Contestuale Private WithEvents MenuImages As New System.Windows.Forms.ContextMenuStrip Private WithEvents ScaricaToolStripMenuItem As New System.Windows.Forms.ToolStripMenuItem Private Sub ListaKeywords() keywords.Sort() selectedKeywords.Sort() chl_keywords.Items.Clear() chl_keywords.Items.AddRange(keywords.ToArray) For Each kw As String In selectedKeywords If chl_keywords.Items.IndexOf(kw) > -1 Then chl_keywords.SetItemChecked(chl_keywords.Items.IndexOf(kw), True) Next End Sub Private Sub FormMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Impostazioni Controlli With ScaricaToolStripMenuItem .Name = "ScaricaToolStripMenuItem" .Text = "Scarica" End With With MenuImages .Items.AddRange(New System.Windows.Forms.ToolStripItem() {ScaricaToolStripMenuItem}) .Name = "MenuImages" End With With chl_keywords .Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left .CheckOnClick = True End With With wbr_google .Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right .IsWebBrowserContextMenuEnabled = False End With btn_ok.Anchor = AnchorStyles.Top Or AnchorStyles.Right txt_keywords.Anchor = AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Left 'File Appunti / Keywords If IO.File.Exists(cartellaAppunti & nomeFileAppunti) = False Then IO.File.Create(cartellaAppunti & nomeFileAppunti) keywords = IO.File.ReadAllLines(cartellaAppunti & nomeFileAppunti).ToList ListaKeywords() End Sub Private Sub btn_salva_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_salva.Click IO.File.WriteAllLines(cartellaAppunti & nomeFileAppunti, keywords) End Sub Private Sub btn_ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_ok.Click If txt_keywords.Text = "" Then MessageBox.Show("Immettere almeno una keyword di ricerca !") Exit Sub End If Dim txt As String = txt_keywords.Text selectedKeywords = txt.Split(" ").ToList 'Controllo correttezza keywords For i As Integer = selectedKeywords.Count - 1 To 0 Step -1 selectedKeywords(i) = selectedKeywords(i).Trim If selectedKeywords(i) = "" Then selectedKeywords.RemoveAt(i) 'Qui altri eventuali controlli sulle keywords... '... Next 'Confronto con le keywords già in lista su chl_keywords For Each kw As String In selectedKeywords If Not keywords.Contains(kw) Then keywords.Add(kw) Next ListaKeywords() txt = String.Join("+", selectedKeywords.ToArray) wbr_google.Navigate(urlGoogleImages & txt) End Sub Private Sub chl_keywords_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chl_keywords.SelectedIndexChanged With chl_keywords If .CheckedItems.Contains(.SelectedItem) Then If Not selectedKeywords.Contains(.SelectedItem) Then selectedKeywords.Add(.SelectedItem) Else selectedKeywords.Remove(.SelectedItem) End If End With txt_keywords.Text = String.Join(" ", selectedKeywords.ToArray) End Sub Private Sub GoogleHtmlElement_MouseUp(ByVal sender As Object, ByVal e As HtmlElementEventArgs) If e.MouseButtonsPressed = Windows.Forms.MouseButtons.Right Then Dim HE As HtmlElement = DirectCast(sender, HtmlElement).Parent Dim LinkMatch As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(HE.OuterHtml, "imgurl=(?<imgurl>.*?)&", _ System.Text.RegularExpressions.RegexOptions.IgnoreCase) If LinkMatch.Success Then SelectedImageUrl = LinkMatch.Groups("imgurl").Value MenuImages.Show(MousePosition) End If End If End Sub Private Sub ScaricaToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ScaricaToolStripMenuItem.Click Dim fileImmagine As System.IO.FileInfo Dim nomeImmagine As String Dim soggettoImmagine As String Dim soggettoRicerca As String = String.Join("+", selectedKeywords.ToArray) Dim contaImmaginiPerSoggetto As Integer For Each fileImmagine In cartellaImmaginiSalvate.GetFiles nomeImmagine = fileImmagine.Name soggettoImmagine = nomeImmagine.Split("_")(0) If soggettoImmagine = soggettoRicerca Then contaImmaginiPerSoggetto += 1 Next Dim numero As String = (contaImmaginiPerSoggetto + 1).ToString("00000") '00000 --> nomi da 00001 a 99999 Dim nomeFile As String = cartellaImmaginiSalvate.FullName & soggettoRicerca & "_" & numero & ".jpg" Dim immagineDaScaricare As New Net.WebClient Try immagineDaScaricare.DownloadFile(SelectedImageUrl, nomeFile) MessageBox.Show("Ok: Immagine Salvata " & nomeFile) Catch ex As Exception MessageBox.Show("Errore : Impossibile Salvare l'Immagine", "masterdrive", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Finally immagineDaScaricare.Dispose() End Try End Sub Private Sub wbr_google_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles wbr_google.DocumentCompleted Dim readyState As WebBrowserReadyState = DirectCast(sender, WebBrowser).ReadyState If readyState = WebBrowserReadyState.Complete Then If e.Url.Host = "www.google.it" Then For Each img As HtmlElement In wbr_google.Document.Images AddHandler img.MouseUp, AddressOf GoogleHtmlElement_MouseUp Next Else For Each img As HtmlElement In wbr_google.Document.Images AddHandler img.MouseUp, AddressOf GoogleHtmlElement_MouseUp Next End If End If End Sub End Class
La scelta delle Keywords viene fatta tipicamente dalla CheckedListBox, ma è anche possibile scrivere direttamente nella TextBox centrale.
Il programma verificherà l'inserimento di nuove Keywords e se caso le metterà in lista.
Pensa il codice, di volta in volta, a creare la giusta stringa da dare in pasto al browser nel caso di più Keywords :
Ho volutamente scritto alcuni spazi dei nomi per esteso per rendere più chiaro il percorso delle Classi .NET usate.
Inoltre parecchie impostazioni sono effettuate via codice e lo stesso menu contestuale è completamente creato e gestito via codice.
In uno scenario pratico, con i dovuti Imports ecc. il codice sarebbe più snello.
Ci sono inoltre vari spunti interessanti su cui focalizzare l'attenzione :
- Creazione e gestione di menu contestuale da codice ( no Design ).
- L'Evento DocumentCompleted() del WebBrowser e relativo uso del WebBrowserReadyState.
- L'estrazione dei link desiderati dal Document, grazie anche alle Regular Expression, e successivo download con Net.WebClient.
- Un valido sistema per comporre dinamicamente e progressivamente i nomi dei file salvati, ecc...
+ Fine Articolo.
5 commenti:
Fine article. I used this in my own app. :)
Maybe it could search other sites, like yahoo, bing, and so on...
I'll keep an eye on this blog. Bye. :)
In fact. My very first intention was to give support for more search engines, but that would have involved different html code handling for each one, 'cause every search engine gives its own results differently. By the way, EVERY ARTICLE on my Blog has not to be considered as "FINISHED" or "CLOSED" forever. Articles can grow, change, and get updates in time. Stay Tuned... ;-)
Funziona tutto, ma non riesco a scaricare l'immagine.. cliccando col tasto destro non compare l'opzione "Scarica".
Ciao, il codice è corretto. Non rilevo problemi. Vedi mia risposta su FB...
Sisi grazie, ho letto :)
Posta un commento