Vlastní webový prohlížeč se záložkami

Václav Bureš       20.01.2008       VB.NET, Komponenty, HTTP/HTML       16596 zobrazení

V dnešní době je web zdrojem nepřeberného množství informací. Avašak někdy může být díky neochotě webového prohlížeče problém se k nim dostat. Pokud tedy někdy zápasíte se svým prohlížečem, předkládám tu jednoduchý návod, jak postavit kostru vlastního...

V dnešní době je web zdrojem nepřeberného množství informací. Avašak někdy může být díky neochotě webového prohlížeče problém se k nim dostat. Pokud tedy někdy zápasíte se svým prohlížečem, předkládám tu jednoduchý návod, jak postavit kostru vlastního...

Nejprve je třeba se zamyslet nad návrhem projektu. Náš webový prohlížeč se bude skládat z hlavního okna, ve kterém se budou zobrazovat jednotlivé záložky, přičemž uživatel bude moci mezi těmito záložkami volně přepínat a aktivní záložku ovládat danými nástroji. K dosažení cíle nám poslouží technologie MDI (Multiple Document Interface). MDI známe například z MS Wordu, kde je jedno hlavní okno, které může obsahovat větší množství rovnocenných podružných oken, ve kterých se zobrazují jednotlivé dokumenty.

Vytvoření nového projektu

Spusťte Visual Studio .NET, nebo Visual Basic .NET a založte nový projekt (vpřípadě Studia založte projekt pro VB). V prohlížeči budeme potřebovat dva druhy oknen, vložíme si proto do projektu ještě jeden prázdný formulář. Dále, abychom mohli provázat dceřinná okna se záložkovými tlačítky v hlavním okně, budeme potřebovat třídu. Vložíme tedy ještě prázdný soubor pro třídu. Nemusím jistě zmiňovat, že je vhodné si projekt průběžně ukládat.

addItems

Návrh formulářů

V Solution Exploreru (standardně okno v pravém horním rohu) poklikejte na první formulář, který se pro nás stane hlavním oknem. Otevře se vám návrhové okno pro úpravu formuláře a vkládání prvků. Pokud označíte jakýkoli ovládací prvek, v okně vlastností (standardně v pravém dolním rohu) se zobrazí vlastnosti, které můžete nastavit. Změníme vlastnost Name na "Master". Tím jsme definovali jméno, pomocí kterého se budeme odkazovat na formulář. Dále ještě u formuláře nastavíme IsMdiContainer na TRUE, protože chceme, aby se tento formulář choval jako hlavní rodičovské okno. Nyní z Toolboxu přidáme jednotlivé ovládací prvky hlavního okna, ktaré budeme potřebovat.mnu

Jako první přidáme MenuStrip, který slouží pro vytvoření menu. Označíme kliknutím nový MenuStrip a jednotlivé položky menu intuitivně přidáváme tak, že do volné pozice, kde je napsáno "Type here", napíšeme text, který uživatel uvidí jako popisek položky menu. Pokud na již vytvořenou položku klikneme, můžeme do ní stejným způsobem vložit podmenu. Vytvořte tedy menu "Soubor", ve kterém budou potřebné příkazy "Nová záložka", "Zavřít záložku", "Zavřít všechny záložky" a "Konec", tak jak napovídá obrázek vpravo.

Dále budeme v hlavním okně potřebovat dva ToolStripy, vložte je tedy z Toolboxu do formuláře. Jeden bude sloužit jako lišta s tlačítky pro přepínání záložek a druhý jako panel nástrojů pro práci s aktivní záložkou. Jeden tedy označíme a z roletky na něm obzažené vložíme tlačítko. Po jeho označení je možné nastavovat vlastnosti, nastavte tedy popisek "Nová záložka". Stejným způsobem na druhém ToolStripu vytvořte ovládací prvky a nastavte popisky  podle následující ilustrace (v pořadí zleva: Button, Button, Label, TextBox, Button). Stejně jako s ToolStripem se pracuje se StatusStripem, který také jeden vložte (využijeme jej pro informaci o stavu načítání stránky) a naplňte jej prvky podle obrázku, nastavte vlastnosti (v pořadí zleva: StatusLabel, ProgressBar, StatusLabel). Vkládaným prvkům doproučuji nastavit rozumné názvy, aby byla následná orientace v kódu jednodušší.

frmMaster

Nyní přejdeme k návrhu záložkového formuláře. Po otevření v návrhovém prostředí ho pojmenujte "Slave" a vložte na něj WebBrowser.

Trocha nutné teorie ... :(

Kód záložkového formuláře bude nejjednodušší, proto s ním začneme. K editoru kódu se dostaneme tlačítkem v Solution Exploreru, nebo přez View>Code. Nyní budeme pracovat na návrhu třídy formuláře, dalo by se říci "šablony", podle které potom budeme vytvářet jednotlivé instance tohoto formuláře. Můžeme se tedy představit, že každý konkrétní formulář, který vytvoříme podle Slave, potom bude obsahovat stejné prvky, metody (Method), události (Event) i vlastnosti (Property).

Psaní kódu ... konečně :)

Záložkový formulář nebude zrovna vzkvétat vlastní inteligencí, tu za něho přebere jeho rodičovský objekt. V tomto formuláři vytvoříme pouze 4 veřejné (Public) sub-rutiny (Sub), které budeme volat, pokud budeme chtít, aby záložka provedla určitou činnost. V těch nebude nic jiného, než že budou předávat příkazy WebBrowseru. V případě rutiny "tabGoto" předáváme ještě adresu webu, který chceme zobrazit. Poslední částí kódu tohoto formuláře je událost jeho načtení "Slave_Load", která proběhne před prvním zobrazením formuláře. Její hlavičku nemusíme vypisovat, stačí z levé záložky nad oknem kódu vybrat "(Slave Events)" a v pravé událost "Load". Při této události záložku maximalizujeme a WebBrowseru poručíme jít na domovskou stránku. Tím je kód záložkového okna hotov:

'kod formulare Slave, ktery bude pouzit jako zalozky

Public Class Slave

    'aktivovani formulare
    Public Sub tabActivate(ByVal sender As Object, ByVal e As System.EventArgs)
        Me.Activate()
    End Sub

    'otevreni stranky
    Public Sub tabGoto(ByVal address As String)
        wb.Navigate(address)
    End Sub

    'historie zpet
    Public Sub tabBack()
        wb.GoBack()
    End Sub

    'historie vpred
    Public Sub tabForw()
        wb.GoForward()
    End Sub

    'pri otevreni nove zalozky ji maximalizujeme a prejdeme na domovskou stranku
    Private Sub Slave_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.WindowState = FormWindowState.Maximized
        wb.GoHome()
    End Sub

End Class

Nyní je třeba oživit hlavní okno. Nejdůležitější jsou pro nás dvě rutiny "tabAdd" a "tabRemove", které budou sloužit pro vytvoření respektive zavření záložky. Tyto následně budeme volat u událostí Click příslušných položek menu a tlačítek. Protože budeme za záložku považovat třídu, která za nás udělá všechnu práci, stačí v rutině pro novou záložku vytvořit novou instanci této třídy, která se o vše již postará. Protože naše třída bude chytrá, odchytí si, pokud uživatel zavře okno a kompletně se zruší. Proto tedy můžeme záložky zavírat například zavřením formuláře, jak je vidět z rutiny "tabRemove". Podobně funguje i událost, která nastane při kliknutí na položku menu "Zavřít všechny záložky", která projde kolekci MdiChildren hlavního formuláře a zavře všechny jeho podružné formuláře.

    'pridani nove zalozky
    Private Sub tabAdd()
        'vytvorime objekt nove zalozky podle tridy TWindow
        Dim newWindow As TWindow
        newWindow = New TWindow(Me)
    End Sub

    'odebrani zalozky
    Private Sub tabRemove()
        'pokud existuje aktivni zalozka, zavreme ji
        Try
            Me.ActiveMdiChild.Close()
        Catch
            MsgBox("Musíte mít otevřenou záložku")
        End Try
    End Sub

    'zavreni vsech zalozek
    Private Sub mnuCloseAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCloseAll.Click
        For Each tab As Form In Me.MdiChildren
            tab.Close()
        Next
    End Sub

Dále je třeba implementovat ovládání záložek. Díky tomu, že hlavní formulář má vlastnost ActiveMdiChild, která nás informuje o aktivním podružném okně, není problém na tomto okně zavolat rutiny, které jsme implementovali dříve. Tedy rutiny pro procházení historie a otevření webu na dané adrese. Abychom zvýšili uživatelský komfort, odchytíme událost KeyDown textového pole s adresou, a pokud uživatel stiskl enter, je to jako kdyby klikl na "GO".

    'v historii krok zpet
    Private Sub ToolBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolBack.Click
        'aktivni zalozce predame povel
        Try
            Dim actChild As Slave = Me.ActiveMdiChild
            actChild.tabBack()
        Catch
            MsgBox("Musíte mít otevřenou záložku")
        End Try
    End Sub

    'v historii krok dopredu
    Private Sub ToolForw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolForw.Click
        'aktivni zalozce predame povel
        Try
            Dim actChild As Slave = Me.ActiveMdiChild
            actChild.tabForw()
        Catch
            MsgBox("Musíte mít otevřenou záložku")
        End Try
    End Sub

    'presmerovani
    Private Sub ToolAdresaBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolAdresaBtn.Click
        Try
            'pokud zalozka existuje, predame ji adresu
            Dim actChild As Slave = Me.ActiveMdiChild
            actChild.tabGoto(Me.ToolAdresaTxt.Text)
        Catch
            'pokud zalozka neexistuje, vytvorime ji
            tabAdd()
            Dim actChild As Slave = Me.ActiveMdiChild
            actChild.tabGoto(Me.ToolAdresaTxt.Text)
        End Try
    End Sub

    'pohlidame, pokud v adresim radku uzivatel zadal enter,
    'je to totez, jako kdyby kliknul na "GO"
    Private Sub ToolAdresaTxt_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ToolAdresaTxt.KeyDown
        If e.KeyCode = Keys.Enter Then
            ToolAdresaBtn_Click(Me, System.EventArgs.Empty)
        End If
    End Sub

Poslední, co musí hlavní formulář umět je reakce na změny na záložkách. Konkrétně se jedná o změnu titulku okna  a změnu stavu načítání dokumentu. Tyto události za nás pohlídá záložková třída, ovšem musí exisovat rutiny, které se v tu chvíli provedou. Rutina "updateTitle" tedy nastaví titulek hlavního okna stejný, jaký má aktivní záložka a "updateProgress" se postará o to, aby se ve status-baru objevilo "Hotovo" v případě, že je dokument kompletní, případně progress-bar, který ukáže aktuální stav.

'nastaveni titulku okna
Public Sub updateTitle()
    Me.Text = Me.ActiveMdiChild.Text
End Sub

'zmena progresu
Public Sub updateProgress(ByVal progress As Single)
    If progress = 1 Then 'nacteno
        statusLoadProc.Visible = False
        statusLoadBar.Visible = False
        statusLoadTxt.Text = "Hotovo"
    Else 'stale se nacita, zobrazime procenta
        statusLoadTxt.Text = "Načítám:"
        statusLoadProc.Visible = True
        statusLoadBar.Visible = True
        statusLoadBar.Value = CInt(100 * progress)
    End If
End Sub

Třída TWindow

Nyní je čas naprogramovat již několikrát zmiňovanou třídu, která bude jádrem programu. Je tedy třeba otevřít soubor s kódem třídy a přejmenovat ho. Pokud jste dodržovali stejné názvy jako já v rutině pro tvorbu nové záložky, pojmenujte třídu "TWindow". Aby naše třída mohla udržet informace o tom, že k záložce kterou reprezentuje patří konkrétní tlačítko v liště a konkrétní formulář, je potřeba, aby si na ně udržovala reference. Třída tedy bude mít následující soukromé (Private) vlastnosti, které budou schraňovat tyto informace:

    'vnitrni reference na objekty
    Private myButton As ToolStripButton 'tlacitko v hlavnim formulari
    Private myMark As Slave 'formular zalozky
    Private myBrowser As WebBrowser 'webBrowser na formulari zalozky
    Private myMaster As Master 'rodicovske okno

Každá třída může obsahovat takzvaný konstruktor. Je to událost, která nastane, pokud z dané třídy vytvoříme instanci. Pokud tedy v našem prohlížeči necháme zobrazit novou záložku, vytvoří se nám instance této třídy a je třeba vykonat určité akce. Nejdříve si nastavíme referenci rodičovského okna, abychom jej mohli následně ovládat. Potom vytvoříme nový formulář a tlačítko hlavního panelu a taktéž si na ně uložíme reference, abychom s nimi mohli komunikovat. Naposled je ještě třeba přidat si kontrolování událostí, což se provede klíčovým slovem AddHandler, za kterým následuje událost, kterou chceme obsloužit a jméno procedury, pomocí které chcemu událost obsloužit.

    'konstruktor
    Public Sub New(ByVal myParent As Master)
        'ulozime si instanci rodicovskeho okna
        myMaster = myParent
        'vytvorime a zobrazime nove okno
        myMark = New Slave
        myMark.MdiParent = myMaster
        myMark.Show()
        'vytvorime a pridame tlacitko do zalozkove listy
        myButton = New ToolStripButton
        myMaster.toolTabs.Items.Add(myButton)
        'vytvorime odkaz na browser
        myBrowser = myMark.wb
        'pridame udalosti

        'pokud klikneme, aktivujeme dany form
        AddHandler myButton.Click, AddressOf myMark.tabActivate
        'pokud se formular zavira, znicime tlacitko
        AddHandler myMark.FormClosing, AddressOf Remove
        'pokud se zmenil titulek stranky
        AddHandler myBrowser.DocumentTitleChanged, AddressOf TitleChange
        'pokud se zmenil stav nacitani dokumentu
        AddHandler myBrowser.ProgressChanged, AddressOf ProgressChange
    End Sub

Všiměte si, prosím, že například v případě, kdy se uzavírá formulář (tedy uživatel zavře záložkové okno), zavolá se rutina Remove. Rutina remove tedy odebere tlačítko z lišty záložek a zruší reference. Obdobná situace nastává se změnou titulku a stavu dokumentu. Při změně titulku stránky je třeba nový titulek nastavit jako nadpisy oken a tlačítka reprezentujícího danou záložku, o což se stará rutina "TitleChange". Při změně progresu se vypočítá stav načítání dokumentu a pošle se do hlavního formuláře, kde je zobrazen ve status-baru.

    'zruseni zalozky
    Private Sub Remove(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
        'odebereme tlacitko z listy masteru a zrusime reference
        myMaster.toolTabs.Items.Remove(myButton)
        myButton = Nothing
        myMark = Nothing
    End Sub

    'zmena titulku
    Private Sub TitleChange(ByVal sender As Object, ByVal e As System.EventArgs)
        'zjistime novy titulek okna a rozdistribuujeme ho, kam je treba
        Dim text As String
        text = myMark.wb.DocumentTitle
        myMark.Text = text
        myButton.Text = text
        myMaster.updateTitle()
    End Sub

    'zmena progresu nacitani
    Private Sub ProgressChange(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserProgressChangedEventArgs)
        'spocitame progress a obnovime ho v hlavnim okne
        Dim progress As Single
        If myBrowser.IsBusy Then
            If e.MaximumProgress = 0 Then
                progress = 0
            Else
                progress = e.CurrentProgress / e.MaximumProgress
            End If
        Else
            progress = 1
        End If
        If progress > 1 Then progress = 1
        myMaster.updateProgress(progress)
    End Sub

Hotovo

Nyní již můžete vyzkoušet projekt spustit a zkusit pracovat s prohlížečem. Jistě objevíte mnoho neohrabaností svého výtvoru. Zkuste je tedy jako cvičení odstranit. Pokud nemáte žádné nápady na vylepšování, tak nějaké nabízím:

  • Aktualizace adresy v adresním řádku při přechodu na jinou stránku
  • Grafická reprezentace příkazových tlačítek
  • Nastavení vlastní domovské stránky
  • Místo adresního text-boxu combo-box, který si bude pamatovat zadané adresy
  • ...

Pokud chcete využít metod zpětného inženýrství, kompletní projekt je ke stažení zde.

Přeji mnoho zdaru...

 

hodnocení článku

2 bodů / 2 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Mohlo by vás také zajímat

Windows Presentation Foundation (WPF) - díl 10.: Návrh přihlašovacího formuláře - TextBox, PasswordBox, CheckBox a Label

Jak navrhnout jednoduchý přihlašovací formulář v technologii WPF. Zároveň popíši další čtyři ze základních komponent: TextBox, PasswordBox, CheckBox a Label.

Práce s časovými pásmy a letním časem v aplikaci a databázi - díl 1.: Úvod do časových pásem a letního času

Ve článku se snažím popsat úskalí, která přináší konverze času přes více časových pásem a pravidel pro počítání letního času.

Hledáme .NET vývojáře (Praha, Brno, Frýdek-Místek)

 

 

Nový příspěvek

 

Diskuse: Tak tady by mohl bejt nadpis

Zdravim vas udělal jsem také prohlížeč a potřeboval bych kod na to aby se mi po 3 sekundách zavřel dialog.Lze to?

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Tak tady by mohl bejt nadpis

ugg boots have<a href="http://www.uggboots7777.com">ugg</a> been<a href="http://www.uggboots7777.com">uggs</a> very popular among<a href="http://www.uggboots7777.com">uggs boots</a> people who love wearing these types of footwear. The boots are made<a href="http://www.uggboots7777.com/ugg-2010-new...">UGG JIMMY CHOO</a> out<a href="http://www.uggboots7777.com">discount uggs</a> of the<a href="http://www.uggboots7777.com">uggs

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Tak tady by mohl bejt nadpis

Zdravím. Nevím, jestli mi na to někdo ještě tady odpoví,ale alespoň se pokusím: když zapíšu

-Public Sub New(ByVal myParent As Master),vyjde mi chybová hláška:Error 2 Statement is not valid in a namespace.

plus

Private Sub ToolAdresaBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolAdresaBtn.Click

'aktivni zalozce predame povel

'pokud záložka existuje,předáme jí adresu

Try

Dim actChild As Slave = Me.ActiveMdiChild

actChild.tabGoTo(Me.ToolAdresaTxt.Text)

Catch

'pokud záložka neexistuje, vytvoříme ji

tabAdd()

Dim actChild As Slave = Me.ActiveMdiChild

actChild.tabGoTo(Me.ToolAdresaTxt.Text)

End Try

End Sub

Error 1 (u tabAdd) Property access must assign to the property or use its value.

Mohl by mi někdo poradit, kde dělám chybu?

Díky za odpověď

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

ahoj,

nevím jak tvůj problém vyřešit, ale rozhodně, a to zdůrazňuji! rozhodně tenhle příklad smaž a začni znovu. Používat try .. catch blok pro řízení toku programu je naprostá prasárna!

Pokud jsi začátečník, předpokládám, že jsi, zkus se zamyslet nad tím, jak celý tento problém napsat bez použítí catch bloku. Můžeš použít různé druhy kontrol na actChild a otestovat, jestli je objekt oukej. nespoléhat na vyjímku. ta je k vyjímečným věcem. Když ti tenhle zlozvyk zůstane, nebudeš dobrý programátor.

měj se hezky

nahlásit spamnahlásit spam -1 / 3 odpovědětodpovědět

Diskuse: Tak tady by mohl bejt nadpis

pekny clanek...

neda se nejak udelat ze kdyz kliknu na nejaky link zobrazi se mi dole vedle progressbaru adresa na kterou me ten text/obrazek odkazuje?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Tak tady by mohl bejt nadpis

Díky moc za tenhle článek. Je pro mne vážně přínosem.

nahlásit spamnahlásit spam 3 / 3 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback