Entwickler-Ecke

Delphi Tutorials - Einen Browser erstellen


Arakis - Mi 12.06.02 14:33
Titel: Einen Browser erstellen
Hallo, in diesen Tutorial möchte ich euch zeigen, wie man in Dephi ganz einfach einen Browser erstellt. Ist im Prinzip recht simpel, die einzigste Schwierigkeit besteht darin, den Aufruf eines neuesn Browserfensters abzufangen und die neue Seite im eigenen Browser zu behalten. Ich habe mich hier für eine TabSheet-Browser entschieden.

Wir benötigen
- 2 Buttons
- 1 Edit
- und ein Pagecontrol ohne Tabsheets draf.

Zusätzlich müssen die Units OleCtrls und SHDocVw eingebunden werden.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, OleCtrls, SHDocVw;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    PageControl1: TPageControl;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
procedure NewWindow(Sender: TObject;var ppDisp: IDispatch; var Cancel: WordBool);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



Mit dem Klick auf den ersten Button soll ein neues Tabsheet mit einer Browserkomponente erstellt werden:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure TForm1.Button1Click(Sender: TObject);
var
  NewTab : TTabSheet;  //variable, die unser neues Tabsheet seinwird
  NewWeb : TWebBrowser;//auf dem tabsheet wird dann diesesbrowserfenster liegen, beide werden zur laufzeit erzeugt
begin
  //TabSheet erstellen
  NewTab:= TTabSheet.Create(Form1.PageControl1);
  //TabSheet ist sichtbar
  NewTab.Visible := True;
  //Beschriftung übergeben
  NewTab.Caption := 'Neue Seite';
  //TabSheet an das PageControl übergeben
  NewTab.PageControl := Form1.PageControl1;
  //Aktive Seite des PageControls auf das gearde erstellt TabSheetsetzen
  Form1.PageControl1.ActivePage:= NewTab;
  //neues Browser Objekt erstellen
  NewWeb:=TWebBrowser.Create(NewTab);
  //Browser Objekt an das TabSheet übergeben
  TWinControl(NewWeb).parent := NewTab;
  //Browser Ausrichtung festlegen
  NewWeb.Align:= alClient;
  //ggf. weitere Ereignisse für das neue WebBrowser Objektfestlegen
  NewWeb.OnNewWindow2:= NewWindow;
  //WebBrowser sichtbar
  NewWeb.Visible := True;
end;


Damit der frisch erstellte TWebbrowser auch eine Seite anzuzeigen hat, proggen wir eben kurz den zweiten Button:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button2Click(Sender: TObject);
begin
  (PageControl1.ActivePage.Controls[0as TWebBrowser).Navigate(Edit1.Text);
end;


Die Zeile sieht ein wenig kompliziert aus, aber letzt endlich wird damit einfach die Brower-Komponente angesprochen. Die Methode Navigate() ist dafür zuständig, das jetzt gesuft wird.

Jetzt das schwierigste(wenn man es weiß natürlch nicht mehr):
Wenn z.B. ein PopUp-Fenster geöffnet wird, soll nicht ein Microsoft Internet-Explorer starten, sondern es soll ein neuer Tabsheet mit neuen Browser angelget werden. Dafür ist die Methode NewWindow() zuständig. Leider gibt uns diese Methode keine Auskunft darüber, welche URL aufgerufen wurde. Dies ist kein Bug von Borland, sondern Microsoft verheimlicht dieses. Die werden ihre Gründe haben...
Über einen Trick geht es aber trotzdem:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.NewWindow(Sender: TObject;var ppDisp: IDispatch; var Cancel: WordBool);
var
  Tabsheet: TTabsheet;
  Browser: TWebBrowser;
begin
  //Neues TabSheet mit WebBrowser erstellen
  Form1.Button1Click(nil);
  //Aktives TabSheet finden
  TabSheet:= Form1.PageControl1.ActivePage;
  //Anfrage umleiten (neue seite im neuen webbrowserdentseranzeigen)
  ppDisp:= (PageControl1.ActivePage.Controls[0as TWebBrowser).DefaultInterface;
end;

Mit Button1Click(nil) wird ein neuer Tabsheet erstellt, die nächste Zeile macht dieses zu aktiven Seite. Der wichtigste Befehl ist hier der letzte.

Damit das Programm direkt beim starten auch schon was zu tun bekommt, emulieren wir hier den Button1- und 2-Klick. Vorraussetzung ist natürlich, dass im Editfeld standartmäßig eine URL eingetragen ist.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.FormActivate(Sender: TObject);
begin
  Form1.Button1Click(nil);
  Form1.Button2Click(nil);
end;

end.


Fertig ist der Browser. Kleiner Tipp: mit Shift und gleichzeitigem Klicken auf einen Link versucht der Internet-Explorer immer, den Link im neuen Fenster zu öffnen.

Für die, die keine Lust am puzzeln haben, gibt es das oben genannte Beispiel als ZIP-Datei:
http://dateien.desk-work.de/delphi/tutorials/tabsheetbrowser1.zip 3,21 KB

Falls jemand Fragen hat, der kann die gerne posten.

Nachtrag: Vielen dank an Highbam aus dem alten DF, dieses Beispiel hatte ich noch aus seiner FAQ :wink:

Ein weiterer Teil folgt in Kürze :P

Bis dann
user defined image


CB - Fr 14.06.02 09:00

Du solltest vielleicht noch erwähnen, dass das natürlich kein eigenständiger Browser ist, sondern die TWebBrowser Komponente nur per ActiveX ein Internet Explorer Fenster in die eigene Applikation einbindet.
D.h., dass der Benutzer auf jedenfall die Version 3.0 oder höher des IEs installiert haben muss. Des weiteren hängt es von den IE Einstellungen ab, ob z.B. JavaScripts, etc. ausgeführt werden oder nicht.


Chatfix - So 22.09.02 14:48

wenn mein browser eine seite mit einem formular aufruft kann ich kein enter in enem memo-feld drücken, also es passiert kein zeilen umbruch wenn ich drücke.. woran kann das liegen?


Arakis - So 22.09.02 14:53

Hi Chatfix user defined image,

dazu musst du folgenden Code am ende des Quelltextes einfügen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
{...}

initialization
  OleInitialize(nil);

finalization
  OleUninitialize;

end.


Bis dann
user defined image


Chatfix - So 22.09.02 14:56

das habe ich schon es geht trotzdem nicht.... ich habe diese zeien eingefügt damit z.B. Copy usw geht, aber enter kann ich trotzdem nciht drücken...


Cyberbob - Sa 19.10.02 13:19

hmm... diese Unit hier : SHDocVw

die wird nciht gefunden beim compilieren. Wo finde ich die bzw, muss ich die runterladen?? (hab Delphi 6, die version aus dem i-net)


Arakis - Sa 19.10.02 14:48

Chatfix hat folgendes geschrieben:
das habe ich schon es geht trotzdem nicht.... ich habe diese zeien eingefügt damit z.B. Copy usw geht, aber enter kann ich trotzdem nciht drücken...


Die Enter-Taste zu aktivieren ist ein bisschen komplizierter, darum hab ich es weggelassen. Außerdem kapier ich den Quelltext dazu nämlich nicht. Aber so wie in diesem Beispiel sollte ein TWebbrowser mit Enter funzen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
unit Unit1; 

interface 

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, OleCtrls, SHDocVw_TLB, ActiveX, StdCtrls; 

type 
  TForm1 = class(TForm) 
    WebBrowser1: TWebBrowser; 
    Button1: TButton; 
    Button2: TButton; 
    procedure FormDestroy(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
  private 
    { Private declarations } 
    FOleInPlaceActiveObject: IOleInPlaceActiveObject; 
    procedure MsgHandler(var Msg: TMsg; var Handled: Boolean); 
  public 
    { Public declarations } 
  end; 

var 
  Form1: TForm1; 


implementation 

{$R *.dfm} 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  FOleInPlaceActiveObject := nil; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  Application.OnMessage := MsgHandler; 
end; 

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean); 
var 
  iOIPAO: IOleInPlaceActiveObject; 
  Dispatch: IDispatch; 
begin 
  { exit if we don't get back a webbrowser object } 
  if (WebBrowser1 = nil) then 
  begin 
    Handled := False; 
    Exit; 
  end; 

  Handled := (IsDialogMessage(WebBrowser1.Handle, Msg) = True); 

  if (Handled) and (not WebBrowser1.Busy) then 
  begin 
    if FOleInPlaceActiveObject = nil then 
    begin 
      Dispatch := WebBrowser1.Application; 
      if Dispatch <> nil then 
      begin 
        Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO); 
        if iOIPAO <> nil then 
          FOleInPlaceActiveObject := iOIPAO; 
      end; 
    end; 

    if FOleInPlaceActiveObject <> nil then 
      if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and 
        ((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then 
        //nothing - do not pass on Backspace, Left or Right arrows 
      else 
        FOleInPlaceActiveObject.TranslateAccelerator(Msg); 
  end; 
end;

Die Originalquelle dazu findet sich unter http://www.swissdelphicenter.ch/de/showcode.php?id=1055

Bis dann
user defined image


Tomekk - Do 20.02.03 18:00
Titel: html quelltext
Ja dieses unglaubliche Activex dings ist schon toll! :D
Aber ist es möglich den Quelltext der aufgerufenen html seite im Programm zu benutzen? so als wenn man im IE rechts klickt und dann auf quelltext geht? Ich hab schon alles mögliche Versucht z.B. gettextbuf und gettextlen (wobei ich immer noch nicht weiß wofür das gut ist) aber ich habs einfach nicht hingekriegt! Hab auch schon im Internet nach einer Beschreibung der einzelnen Funktionen der Komponente gesucht aber nichts gefunden! Wäre net wenn ihr mir weiterhelfen könntet!


Arakis - Do 20.02.03 18:22

Das geht recht einfach. Ich hab grad leider nur Delphi 6 Personal zur Hand, kann also nix selber ausprobieren. TWebBrowser.Document hat das Interface IHTMLDocument2 implementiert, was dir zugriff auf sämtliche HTML-Elemente gibt. Auch den HTML-Quelltext:

Quelltext
1:
(WebBrowser.Document as IHTMLDocument2).innerHTML                    


Dazu musst du aber erst glaub ich die Unit mshtml einbinden(geht nicht bei der Delphi Personal-Version).

Hier zwei recht hilfreiche Seiten:
http://www.dataweb.de/articles/mshtmlediting/mshtmlediting.html (Designmode des IE)

http://www.euromind.com/iedelphi/ (Ein muss für jeden TWebBroser-Nutzer)

Bis dann
user defined image


Tomekk - Fr 21.02.03 08:32

Na toll! Wo soll ich als kleiner armer Schüler den jetzt delphi professional herkriegen? Trotzdem danke für den hilfe! Kann man nicht vieleicht die mshtml.dll direkt benutzen?


hibbert - Mo 18.08.03 22:40

Cyberbob hat folgendes geschrieben:
hmm... diese Unit hier : SHDocVw

die wird nciht gefunden beim compilieren. Wo finde ich die bzw, muss ich die runterladen ?? (hab Delphi 6, die version aus dem i-net)

Cyverb :twisted: b

hmm, ich habe auch das gleiche Problem, und ich konnte es leider auch nicht lösen, also schließe ich mich Cyberbob an.

Hibbert


Roy - Fr 23.05.14 20:44

Wie kann ich einen Tab schließen


trm - Fr 23.05.14 22:51

Hi Roy, das Datum hast Du aber schon gesehen von dem Tutorial?

Um den aktiven Tab zu schließen, mach einen neuen Button auf die Form und in den Event schreibst Du dann rein:


Delphi-Quelltext
1:
pagecontrol1.activepage.free;