Il componente TWebBrowser Delphi fornisce l'accesso alla funzionalità del browser Web dalle applicazioni Delphi.
Nella maggior parte dei casi si utilizza TWebBrowser per visualizzare documenti HTML all'utente, creando così la propria versione del browser Web (Internet Explorer). Si noti che TWebBrowser può anche visualizzare documenti Word, ad esempio.
Una caratteristica molto utile di un browser è la visualizzazione delle informazioni sui collegamenti, ad esempio, nella barra di stato, quando il mouse passa sopra un collegamento in un documento.
TWebBrowser non espone un evento come "OnMouseMove". Anche se un evento del genere esistesse, verrebbe generato per il componente TWebBrowser - NON per il documento visualizzato all'interno di TWebBrowser.
Per fornire tali informazioni (e molto altro, come vedrai tra poco) nell'applicazione Delphi utilizzando il componente TWebBrowser, una tecnica chiamata "affondamento degli eventi"deve essere implementato.
Per accedere a una pagina Web utilizzando il componente TWebBrowser, si chiama Navigare metodo. Il Documento la proprietà di TWebBrowser restituisce un IHTMLDocument2 valore (per documenti web). Questa interfaccia viene utilizzata per recuperare informazioni su un documento, esaminare e modificare gli elementi HTML e il testo all'interno del documento ed elaborare gli eventi correlati.
Per ottenere l'attributo "href" (link) di un tag "a" all'interno di un documento, mentre il mouse passa sopra un documento, è necessario reagire all'evento "onmousemove" di IHTMLDocument2.
Ecco i passaggi per affondare gli eventi per il documento attualmente caricato:
Dato che siamo interessati all'attributo HREF di un elemento A - al fine di mostrare l'URL di un link su cui si trova il mouse, affonderemo l'evento "onmousemove".
La procedura per ottenere il tag (e i suoi attributi) "sotto" il mouse può essere definita come:
var htmlDoc: IHTMLDocument2; ... procedura TForm1.Document_OnMouseOver; var elemento: IHTMLElement; inizio Se htmlDoc = zero poi Uscita; element: = htmlDoc.parentWindow.event.srcElement; elementInfo.Clear; Se LowerCase (element.tagName) = 'a' allora inizio ShowMessage ('Link, HREF:' + element.getAttribute ('href', 0)]); fine altro Se LowerCase (element.tagName) = 'img' poi inizio ShowMessage ('IMAGE, SRC:' + element.getAttribute ('src', 0)]); fine altro inizio elementInfo.Lines.Add (Format ('TAG:% s', [element.tagName])); fine; fine; (* Document_onmouseover *)
Come spiegato sopra, alleghiamo l'evento onmousemove di un documento nell'evento OnDocumentComplete di un TWebBrowser:
procedura TForm1.WebBrowser1DocumentComplete (ASender: TObject; const pDisp: IDispatch; var URL: OleVariant); inizio Se Assegnato (WebBrowser1.Document) poi inizio htmlDoc: = WebBrowser1.Document come IHTMLDocument2; htmlDoc.onmouseover: = (TEventObject.Create (Document_OnMouseOver) come IDispatch); fine; fine; (* WebBrowser1DocumentComplete *)
Ed è qui che sorgono i problemi! Come puoi immaginare l'evento "onmousemove" non è * un * un evento normale - come lo sono quelli con cui siamo abituati a lavorare in Delphi.
"Onmousemove" prevede un puntatore a una variabile di tipo VARIANT di tipo VT_DISPATCH che riceve l'interfaccia IDispatch di un oggetto con un metodo predefinito che viene richiamato quando si verifica l'evento.
Per allegare una procedura Delphi a "onmousemove" devi creare un wrapper che implementa IDispatch e genera il tuo evento nel suo metodo Invoke.
Ecco l'interfaccia di TEventObject:
TEventObject = classe(TInterfacedObject, IDispatch) privato FOnEvent: TObjectProcedure; protetta funzione GetTypeInfoCount (su Conteggio: intero): HResult; stdcall; funzione GetTypeInfo (Index, LocaleID: Integer; su TypeInfo): HResult; stdcall; funzione GetIDsOfNames (const IID: TGUID; Nomi: puntatore; NameCount, LocaleID: Integer; DispIDs: Puntatore): HResult; stdcall; funzione Invoke (DispID: Integer; const IID: TGUID; LocaleID: intero; Bandiere: Word; var Parametri; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall; pubblico costruttore Creare(const OnEvent: TObjectProcedure); proprietà OnEvent: TObjectProcedure leggere FOnEvent Scrivi FOnEvent; fine;
Ecco come implementare il sink di evento per un documento visualizzato dal componente TWebBrowser e ottenere le informazioni di un elemento HTML sotto il mouse.
Scarica
Rilasciare un TWebBrowser ("WebBrowser1") su un modulo ("Form1"). Aggiungi un TMemo ("elementInfo") ...
unità Unità 1;
interfaccia
usi
Windows, Messaggi, SysUtils, Varianti, Classi, Grafica, Controlli, Moduli,
Finestre di dialogo, OleCtrls, SHDocVw, MSHTML, ActiveX, StdCtrls;
genere
TObjectProcedure = procedura di oggetto;
TEventObject = classe(TInterfacedObject, IDispatch)
privato
FOnEvent: TObjectProcedure;
protetta
funzione GetTypeInfoCount (out Count: Integer): HResult; stdcall;
funzione GetTypeInfo (Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
funzione GetIDsOfNames (const IID: TGUID; Nomi: puntatore; NameCount, LocaleID: Integer; DispIDs: Puntatore): HResult; stdcall;
funzione Invoke (DispID: Integer; const IID: TGUID; LocaleID: intero; Bandiere: Word; var Parametri; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
pubblico
costruttore Creare(const OnEvent: TObjectProcedure);
proprietà OnEvent: TObjectProcedure leggi FOnEvent scrivi FOnEvent;
fine;
TForm1 = classe(TForm)
WebBrowser1: TWebBrowser;
elementInfo: TMemo;
procedura WebBrowser1BeforeNavigate2 (ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Header: OleVariant; var Annulla: WordBool);
procedura WebBrowser1DocumentComplete (ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
procedura FormCreate (Mittente: TObject);
privato
procedura document_onmouseover;
pubblico
Pubblico dichiarazioni
fine;
var
Form1: TForm1;
htmlDoc: IHTMLDocument2;
implementazione
$ R * .dfm
procedura TForm1.Document_OnMouseOver;
var
elemento: IHTMLElement;
inizio
Se htmlDoc = zero poi Uscita;
element: = htmlDoc.parentWindow.event.srcElement;
elementInfo.Clear;
Se LowerCase (element.tagName) = 'a' poi
inizio
elementInfo.Lines.Add ('LINK info ...');
elementInfo.Lines.Add (Format ('HREF:% s', [element.getAttribute ('href', 0)]));
fine
altro Se LowerCase (element.tagName) = 'img' poi
inizio
elementInfo.Lines.Add ('Informazioni IMMAGINE ...');
elementInfo.Lines.Add (Format ('SRC:% s', [element.getAttribute ('src', 0)]));
fine
altro
inizio
elementInfo.Lines.Add (Format ('TAG:% s', [element.tagName]));
fine;
fine; (* Document_onmouseover *)
procedura TForm1.FormCreate (Mittente: TObject);
inizio
WebBrowser1.Navigate ('http://delphi.about.com');
elementInfo.Clear;
elementInfo.Lines.Add ('Sposta il mouse sul documento ...');
fine; (* FormCreate *)
procedura TForm1.WebBrowser1BeforeNavigate2 (ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Header: OleVariant; var Annulla: WordBool);
inizio
htmlDoc: = zero;
fine; (* WebBrowser1BeforeNavigate2 *)
procedura TForm1.WebBrowser1DocumentComplete (ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
inizio
Se Assegnato (WebBrowser1.Document) poi
inizio
htmlDoc: = WebBrowser1.Document come IHTMLDocument2;
htmlDoc.onmouseover: = (TEventObject.Create (Document_OnMouseOver) come IDispatch);
fine;
fine; (* WebBrowser1DocumentComplete *)
TEventObject
costruttore TEventObject.Create (const OnEvent: TObjectProcedure);
inizio
ereditato Creare;
FOnEvent: = OnEvent;
fine;
funzione TEventObject.GetIDsOfNames (const IID: TGUID; Nomi: puntatore; NameCount, LocaleID: Integer; DispIDs: Puntatore): HResult;
inizio
Risultato: = E_NOTIMPL;
fine;
funzione TEventObject.GetTypeInfo (Index, LocaleID: Integer; out TypeInfo): HResult;
inizio
Risultato: = E_NOTIMPL;
fine;
funzione TEventObject.GetTypeInfoCount (out Count: Integer): HResult;
inizio
Risultato: = E_NOTIMPL;
fine;
funzione TEventObject.Invoke (DispID: intero; const IID: TGUID; LocaleID: intero; Bandiere: Word; var Parametri; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
inizio
Se (DispID = DISPID_VALUE) poi
inizio
Se Assegnato (FOnEvent) poi FOnEvent;
Risultato: = S_OK;
fine
altro Risultato: = E_NOTIMPL;
fine;
fine.