![]() |
TWebBrowser < undefinierter Bezeichner
Hallo,
ich möchte in einem Thread den TwebBrowser dynamisch erzeugen, allerdings meckert der Compiler das TWebBrowser ein undefinierter Bezeichner wäre.
Delphi-Quellcode:
Die Uses hatte ich auch schon einmal erweitert
uses
Classes, SysUtils; ... procedure TMyThreads.Grabber(Keyword: String; FFirstStep: Integer); var WebBrowser: TWebBrowser; begin WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try except //nix end; FreeAndNil(WebBrowser); end;
Delphi-Quellcode:
Jemand eine Idee?
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; |
Re: TWebBrowser < undefinierter Bezeichner
Du musst noch die entsprechende Unit einbinden. SHDocVw_TLB müsste die richtige sein...
|
Re: TWebBrowser < undefinierter Bezeichner
Du musst entweder die Unit ShDocVw (ab Professional) oder ShDocVw_TLB (bei Personal, wenn selbst importiert) einbinden.
|
Re: TWebBrowser < undefinierter Bezeichner
oh danke =)
|
Re: TWebBrowser < undefinierter Bezeichner
hmm ein kleines problem hab ich nun aber trotzdem noch,
wenn ich über .navigate eine webseite laden möchte wird diese ohne sleep(); nur teilweise oder gar nicht geladen. kann man dazu irgendwo einen timeout setzen?
Delphi-Quellcode:
procedure TMyThreads.Grabber();
var WebBrowser: TWebBrowser; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try WebBrowser.Navigate('http://test.com'); sleep(2000); except //nix end; FreeAndNil(WebBrowser); OleUninitialize; end; |
Re: TWebBrowser < undefinierter Bezeichner
Neue Frage, neuer Thread!
Zitat:
Delphi-Quellcode:
dann kannst du nachher nur "Navigate('...');" schreiben, ohne vorangestelltes "WebBrowser". ;)
with WebBrowser do
Und "sleep" friert das ganze Programm ein, schau lieber mal nach ![]()
Delphi-Quellcode:
Sollte man auch nicht verwenden, siehe dazu
try
... except //nix end; ![]() Du kannst auch warten, bis die Seite komplett geladen ist, mittels:
Delphi-Quellcode:
procedure TForm1.wbNavigateComplete2(Sender: TObject;const pDisp: IDispatch; var URL: OleVariant);
const url_google = 'http://www.google.de'; begin cbWeb.Text := lower(wb.OleObject.Document.Url); if (cbWeb.Text = url_google) or (cbWeb.Text = url_google + '/') then begin ShowMessage(cbWeb.Text + ' wurde geladen'); end; end; Edit: Ein paar Tippfehler verbessert. |
Re: TWebBrowser < undefinierter Bezeichner
oh danke für die hilfe,
ich werd versuchen zukünftig deine ratschläge zu beherzigen =) eine frage hab ich allerdings trotzdem noch *gg* wenn ich versuche in einem thread ein formular (z.b. google.com) auszufüllen dann gibt es eine zugriffverletzung an dieser stelle:
Delphi-Quellcode:
Exception der Klasse EAccessViolation
WebBrowser.OleObject.Document.forms.Item(0).Item('g').Value := 'internet';
|
Re: TWebBrowser < undefinierter Bezeichner
also ich hab nun versucht zu prüfen ob
überhaupt ein formular existiert das ich ausfüllen kann, auch hier erhalte ich eine zugriffsverletzung wenn der thread versucht auf das OLE Objekt zu zugreifen.
Delphi-Quellcode:
das selbe problem stellt sich bei mir auch da wenn ich
if OleObject.Document.all.tags('FORM').Length = 0 then
begin Exit; end; zum testen eine neue anwendung erzeuge
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ShDocVw, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var wb: TWebBrowser; begin wb := TWebBrowser.Create(Form1); TWinControl(wb).Name := 'MyWebBrowser'; TWinControl(wb).Parent := Form1; wb.Align := alClient; wb.Navigate('http://www.google.com'); sleep(2000); if wb.OleObject.Document.all.tags('FORM').Length = 0 then begin Exit; end else showmessage('found'); end; end. |
Re: TWebBrowser < undefinierter Bezeichner
ich versteh das einfach nicht, nun les ich mich seit stunden
durch foren, newsgroups und artikel und hab diverese sourcecodes ausprobiert, aber jedesmal wenn ich auf auf ole objekt zugreifen will gibts den fehler das ist echt zum kotzen :wall: |
Re: TWebBrowser < undefinierter Bezeichner
:warn: Pushen ist erst nach 24 Stunden erlaubt :dp:
|
Re: TWebBrowser < undefinierter Bezeichner
naja eigentlich wollte ich damit nix pushen,
fehlt auch irgendwie die hälfte bei dem posting ich hatte das ganze nun wie folgt ausprobiert, aber ich häng noch immer an der selben stelle
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ShDocVw, StdCtrls, activex; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var wb: TWebBrowser; begin wb := TWebBrowser.Create(Form1); TWinControl(wb).Name := 'MyWebBrowser'; TWinControl(wb).Parent := Form1; wb.Align := alClient; wb.Navigate('http://www.google.com'); sleep(2000); wb.OleObject.document.forms.item(0).elements.item('q').value:='test'; end; end. |
Re: TWebBrowser < undefinierter Bezeichner
ersetz das sleep(2000); durch
Delphi-Quellcode:
mit sleep hälst du nur den prozess (mainthread) an, das hilft dir dann aber auch nix wenn die seite noch net geladen ist...
while wb.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages; |
Re: TWebBrowser < undefinierter Bezeichner
hallo, danke für die hilfe, das sleep hier eher unangebracht ist war mir schon
klar, das dadurch allerdings diese zugriffsverletzung verursacht wird ist mir neu, wie zu erwarten war funktioniert der aufruf Application.ProcessMessages; in den threads nicht der einbau von OnDocumentComplete ist mir auch ein rätsel
Delphi-Quellcode:
procedure TMyThreads.Grabber();
var WebBrowser: TWebBrowser; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try Navigate('http://www.google.com'); OnDocumentComplete:= //?????? OleObject.Document.Forms.item(0).submit; ??????/// except //nix end; Fstatus:= 'done.'; Synchronize(UpdateLVCaption); FreeAndNil(WebBrowser); OleUninitialize; end; |
Re: TWebBrowser < undefinierter Bezeichner
also ich hab nun nochmal ne ganze weile rumprobiert
und mittlerweile echt genervt von dem kram =(
Delphi-Quellcode:
Der Aufruf von Application.ProcessMessages; funktioniert in
procedure TMyThreads.Execute();
var WebBrowser: TWebBrowser; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try Navigate('http://www.google.com'); while ReadyState <> READYSTATE_COMPLETE do Application.ProcessMessages; OleObject.document.forms.item(0).elements.item('q').value:='test'; OleObject.Document.Forms.item(0).submit; except end; FreeAndNil(WebBrowser); OleUninitialize; end; dem Thread nicht und mit einer Delay Funktion aus diesem Forum wird die while Schleife nie verlassen. der Ansatz mit Hilfe von ReadyStats <> Readystats_Complete klingt ja vielversprechend, aber wie kann damit im besagten Thread auf ein positives Ergebnis warten bzw wie kann man Delphi veranlassen auf das Eintreten des OnDocumentComplete Events zu warten. |
Re: TWebBrowser < undefinierter Bezeichner
Delphi-Quellcode:
Also ich würde auf keinen Fall das Objekt WebBrowser dynamisch zu Laufzeit erzeugen,
var
WebBrowser: TWebBrowser; begin WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do // irgendwas tun end; FreeAndNil(WebBrowser); end; damit arbeiten und gleich wieder zerstören. Hinter dem WebBrowser stecken sehr viele DLLs, Schnittstellen, Resourcen, .... Deshalb sollte man das Ding nur einmal erzeugen und erst dann zerstören, wenn auch das Formular zerstört wird. Vielleicht ist Navigate noch nicht ganz fertig und du ziehst dem BrowserObjekt sozusagen den Stuhl unterm Hinern weg. |
Re: TWebBrowser < undefinierter Bezeichner
naja, wie gesagt, das ganze läuft in threads,
ich denke da läßt sich das erzeugen wärend der laufzeit nicht vermeiden leider hast du recht damit das navigate(); nicht ausreichend zeit bekommt um die aufgerufene seite vollständig zu laden, da ich nicht weiß wie ich bei einem dynamisch erzeugten twebbrowser auf das event OnDocumentComplete reagieren kann bzw es einzubinden habe - oder "ReadyState <> READYSTATE_COMPLETE" in die warteschleife schicken aber leider konnte ich dazu bisher nichts finden |
Re: TWebBrowser < undefinierter Bezeichner
hab die funktion hier im forum gefunden, das könntest du dann statt Application.ProcessMessages; nehmen:
Delphi-Quellcode:
musst dann als parameter einfach Handle einsetzen..
procedure ProcessMessages(hWnd: DWORD);
var Msg: TMsg; begin while PeekMessage(Msg, hWnd, 0, 0, PM_REMOVE) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end; hoffe konnte dir damit n bischen helfen :| |
Re: TWebBrowser < undefinierter Bezeichner
ich weiß nicht ob ich bei der ganzen geschichte etwas
falsch verstehe, aber eigentlich macht es doch keinen unterschied ob ich den twebbrowser wärend der laufzeit erzeuge oder statisch, ich müßte doch trotzdem events wie ondocumentcomplete nutzen können oder lieg ich damit völlig falsch? |
Re: TWebBrowser < undefinierter Bezeichner
Ist ja auch kein Problem das du das nutzen möchtest!
Gibt zwei Möglichkeiten! 1. Du übergibst deinem Thread die Application. Somit kannst du dann auch Applications.ProcessMessages benutzen. Hab ich aber nicht ausprobiert und kann ich auch nicht sagen ob das in einem Extra Thread dann genauso funktioniert, wie wenn du nur den Hauptthread hast! 2. du bist ja mit dem OnDocumentComplete garnicht mal so weit von der lösung weg! das WebBrowser1.OnDocumentComplete benötigt nur der zuweisung einer Prozedur. Funktioniert nach dem Schema wie im ObjektInspektor! da Klickst du ja normalerweise Doppelklick auf "OnDocumentComplete" und Delphi erstellt dir von hand eine Prozedur und weisst WebBrowser1.OnDocumentComplete automatisch dieser Prozedur zu. Mach du das doch einfach von hand:
Code:
Und da schreibste dann rein was er machen soll!
WebBrowser1.OnDocumentComplete := meineProzedurWennFertigGeladen;
greetz emploi |
Re: TWebBrowser < undefinierter Bezeichner
hallo,
danke für die antwort, die variante 2 hatte ich auch schon ausprobiert, allerdings bekomm ich dann folgende Fehlermeldung: Zitat:
Delphi-Quellcode:
type
TMyThreads = class(TThread) private { Private-Deklarationen } ... procedure Submit(); ... protected procedure Execute; override; ... end; implementation procedure TMyThreads.Execute; var WebBrowser: TWebBrowser; i:integer; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try Navigate('http://www.google.com'); OnDocumentComplete:= Submit(); except //fehlt noch end; FreeAndNil(WebBrowser); OleUninitialize; end; procedure TMyThreads.Submit; // Compiler-Fehler: Unbekannte Anweisung: 'OleObject'. OleObject.document.forms.item(0).elements.item('q').value:='test'; OleObject.Document.Forms.item(0).submit; end; |
Re: TWebBrowser < undefinierter Bezeichner
Delphi-Quellcode:
sollte funktionieren
type
TMyThreads = class(TThread) private procedure Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); //deine prozedur und die andere müssen identisch sein (jedenfalls die Parameter..)! protected procedure Execute; override; end; implementation procedure TMyThreads.Execute; var WebBrowser: TWebBrowser; i:integer; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do begin try Navigate('http://www.google.com'); OnDocumentComplete:= Submit; except //... end; end; end; procedure TMyThreads.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin if URL = 'http://www.google.com' then begin (Sender As TWebBrowser).OleObject.document.forms.item(0).elements.item('q').value:='test'; (Sender As TWebBrowser).OleObject.Document.Forms.item(0).submit; end; end; |
Re: TWebBrowser < undefinierter Bezeichner
hi,
dein problem ist wenn du der OnDocumentComplete ne Prozedur zuweist dann musst die genau die gleiche schnittstelle haben wie die die vom Objektinspektor automatisch generiert wird! dh klick mal im Objektinspektor doppelklick auf das ereigniss DocumentComplete und schau dir die Schnittstelle an! Genau diese Schnittstelle muss deine eigene Prozedur auch haben! dann sollte es gehen! mfg emploi |
Re: TWebBrowser < undefinierter Bezeichner
oh danke danke, damit helft ihr mir sehr weiter :)
ich hab das ganze nun dank Eurer Hilfe wie folgt umgebaut und der compiler meckert nun auch nicht mehr. leider tritt das OnDocumentComplete Ereignis nie ein.
Delphi-Quellcode:
procedure TMyThreads.Execute;
var WebBrowser: TWebBrowser; i:integer; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try Navigate('http://www.google.com'); Fstatus:= 'Connecting to http://google.com'; Synchronize(UpdateLVCaption); OnDocumentComplete:= Submit; except FreeAndNil(WebBrowser); OleUninitialize; end; Fstatus:= 'finished.'; Synchronize(UpdateLVCaption); end; procedure TMyThreads.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin // Tritt leider nie ein ************************** showmessage('Submit fired'); //************************************************ (Sender As TWebBrowser).OleObject.document.forms.item(0).elements.item('q').value:='test'; (Sender As TWebBrowser).OleObject.Document.Forms.item(0).submit; FreeAndNil(Sender); OleUninitialize; end; |
Re: TWebBrowser < undefinierter Bezeichner
möglicherweise endet die methode schon bevor
ondocumentcomplete ausgelöst wird |
Re: TWebBrowser < undefinierter Bezeichner
auf showmessage würde ich mich nicht verlassen, ist soweit ich mich erinner, ne an die VCL angekoppelte funktion, die in threads net funktioniert :gruebel: :roll:
[EDIT] btw seh ich gerad das freeandnil+couninitialize in dem event.. musste weg :angel2: [/EDIT] |
Re: TWebBrowser < undefinierter Bezeichner
Also ich kann mir zwar nicht vorstellen das es davon abhängig ist,
aber weise mal dem OnDocumentComplete direkt nach dem erzeugen deiner Submit Methode zu. Vielleicht geht das ja ;) Ansonsten könnte es auch passieren das das laden der seite länger dauert...
Code:
... und er das FreeAndNil eher aufruft bevor das Ereignis überhaupt auftreten kann!
procedure TMyThreads.Execute;
var WebBrowser: TWebBrowser; i:integer; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try Navigate('http://www.google.com'); Fstatus:= 'Connecting to http://google.com'; Synchronize(UpdateLVCaption); OnDocumentComplete:= Submit; except FreeAndNil(WebBrowser); OleUninitialize; end; Fstatus:= 'finished.'; Synchronize(UpdateLVCaption); end; procedure TMyThreads.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin // Tritt leider nie ein ************************** showmessage('Submit fired'); //************************************************ (Sender As TWebBrowser).OleObject.document.forms.item(0).elements.item('q').value:='test'; (Sender As TWebBrowser).OleObject.Document.Forms.item(0).submit; FreeAndNil(Sender); OleUninitialize; end; Hab leider momentan keine zeit, bin immer nur mal sporadisch am pc. werd mir das morgen mal angucken wennes bis dahin nicht gelöst hast! mfg emploi [edit] ich seh grad der Basic war ja schneller mit der antwort :P [/edit] |
Re: TWebBrowser < undefinierter Bezeichner
also laut meinem packetsniffer wird
Navigate('http://www.google.com'); ausgeführt und anschließend wird Fstatus:= 'finished.'; übergeben. die ondocumentcomplete anweisung dazwischen wird nicht ausgeführt |
Re: TWebBrowser < undefinierter Bezeichner
Zitat:
dieser wird auch nicht angezeigt in meiner mainform:
Delphi-Quellcode:
darüber hinaus hab ich auch noch andere Events ausprobiert,
procedure TMyThreads.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant);
begin Fstatus:= 'Submit() fired!'; Synchronize(UpdateLVCaption); end; immer mit dem selben Ergebnis :( |
Re: TWebBrowser < undefinierter Bezeichner
so hab mal bissel dran gebastelt.
schau dir das an und probier es ein bissel aus. sollte dann für dich klappen:
Code:
unit Unit2;
interface uses SysUtils, Classes, Controls, Forms, Dialogs, OleCtrls, SHDocVw, ActiveX; type myThread = class(TThread) private { Private-Deklarationen } protected procedure Execute; override; procedure Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); procedure UpdateCaption; public app : TApplication; end; implementation uses Unit1; { Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen nur in einer Methode namens Synchronize aufgerufen werden, z.B. Synchronize(UpdateCaption); und UpdateCaption könnte folgendermaßen aussehen: procedure myThread.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; } { myThread } procedure myThread.Execute; var wb : TWebBrowser; begin OleInitialize(nil); wb := TWebBrowser.Create(Form1); try TWinControl(wb).Name := 'MyWebBrowser'; TWinControl(wb).Parent := Form1; wb.OnDocumentComplete := self.Submit; wb.Align := alClient; wb.Navigate('http://www.google.com'); while wb.ReadyState <> READYSTATE_COMPLETE do app.ProcessMessages; Synchronize(UpdateCaption); except FreeAndNil(wb); OleUninitialize; end; end; procedure myThread.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; procedure myThread.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin showmessage('test'); end; end. HauptUnit
Code:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, SHDocVw, StdCtrls, Unit2; type TForm1 = class(TForm) procedure FormShow(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject); var myTestThread : myThread; begin myTestThread := myThread.Create(True); WITH myTestThread DO BEGIN myTestThread.app := Application; FreeOnTerminate := True; Resume; END; END; end. mfg emploi |
Re: TWebBrowser < undefinierter Bezeichner
hallo,
danke für deine mühe =), nun bin ich schon ein ganzes stück weiter dank deiner hilfe, leider gibts noch immer zugriffsverletzungen =( die threads werden in der hauptform nun wie folgt erzeugt:
Delphi-Quellcode:
die thread unit hab ich wie folgt geändert:
for Loop := 0 to length(ThreadArray) - 1 do
begin ThreadArray[Loop] := TMyThreads.Create(true); ThreadArray[Loop].app := Application; ... end;
Delphi-Quellcode:
Wenn ich den Form-Submit auskommentiere erhalte ich die Fehlermeldung:
procedure TMyThreads.Execute;
var WebBrowser: TWebBrowser; begin OleInitialize(nil); WebBrowser:= TWebBrowser.Create(nil); with WebBrowser do try OnDocumentComplete:= Submit; Navigate('http://www.google.com'); while WebBrowser.ReadyState <> READYSTATE_COMPLETE do app.ProcessMessages; Fstatus:= 'ReadyState done.'; Synchronize(UpdateLVCaption); except FreeAndNil(WebBrowser); OleUninitialize; end; Fstatus:= 'finished.'; Synchronize(UpdateLVCaption); end; procedure TMyThreads.Submit(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin Fstatus:= 'sending.'; Synchronize(UpdateLVCaption); // (Sender As TWebBrowser).OleObject.document.forms.item(0).elements.item('q').value:='test'; // (Sender As TWebBrowser).OleObject.Document.Forms.item(0).submit; FreeAndNil(Sender); OleUninitialize; end; Zitat:
gibt es ebenfall eine Zugriffsverletzung. Zumindesten funktioniert das OnDocumentComplete Event jetzt. Des öfteren scheint es auch vorzukommen dass das Programm bzw der/die Threads in der ReadyState - while Schleife einfrieren. Hast Du vielleicht noch eine Idee wie man diese Fehler beheben könnte? |
Re: TWebBrowser < undefinierter Bezeichner
hehe, wie ich sehe benutzt du jetzt auch ein thread array ;)
das ist ja ein zufall. Ich bastel nämlich grad auch an einem programm wo ich zum ersten mal mit threads und halt gleich nem thread array arbeite. das problem ist das ich immer einen stack overflow bekomme. damit muss ich mich auch noch irgendwie zurecht finden, werd nachher mal an der lösung deines problems weiter machen. kannst ja mal bei mir reingucken :) ![]() mfg emploi |
Re: TWebBrowser < undefinierter Bezeichner
ich hab mit ein bissel hilfe hier im forum auch
schon ein paar brauchbare programme die mit threads arbeiten zusammengebastelt,bisher hab ich dafür immer die indy komponenten nutzen können, aber in diesem fall geht es leider nicht ohne den ie :( |
Re: TWebBrowser < undefinierter Bezeichner
das ist um so besser :)
ich kenn mich mitm ie mitlerweile echt ziemlich gut aus. also mit der TWebBrowser Komponente! und ich benutz auch die indy im thread! vielleicht können wir uns ja echt gegenseitig helfen! mfg emploi |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz