Entwickler-Ecke

Internet / Netzwerk - TWebbrowser, zugriffsverletzung bei jeder OLE rückgabe


fuba - Mo 20.04.09 15:34
Titel: TWebbrowser, zugriffsverletzung bei jeder OLE rückgabe
Tag zusammen,

Ich war gerade dabei mich mit TWebbrowser zu beschäftigen.
Dabei habe ich versucht auf die Forms einer seite zuzugreifen und diese gegebenfalls auszufüllen und abzuschicken.
Habe schon einige treaths gefunden, wo jeder sagt es funktioniert, jedoch kann ich das nicht sagen, da ich jedesmal wenn ich die OLEVariant auslesen will einen zugriffsverletzung bekomme.

Wichtig!
Ich nutze Windows 7 64bit mit Internet Explorer 8
Möglicherweise liegt es daran?

aber hier mal mein code, mal sehen was ihr dazu sagt oder ob ihr vorschläge habt.

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:
procedure TForm1.Button3Click(Sender: TObject);
var
  i, j: Integer;
  OV, FormItem: Variant;
begin
  WebBrowser1.Navigate('http://postdata.kilu.de');

  OV := WebBrowser1.OleObject.Document.forms;

  for i := 0 to WebBrowser1.OleObject.Document.forms.Length-1 do
  begin
    FormItem := WebBrowser1.OleObject.Document.forms.Item(i);
    for j := 0 to FormItem.Length-1 do
    begin
      if FormItem.Item(j).Name = 'username' then
      begin
        FormItem.Item(j).Value := 'TEST User';
      end;
      if FormItem.Item(j).Name = 'pwd' then
      begin
        FormItem.Item(j).Value := 'TEST Password';
      end;
    end;
  end;
end;


der fehler tritt immer bei

Delphi-Quelltext
1:
OV := WebBrowser1.OleObject.Document.forms;                    

auf.

Der fehler:

Quelltext
1:
Zugriffsverletzung bei Adresse 0047028B in Modul 'Project1.exe'. Lesen von Adresse 00000000.                    


P.S
Ich weiß dies geht auch mit TidHTTP, dennoch möchte ich es auch mit TWebbrowser machen.

Würde mich freuen wenn ihr ne idee habt woran es liegen kann.
Werde das ganze auch mal im WinXP testen und sehen was da kommt.

danke für eure antworten,
lg. fuba


toms - Mo 20.04.09 15:50

Hallo,

Direkt nach dem Navigieren ist WebBrowser1.OleObject.Document auch noch nicht definiert.

ist leicht zu überprüfen:

Delphi-Quelltext
1:
2:
3:
4:
  
 WebBrowser1.Navigate('http://postdata.kilu.de');
 ovDoc := Webbrowser1.OleObject.Document;
 if  VarIsClear(ovDoc) then ...


Lösung: Vor dem Zugrff auf ebBrowser1.OleObject.Document.forms warten, bis die Seite fertig geladen hat (OnDocumentComplete Ereignis verwenden)


fuba - Mo 20.04.09 19:28

user profile icontoms hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

Direkt nach dem Navigieren ist WebBrowser1.OleObject.Document auch noch nicht definiert.

ist leicht zu überprüfen:

Delphi-Quelltext
1:
2:
3:
4:
  
 WebBrowser1.Navigate('http://postdata.kilu.de');
 ovDoc := Webbrowser1.OleObject.Document;
 if  VarIsClear(ovDoc) then ...


Lösung: Vor dem Zugrff auf ebBrowser1.OleObject.Document.forms warten, bis die Seite fertig geladen hat (OnDocumentComplete Ereignis verwenden)


Das mit OnDocumentComplete funktioniert nur dann, wenn ich die schleife direkt in OnDocumentComplete einfüge, jedoch nicht wenn ich eine Globale variable anspreche und auf diese dann im buttoncode warte:

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:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
var
  isLoaded: Bool;
...
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
  isLoaded:=true;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i, j: Integer;
  ovDoc, ovForm, FormItem: Variant;
begin
  isLoaded:=False;
  WebBrowser1.Navigate('http://postdata.kilu.de');
  ovDoc := WebBrowser1.OleObject.Document;
  while not isLoaded do
  begin
    sleep(50);
    Application.ProcessMessages;
  end;

  ovForm := ovDoc.forms; // hier ist wieder der fehler, obwohl die seite schon geladen sein sollte ?!?

  for i := 0 to WebBrowser1.OleObject.Document.Forms.Length-1 do
  begin
    FormItem := WebBrowser1.OleObject.Document.Forms.Item(i);
    for j := 0 to FormItem.Length-1 do
    begin
      if FormItem.Item(j).Name = 'username' then
      begin
        FormItem.Item(j).Value := 'username';
      end;
      if FormItem.Item(j).Name = 'pwd' then
      begin
        FormItem.Item(j).Value := 'password';
      end;
    end;
  end;
end;


hab auch schon folgendes probiert:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
WebBrowser1.Navigate('http://postdata.kilu.de');
  ovDoc := WebBrowser1.OleObject.Document;

  repeat
    sleep(50);
    Application.ProcessMessages;
  until Webbrowser1.ReadyState = READYSTATE_COMPLETE;

  ovForm := ovDoc.forms; // wieder hier der fehler
  ...


wenn ich Application.ProcessMessages ganz weglasse, dann hängt das project, andernfalls kommt der selbe fehler wie oben beschrieben.
Aber du musst wohl recht haben das es, wenn ich das Laden der Seite

Delphi-Quelltext
1:
  WebBrowser1.Navigate('http://postdata.kilu.de');                    

und den restlichen code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
for i := 0 to WebBrowser1.OleObject.Document.Forms.Length-1 do
begin
  FormItem := WebBrowser1.OleObject.Document.Forms.Item(i);
  for j := 0 to FormItem.Length-1 do
  begin
    if FormItem.Item(j).Name = 'username' then
    begin
      FormItem.Item(j).Value := 'username';
    end;
    if FormItem.Item(j).Name = 'pwd' then
    begin
      FormItem.Item(j).Value := 'password';
    end;
  end;
end;

getrennt auf 2 verschiedene buttons lege, dann funktioniert es (also es kommt keine zugriffsverletzung), da er die seite warscheinlich erst fertig lädt und dann erst den restlichen code ausführt.

Jedoch blicke ich nicht durch warum es nicht geht, wenn ich schon auf das ende des Ladevorgangs warte und trotzdem die zugriffsverletzung bekomme :?:
Warscheinlich habe ich irgendwas übersehen, währe toll wenn du mir da nen tip geben könntest ;)


fuba - Mo 20.04.09 19:47

ok habe es, wie es jetzt aussieht geschafft :)


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:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
procedure TForm1.Button6Click(Sender: TObject);
var
  i, j: integer;
  ovDoc, ovForm, FormItem: Variant;
begin
  WebBrowser1.Navigate('http://postdata.kilu.de');

  while WebBrowser1.ReadyState <> 4 do
  begin
    application.ProcessMessages;
    sleep(50);
  end;

  ovDoc   := WebBrowser1.OleObject.Document;
  ovForm  := ovDoc.forms;

  for i := 0 to ovForm.Length-1 do
  begin
    FormItem := ovForm.Item(i);
    for j := 0 to FormItem.Length-1 do
    begin

      if FormItem.Item(j).Name = 'username' then
      begin
        FormItem.Item(j).Value := 'ICH';
      end;

      if FormItem.Item(j).Name = 'pwd' then
      begin
        FormItem.Item(j).Value := '0000';
      end;

      if (FormItem.Item(j).Type = 'submit'and (FormItem.Item(j).Value = 'Login'then
      begin
        FormItem.Item(j).click;
      end;

    end;
  end;
end;


Ich danke dir nochmal für den hinweis auf (kurz gesagt: warte bis das dokument geladen wurde).
Ich hoffe den rest schaffe ich alleine, wenn nicht melde ich mich ;)

lg. fuba