vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Sch?tzen Sie Ihre Software vor Software-Piraterie - mit sevLock 1.0 DLL!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2017
 
zurück
Rubrik: Internet/Netzwerk   |   VB-Versionen: VB5, VB615.03.05
IE Toolbar in VB selbst erstellen

Mit diesem Workshop möchten wir zeigen, wie man sich seine eigene Toolbar für die Integration im Microsoft Internet Explorer erstellen kann. Der Workshop bezieht sich hierbei auf die bereits vor längrere Zeit vorgestellte vb@rchiv Toolbar.

Autor:  Ralf SchoenBewertung:     [ Jetzt bewerten ]Views:  31.441 

Mit diesem Workshop möchten wir zeigen, wie man sich seine eigene Toolbar für die Integration im Microsoft Internet Explorer erstellen kann. Der Workshop bezieht sich hierbei auf die bereits vor längrere Zeit vorgestellte vb@rchiv Toolbar.

Wie wohl schon lange von erwartet, hier der Workshop zur vb@rchiv Toolbar.

In diesem Workshop gehe ich nur noch ganz kurz auf die Erstellung von Type Lib´s ein. Dazu habe ich bereits einen Workshop geschrieben, der das Grundprinzip zur Erstellung solcher Type Lib´s zeigt. Des Weiteren muss hier jedem klar sein, das dieser Workshop sich nicht an Anfänger richtet. Klar, mit dem Code wird wohl jeder in der Lage sein, seine eigene Toolbar zu schreiben, doch stellt euch das auch nicht so einfach vor. Es gibt noch einige Hürden die man überwinden muss, damit auch noch andere Sachen funktionieren. Daher gebe ich jedem den Tipp, sich wirklich mit dem Thema auseinander zu setzen, wenn er tatsächlich eine eigene Toolbar schreiben möchte.

Los geht's:

Was brauchen wir? Wir benötigen erst einmal eine ActiveX-DLL, die verschiedene Schnittstellen zu implementieren hat. Diese Schnittstellen sind in der vbArchivWS.tlb deklariert. Der Source von dieser TLB befindet sich in der Datei vbArchivWS.odl. Binden Sie über Verweise die vbArchivWS.tlb ein. Nun stehen Ihnen die Schnittstellen zur Verfügung und es kann los gehen.

Folgende Schnittstellen werden benötigt:

Implements IDeskBand
Implements IObjectWithSite
Implements ISubclass

Viele fragen sich, wie und wo man anfangen sollte. Wenn man sich mal zu Gemüte führt, wie solche Band Objects (aha, die Dinger heißen BandObjects funktionieren, dann weiß man ganz schnell wo es losgehen muss. Wenn ein Band Objects in einem Explorer geladen wird, dann wird ein so genannter "site pointer" an das Band Objects übergeben und wenn man diesen dann dazu benutzt um an das IWEBBrowser2 Interface zu kommen, dann steht einer Kommunikation mit dem IE nix mehr im Wege. Dadurch stehen uns alle IE - Events und das komplette DOM zur Verfügung. Dieser "site pointer" ist vom Type IUknown.

Um dies zu tun haben wir das Interface IObjectWithSite eingebunden. Dieses Interface stellt uns zwei Methoden zur Verfügung. GetSite und SetSite.

SetSite wird aufgerufen wenn eine Instance vom IE geladen wird und hier bekommen wir dann den "site pointer" übergeben.

Private Sub IObjectWithSite_SetSite(ByVal pUnkSite As stdole.IUnknown)

pUnkSite ist unser "site pointer"

Wenn wir nun diesen "site pointer" dafür verwenden um das IWebBrowser2 Interface zu bekommen, dann haben wir die Instance vom IE. Dies tun wir nun über das Interface IServiceProvider. Über dieses Interface können wir uns die Instance besorgen ... Weitere Infos gibt es hier: ( http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iserviceprovider/iserviceprovider.asp)

IServiceProvider hat nur eine Methode: QueryService. Dieser übergeben wir die GUID, die wir uns vorher noch über CLSIDFromStirng besorgen und bekommen dann unsere Instance zurück. In unserem Fall sind der angeforderte Service (guidService) und das Interface (riid) das selbe.

Public Function getInstanceIE(ByVal BandSite As vbArchivToolbar.IServiceProvider) As IWebBrowserApp
  Dim GUID As vbArchivToolbar.GUID
 
  Const IIDSTR_IWebBrowserApp = "{0002DF05-0000-0000-C000-000000000046}"
 
  ' Konvertierung von IID und SID
  CLSIDFromString IIDSTR_IWebBrowserApp, GUID
 
  ' nun über QueryService den Internet Explorer holen
  BandSite.QueryService GUID, GUID, getInstanceIE
End Function

GetSite gibt uns das zurück was mit SetSite gesetzt wurde. Das einzige was wir hier machen müssen ist, den Rückgabewert von QueryInterface zurückzugeben. Und an QueryInterface geben wir einfach die Parameter weiter, die wir von GetSite bekommen haben. QueryInterface? Wo kommt das denn jetzt schon wieder her? In GetSite speichern wir uns den "site pointer" und nun haben wir das Interface IUnknown welches die QueryInterface bereitstellt.

Private Sub IObjectWithSite_GetSite(priid As vbArchivToolbar.GUID, ppvObj As stdole.IUnknown)
  Dim result As Long
 
  result = m_BandObject.QueryInterface(priid, ppvObj)
  If result Then Err.Raise result
End Sub

Wenn dies alles erledigt ist, dann können wir unsere Toolbar erstellen. Bis jetzt hat das Ganze ja noch nicht so viel mit der Toolbar zu tun, oder?

Hier jetzt der komplette Source von SetSite:

Wie man jetzt auch sieht, speichere ich am Anfang den "site pointer", hole die Instance vom IE und frmToolbar.Init (m_InternetExplorer, ME). Nun, wir möchten ja gerne ein paar DropDown-Buttons haben und dafür brauchen wir auch ein Menu. Warum also nicht einfach auf eine Form ein Menu und darin alles handeln? Durch die Übergabe von m_InternetExplorer kann man dann ganz bequem auf die Klick-Ereignisse des Menüs reagieren. Z.B. m_InternetExplorer.Navigate "www.vbArchiv.net".

Private Sub IObjectWithSite_SetSite(ByVal pSite As vbArchivToolbar.IUnknownVB)
  On Error Resume Next
 
  ' Das übergebene Site Objekt speichern
  Set m_BandObject = pSite
 
  If Not m_BandObject Is Nothing Then
    ' Instance vom Internet Explorer holen
    Set m_InternetExplorer = getInstanceIE(m_BandObject)
 
    Call frmToolbar.Init(m_InternetExplorer, Me)
    ' Toolbar erstellen
    CreateToolbar
  Else
    Set m_InternetExplorer = Nothing
  End If
End Sub

Die Toolbar

Dann kommt die CreateToolbar- Funktion. In dieser Funktion erstellen wir erstmal ein Window, welches unsere Messages aufnehmen soll.

m_lMessageWindow = CreateWindowEx(0, "#32770", vbNullString, _
  0, 0, 0, 0, 0, HWND_MESSAGE, 0, App.hInstance, ByVal 0&)

Wir erstellen ein "Message only Window" weiter brauchen wir ja nix, aber nicht vergessen, das Handle des Fenster zu behalten .... Infos hierzu gibt es wie immer hier ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowfeatures.asp)

Dann erstellen wir unsere Toolbar ...
( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/toolbar/functions/createtoolbarex.asp)

m_lToolbarWindow = CreateToolbarEx(m_lMessageWindow, WS_CHILD Or WS_VISIBLE Or _
  CCS_NODIVIDER Or CCS_NORESIZE Or _
  TBSTYLE_LIST Or TBSTYLE_TOOLTIPS Or TBSTYLE_FLAT Or TBSTYLE_TRANSPARENT, _
  0, 2, 0, 0, Ttb, 0, 16, 16, 16, 16, LenB(Ttb))

Diese Funktion erklärt sich eigentlich von selbst , was hier zu beachten ist: dass wir den Type TBButton haben müssen und diesen halt übergeben .. Einfach mit Dim Ttb As TBButton deklarieren und gut ist.

Der Type TBButton ist auch nix besonderes wie man sieht.

Public Type TBButton
  iBitmap As Long
  idCommand As Long
  fsState As Byte
  fsStyle As Byte
  bReserved(0 To 1) As Byte
  dwData As Long
  iString As Long
End Type

Wenn man DropDown Buttons in seiner Toolbar haben möchte, dann muss man noch folgende Message an die Toolbar senden. Damit ist jetzt sichergestellt, das wir auch DropDown´s anzeigen können.

SendMessageLong m_lToolbarWindow, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS

Dann noch die Init von meiner cTBButton Klasse aufrufen, um das Handle des ToolbarWindow zu übergeben.

Toolbar-Icons
Jetzt aber erst einmal die Icons für die Toolbar vorbereiten. Ich habe alle Icons in einer Ressourcen-Datei gespeichert und nun werden sie der Toolbar übergeben ...

Call TBButton.AddToolbarIcons(App.hInstance

Hier wird zuerst eine ImageList erstellt und dann die Bilder in diese geladen.

lImgList = ImageList_Create(16, 16, ILC_COLOR8 Or ILC_MASK, 8, 0) ' gezählt bei 0
 
' Load the icon
lIcon = LoadIcon(App.hInstance, 1&)
ImageList_ReplaceIcon lImgList, -1, lIcon

Das Ganze nun für alle Bilder und dann die ImageList an die Toolbar übergeben.

SendMessage m_ToolBarWindow, TB_SETIMAGELIST, ByVal 0, ByVal lImgList

Toolbar-Buttons
Jeder Button braucht eine eindeutige ID, Text , Style, State, ImageID und einen Tooltip. Ich habe im Modul modDef die ID´s und die Texte festgelegt. Da ich die ID´s auch später noch brauche, habe ich mich für diese Variante entschieden und nicht direkt in den Aufruf eingetragen.

Call TBButton.AddToolbarButtons(IDvbArchiv, sButtonVbArchiv, CTBDropDown Or BTNS_AUTOSIZE, _
  TBSTATE_ENABLED, 0, "vb@rchiv - Die Welt der VB Programmierung")
 
Call TBButton.AddSepButton(10)

In der Funktion AddToolbarButtons wird dann ein Array gefüllt wo ich mir für später die ToolTips merke:

ReDim Preserve TBTT(iCountButton - 1)
TBTT(iCountButton - 1).ToolTipText = ""
TBTT(iCountButton - 1).idButton = -1

Des Weiteren fülle ich dann die TBButton Struktur:

tTButton.idCommand = idCommand
tTButton.iString = StrPtr(sString)
tTButton.fsStyle = fsStyle
tTButton.fsState = fsState
tTButton.iBitmap = iBitmap

Dann müssen wir uns auch noch die größte idCommand merken, brauchen wir für später. Und wieder an die Toolbar schicken.

SendMessage m_ToolBarWindow, TB_ADDBUTTONSW, 1, tTButton

Um einen Separator zu erzeugen, müssen wir nicht die komplette Struktur füllen.

tTButton.fsStyle = BTNS_SEP
tTButton.iBitmap = Size

Die Größe des Separators wird in iBitmap übergeben und dann auch wieder an die Toolbar gesendet.

Dann wird noch das Subclassing aktiviert, auf das ich hier aber nicht weiter eingehen werde. Dazu gibt es ja auch schon einen Workshop im vb@rchiv.

IDeskband
Nun kommen wir zum Interface IDeskband. IDeskband hat eigentlich nur eine Methode: GetBandInfo. Da aber IDeskband von IDockingWindow und dieses wieder von IOleWindow abgeleitet ist, haben wir hier 6 Methoden:

IOleWindow
  GetWindow 
  ContextSensitiveHelp
 
IDockingWindow 
  ShowDW
  CloseDW
  ResizeBorderDW
 
IDeskband
  GetBandInfo

Kurze Erläuterung zu den Methoden:

IOleWindowGetWindowübergeben wir unser ToolbarWindow Handle
 ContextSensitiveHelp   nicht implementiert
 
IDockingWindow   ShowDWsind wir sichtbar oder aktiv ?
 CloseDWhier rufen wir DestroyToolbar auf und aus ist es mit unserer Toolbar
 ResizeBorderDWnicht implementiert
 
IDeskbandGetBandInfoInformationen über das Band Info besorgen

Alle mit "nicht implementiert" müssen einen Aufruf von Err.Raise E_NOTIMPL beinhalten. Damit klar ist, dass wir es nicht implementiert haben.

In ShowDW bekommen wir mit, ob wir sichtbar sind oder nicht. Darauf reagieren wir natürlich auch entsprechend.

If fShow Then
  ShowWindow m_lToolbarWindow, SW_SHOWNOACTIVATE
Else
  ShowWindow m_lToolbarWindow, SW_HIDE
End If

Nun kommt GetBandInfo, hier werden einige Einstellungen für die Toolbar abgefragt, die angefordert werden. Folgende Werte können angefordert werden:

DBIM_MINSIZEMinimalgröße wird angefordert
DBIM_MAXSIZEMaximalgröße wird angefordert
DBIM_INTEGRALWie viele Schritte sollen aufgezogen werden? Nur aktiv wenn dwModeFlags DBIMF_VARIABLEHEIGHT beinhaltet
DBIM_ACTUALDie Ideal Größe , nicht garantiert
DBIM_TITLETitle von der Toolbar
DBIM_MODEFLAGSDBIMF_NORMALNormales Band Objekt
 DBIMF_VARIABLEHEIGHT   höhenverstellbar
 DBIMF_DEBOSSEDToolbar wird mit einem "sunken" Border gezeichnet
 DBIMF_BKCOLORHintergrundfarbe kann geändert werden.
DBIM_BKCOLORHintergrundfarbe der Toolbar. Nur aktiv wenn dwModeFlags DBIMF_BKColor beinhaltet

BUTTONKLICK:
So, nun haben wir alle Interfaces durch die wir brauchen und wie man sieht ist es gar nicht so viel. Nur wenn man nicht weiß wie und was man alles braucht, ist es schon eine hartes Stück Arbeit.

Natürlich sind wir noch nicht am Ende. Wir haben zwar jetzt die ganzen Interfaces gefüllt und die Toolbar mit den Buttons erstellt, doch wie sieht es nun aus mit der Abfrage und der Kommunikation mit der Site?

Ok, dazu schauen wir mal in die ISubclass_WindowProc.

Ich bin hier nicht näher auf das Subclassing eingegangen und werde es auch nicht tun, doch hier in der WindowProc läuft natürlich schon einiges ab, was wir unbedingt brauchen. Hier komme ich jetzt auch auf die Tooltips zu sprechen. Ich habe das Ganze in einige Funktionen gekapselt, die ich aber nicht immer ganz erklären werde, sondern nur kurz anspreche, weil sie eigentlich nix besonders machen.

Wir fangen nur zwei Messages ab und zwar die WM_COMMAND und die WM_NOTIFY. Im WM_COMMAND passiert auch nicht gerade viel, hier wird sich über den wParam das LOWORD geholt und dann überprüft, ob es die idCommand unseres Buttons ist. Wenn ja, dann ButtonClicked aufrufen.

Select Case wParam \ &H10000
  Case Is < &H100
    If wParam >= 100 And wParam <= TBButton.getMaxButton Then
      ButtonClicked wParam
      Handled = True
    End If
End Select

Hier brauchen wir dann auch wieder unsere getMaxButton, die ich vorhin mal kurz angesprochen hatte.

In der ButtonClicked-Sub gibt es eine Select Anweisung, die dann die entsprechende Aktion durchführt. Die Menüs selber werden in der Form gehandelt. Wie ich am Anfang schon einmal gesagt hatte, benutze ich das VB-Menu für die DropDowns.

Im WM_NOTIFY passiert schon etwas mehr. Als erstes holen wir und die NMHDR Struktur über CopyMemory. Dann schauen wir nach, ob TBN_DROPDOWN oder TTN_NEEDTEXT ausgelöst wurde.

Wenn TBN_DROPDOWN dann noch checken ob es auch unser Fenster war, welches die Infos braucht. Wenn ja, dann die ToolbarInfo Struktur holen und die DropDown aufrufen, in der dann das Menu angezeigt wird. Der DropDown übergeben wir einmal die realID (so habe ich die ID genannt) und einmal die idCommand, die wir selbst vergeben haben. In der DopDown selbst wird dann die genaue Position geholt, wo das Menu angezeigt werden soll. Über GetDropDownPosition und mit der Übergabe der realID bekommen wir dann unsere Position zurück. Und zwar über

Call SendMessage(m_lToolbarWindow, TB_GETITEMRECT, ID, udtrect)

holen wir uns das Rechteck des Buttons. Danach über ClientRectToScreen noch umwandeln und schon haben wir unsere Position. Dann noch den Button-State ändern und MenuAnzeigen. Beim Anzeigen des Menüs greife ich auf eine Funktion Namens GetVBSubmenu zurück. Diese holt mir das richtige Menü, das angezeigt werden soll.

Anschließend wieder den State des Buttons anpassen und das war´s dann mit dem DropDown-Menü. Die Auswertung der Menüs findet in der frmToolbar statt. Darauf brauche ich wohl nicht mehr einzugehen .

SONSTIGES

Es gibt noch eine Funktion die ich nicht benutzt habe. Mit EnableToolbarButton kann man einen Button deaktivieren. Hier einfach unsere idCommand und den Status angeben und schon erscheint er inaktiv oder wieder aktiv. Der Aufruf, der dahinter steckt, sieht wie folgt aus:

SendMessageLong m_lToolbarWindow, TB_PRESSBUTTON, idButton, fstate

Dann gibt es noch die ChangeButtonText. Mit dieser Funktion ist es möglich einen Text von einem vorhandenen Button zu ändern. Hier wird auch die idCommand von unserem Button übergeben und der neue Text. Zuerst wird der Text ein wenig konvertiert und dann in die Struktur ToolbarButtonInfo geschrieben. Hier ist es dann wichtig darauf zu achten, dass der Text als Pointer übergeben wird.

tbi.pszText = StrPtr(sChangeText)

Der eigentliche Funktionsaufruf sieht dann wie folgt aus:

Call SendMessage(m_lToolbarWindow, TB_SETBUTTONINFO, idButton, tbi)

Über ChangeButtonImage kann man einem Button ein anderes Icon zuweisen. Ich denke mal, dass hier allen klar ist, wie das geht. Die idCommand und eben die neue Resourcen ID des Bildes übergeben.

Nun sind wir auch schon am Ende dieses Workshops. Was den meisten wohl in diesem Workshop fehlt, ist die Einbindung einer ComboBox und evtl. das richtige Hervorheben von Suchbegriffen, oder das automatische Update. Doch ich bin der Meinung, dass es für den Anfang reichen sollte. Ich werde aber die Erstellung einer ComboBox und das Hervorheben von Suchbegriffen an einer anderen Stelle beschreiben. Es ist auch nicht ganz so einfach. Klar, das Hervorheben ist nicht das Problem , aber die ComboBox (oder mehrere) und deren Verhalten in einer Toolbar. Daher habe ich entschieden euch dieses erst später zu erklären.

Installation der Toolbar:
Vielleicht noch ein paar Worte zur Installation der Toolbar. In der Datei install.reg findet Ihr alles was man dazu braucht um die Toolbar zu registrieren.

Hier die komplette Datei...

REGEDIT4
 
[HKEY_CLASSES_ROOT\CLSID\{19E4CADB-18F6-4533-8A25-CB9854DD0DA0}]
@ = "vbArchiv Workshop"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Toolbar]
"{19E4CADB-18F6-4533-8A25-CB9854DD0DA0}"="vbArchiv Workshop"

BITTE DARAUF ACHTEN, DASS IHR DIE KOMPATIBILITÄT DER DLL UNTERBRECHT.
Sonst wird es bald einige Toolbars geben, die sich dann gegenseitig überschreiben Wenn ihr also eine neue Toolbar schreibt, dann holt euch die neue CLSID und tragt diese in beide Schlüssel ein. Den Schlüssel bekommt ihr heraus, wenn man in der REG z.B. nach vbArchivWS.Toolbar sucht. Also Projektname + Klassenname und dann ist das die AppID. Klar, den Namen sollte man dann auch noch ändern. Das wäre aber dann schon alles um die Toolbar in den IE einzubinden.

Vielleicht noch was in eigener Sache. Dieser Workshop ist nicht dafür geschrieben worden um kommerzielle Toolbars zu schreiben. Dieses möchte ich nicht. Des weiteren wäre es nur fair, wie es auch schon in den Foren angesprochen wurde, wenn man einen Hinweis in den Info Dialog reinbringt, wo ihr die Infos her habt. Da ist es mir egal ob ihr nur das vb@rchiv erwähnt oder meine Person, das ist euch überlassen.

Dann bleibt mir nur noch euch viel Spaß damit zu wünschen und stellt damit keinen Blödsinn an

Ralf
 

Dieser Workshop wurde bereits 31.441 mal aufgerufen.

Über diesen Workshop im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Workshop, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2017 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel