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 ClassLa 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.



19:12
MarcoGG



Posted in:
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