Webbrowser - Getting form elements in frames

Gidday there,

If I load a page and use
showmessage(IntToStr(WebBrowser.OleObject.Document.Forms.Length))
I get the number of forms on the page.
ie 1 or 2 ect

Now if that page has frames it always returns 0
How can I get the count of forms, or more importantly, how can I access a forms elements on a page with frames?
Like
WebBrowser.OleObject.document.forms.item(1).elements.item('myname').value:= 'Bob';

Cheers guys
LVL 10
wildzeroAsked:
Who is Participating?
 
Eddie ShipmanConnect With a Mentor All-around developerCommented:
Well I guess you're out of luck because MS declared that it was unsafe. I don't know if you'd be able to do it
with the Firefox DOM, either.
0
 
wildzeroAuthor Commented:
Points upped
0
 
Wayne BarronCommented:
If you had a link that I could help test on that would be helpful.
But anyway, take a look at this code.
And see if you can accomplish what you need with it.

How t0 interate through Frames
=====================================
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to (WebBrowser1.OleObject.Document.frames.Length - 1) do
    if WebBrowser1.OleObject.Document.frames.item(i).document.queryCommandEnabled('Copy') then
      ShowMessage('copy command is enabled for frame no.' + IntToStr(i));
end;
======================================
Carrzkiss
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
wildzeroAuthor Commented:
Carrzkiss,

Gidday there
Let me throw up a site - while I do that

If thats how to interate though frames, how could I use that to fill out a form on a frame?
like, interate though frames to interate though forms ;)
0
 
Wayne BarronCommented:
Put up a site, and send the link over, I will take a look at it.
Also, if you have some sample code that you are using to do it.
Without Frames, Then please post that as well.
This way we are both working on the same track.

Carrzkiss
0
 
Wayne BarronCommented:
Code for filling in the forms, it what I meant to say
0
 
wildzeroAuthor Commented:
http://storeit-online.com/framestest/index.html

There is a url there of something I am trying to do, just like fillin the fields of say, the main page (name and url)
I tried using this

For i := 0 to WebBrowser.OleObject.Document.Forms.Length-1 do
  begin
    WebBrowser.OleObject.document.forms.item(i).elements.item('name').value:= 'Bob';
    WebBrowser.OleObject.document.forms.item(i).elements.item(url).value:= 'http://mysite.com';
  end;


Even just showmessage(IntToStr(WebBrowser.OleObject.Document.Forms.Length));
which normally returns more then 0
0
 
wildzeroAuthor Commented:
Hey there, manage to get any further?
0
 
wildzeroAuthor Commented:
Figured it out! Finally

procedure TForm1.Button5Click(Sender: TObject);
var
  g, f, k : integer;
  pDispatch : IDISPATCH;
  textarea: IHTMLTextAreaElement;
begin
  for f := 0 to WebBrowser1.OleObject.Document.frames.Length - 1 do
    begin
      showmessage(intToStr(WebBrowser1.OleObject.Document.frames.item(f).document.Forms.Length));
        for g := 0 to WebBrowser1.OleObject.Document.frames.item(f).document.Forms.Length-1 do
          begin
             for k := 0 to WebBrowser1.OleObject.Document.frames.item(f).document.forms.item(g).elements.length-1 do
              begin
                showmessage(WebBrowser1.OleObject.Document.frames.item(f).document.forms.item(g).elements.item(k).name);
                showmessage(WebBrowser1.OleObject.Document.frames.item(f).document.forms.item(g).elements.item(k).tagname);
                showmessage(WebBrowser1.OleObject.Document.frames.item(f).document.forms.item(g).elements.item(k).type);
                {Fill text field}
                WebBrowser1.OleObject.Document.frames.item(f).document.forms.item(g).elements.item('name').value := 'Bob';
                {Fill in a text area}
                pDispatch := WebBrowser1.OleObject.Document.frames.item(2).document.forms.item(0).elements.item('S1', 0);
                  try
                    OleCheck(pDispatch.QueryInterface(IID_IHTMLTextAreaElement, textarea));
                    textarea.Set_value('Hello');
                  except
                  end;
              end;
          end;
    end;
end;
0
 
Wayne BarronCommented:
Hello WildZero;

  I am so sorry that I have not gotten back with you.
It has been rather hectic here at my house over the weekend.
And I just took a break from doing anything on the computer.
(The life of being a single parent)
I am glad to see that you was able to figure it out with the
Code that I sent over.

Maybe I am just wore out, But I cannot get it to compile.
Getting a few errors. ( Maybe rest will help my brain ;-)  )

[Error] Unit1.pas(34): Undeclared identifier: 'IHTMLTextAreaElement'
[Error] Unit1.pas(51): Undeclared identifier: 'OleCheck'
[Error] Unit1.pas(51): Undeclared identifier: 'IID_IHTMLTextAreaElement'
&
[Error] Unit1.pas(52): Missing operator or semicolon
On this:                     textarea.Set_value('Hello');

Anyway.
Hope that you make something that makes you a lot of fortune.

Take Care
Carrzkiss
0
 
Eddie ShipmanAll-around developerCommented:
Your errros come from missing units in your uses.
Be aware that you WILL NOT be able to do this on frames that are not on your the same domain as
the frameset. obtaining info from cross-domain frames will be caught by IE's security measures.
0
 
wildzeroAuthor Commented:
MSHTML_TLB (MSHTML for some) and SHDocVw I think it is you need.

Eddie, you are right - and thats the thing I need to work nothing you can think of/suggest?
0
 
Wayne BarronCommented:
Uses MSHTML_TLB, SHDocVw, ComObj;

Thanks, good now I can test it out.
0
 
Eddie ShipmanAll-around developerCommented:
I can't get that code to work at all.
0
 
Wayne BarronConnect With a Mentor Commented:
I have not had the opertinity to test it out.
Got so much more stuff going on that I forgot about it.

I do know that I compiled the project, but that was as for as I got with it.
I could not feel in anything on the forms?
Will have to test it out again later on.

Carrzkiss
0
 
AqueathCommented:
Hi,
"WebBrowser1.OleObject.Document.frames.item(0).Document.forms.Item(0).Item(0).Value:='Bob';" will set the value of the first item on the first form of the first frame to 'Bob' provided that  such an item, form and frame exist, and provided that the item can be set.

Hope that helps you.

A.
0
 
AqueathCommented:
0
 
Eddie ShipmanAll-around developerCommented:
Aqueath,
  It doesn't work on ;ater versions of IE6 because of cross-domain security.
I can't even get it to work when the frame is on my own domain.
0
 
AqueathCommented:
Eddie,
According to Windows Update I have upgraded to the latest version of IE6, and this still works on my machine. I did however use the TWebBrowser component while testing this. Can you list the page you tried this on? And you IE6 version?

A.
0
 
wildzeroAuthor Commented:
A.

I got the code I posted to work fine but doesn't with cross domain things.
ie one frame on a different domain name.

Did you try that?
I am running IE6 on both machines
0
 
Eddie ShipmanAll-around developerCommented:
I tried it both ways and couldn't get it to work in either situation.

Here is the HTML I used:
<html>
  <head>
    <title>Untitled Document</title>
  </head>
  <frameset rows="14.3%,*,12.3%" frameborder="NO" border="1" framespacing="0">
    <frame src="gallery_2.html" name="topFrame" scrolling="NO" noresize frameborder="no" border="0">
      <frameset cols="27%,70%" frameborder="no" border="1" framespacing="0" marginwidth=0 marginheight=0>
        <frame src="gallery_3.html" name="mainFrame" scrolling="NO" noresize>
        <frame src="http://www.delphipages.com" name="dynamicframe" scrolling="yes" noresize frameborder="yes">
      </frameset>
    <frame src="gallery_4.html" name="topFrames" scrolling="NO" noresize frameborder="no">          
  </frameset>
</html>

The gallery_X.html pages are pages on my site.

If I change the delphipages.com url to another page on my site, it still doesn't work.

Of course I'm also trying this locally, too, (http://locahost/framsettest.html) and it doesn't work in either case.

0
 
wildzeroAuthor Commented:
With
WebBrowser1.OleObject.Document.frames.item(0).Document.forms.Item(0).Item(0).Value:='Bob';
I get Access Denied.

When I do this
  showmessage(IntToStr(WebBrowser1.OleObject.Document.frames.Length));
  for f := 0 to WebBrowser1.OleObject.Document.frames.Length - 1 do
    showmessage(intToStr(WebBrowser1.OleObject.Document.frames.item(f).document.Forms.Length));

I get the first message (2 for two forms)
But then I get a access denied message as well.....

0
 
AqueathCommented:
Wildzero,
Can you tell me the url of the page you're trying to reach?

A.
0
 
wildzeroAuthor Commented:
I just tried this and got the same result.

Open up notepad and paste this

<html>
  <head>
    <title>Untitled Document</title>
  </head>
  <frameset rows="595,*,115" frameborder="NO" border="1" framespacing="0">
   <frame src="http://www.delphipages.com" name="dynamicframe" scrolling="yes" noresize frameborder="yes">       
      <frameset cols="51%,49%" frameborder="no" border="1" framespacing="0" marginwidth=0 marginheight=0>
        <frame name="mainFrame" scrolling="NO" noresize>
        <frame name="topFrame" scrolling="NO" noresize frameborder="no" border="0">
       
      </frameset>
    <frame name="topFrames" scrolling="NO" noresize frameborder="no">          
  </frameset>
</html>

Save as test.html to C:\
Then set webbrowser1 to navigate to C:\txt.html

Then try this
  showmessage(IntToStr(WebBrowser1.OleObject.Document.frames.Length));
  for f := 0 to WebBrowser1.OleObject.Document.frames.Length - 1 do
    showmessage(intToStr(WebBrowser1.OleObject.Document.frames.item(f).document.Forms.Length));

It came up with 4 as expected, but then got access denied..

0
 
Eddie ShipmanAll-around developerCommented:
You can't just navigate to c:\txt.html. You must place it in inetpub\wwwroot and use http://locahost/txt.html.
I tried it that way and got the same result.
0
 
wildzeroAuthor Commented:
Eh?
I placed it on c:\ and naviagated to it just fine
Got the same result as if it was on the internet anyway
0
 
AqueathConnect With a Mentor Commented:
Hi Guys,

It seems you might be right Eddie about the cross-domain security. I tried the html you posted, and I ran into trouble accessing the objects on delphipages or any other page for that matter, when running a html form locally. I had only tried this previously on pages located on the same domain, as the code below will show. I have NO idea of what is said on the testpage used as my linguistic skills are rather limited, and does not include cyrillic characters in any form ;-) The testpage does however include both frames and a form, and I included a source that works for me on the selected testpage, and demonstrates the basics. Unfortunately it may not work on all pages due to the fact Eddie previously pointed out. Anyway....

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure WebBrowser1DocumentComplete(Sender: TObject;
      const pDisp: IDispatch; var URL: OleVariant);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.Enabled:=False;
  Button2.Enabled:=False;
  Button3.Enabled:=False;
  Button4.Enabled:=False;
  WebBrowser1.Navigate('http://relay.adm.yrg.kuzbass.net/gai/homegai.html');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage(WebBrowser1.OleObject.Document.frames.length);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  showmessage(WebBrowser1.OleObject.Document.frames.item(1).Document.forms.length);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  WebBrowser1.OleObject.Document.frames.item(1).document.forms.Item(0).Item(0).Value:='Bob';
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  WebBrowser1.OleObject.Document.frames.item(1).Document.forms.item(0).submit;
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
  Button1.Enabled:=True;
  Button2.Enabled:=True;
  Button3.Enabled:=True;
  Button4.Enabled:=True;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  WebBrowser1.OleObject.Document.frames.item(1).Document.forms.item(0).submit;
end;

end.


A.
0
 
wildzeroAuthor Commented:
Aqueath - Thanks for the msg and summary, but it doesn't really get me any further ahead then my post "Figured it out! Finally....." I do appreaciate the time you've put into it though... Just gota figure out the cross domain thing...
0
 
Eddie ShipmanAll-around developerCommented:
I was working on a MHTML (web archive)  processor and was having major problems with Frames
and IFrames. Then I ran accross a post on comp.infosystems.authoring.html about the cross-domain
security issue.

Now, I am not using IHTMLDocument2 anymore, I just use idHTTP and TRegEx to parse the HTML. When
I run across a frame/iframe, I download the source separately.

I am trying to recreate the technique used in this VB.Net article in Delphi:
http://www.codeproject.com/vb/net/MhtBuilder.asp#xx979211xx
0
 
wildzeroAuthor Commented:
mmmm
thats what I may have to do
A friend pointed out that Robo form handles frames and iframes so there must be some way - maybe it has it's own build in html engine. Who knows. Tis a shame...
0
 
Eddie ShipmanAll-around developerCommented:
So, is that what you are doing, building a tool to download entire websites either into a MHT file or a directory?
0
 
wildzeroAuthor Commented:
Negative,

Trying to get the form elements from frames.
I may have to parse the html and if there are frames load them up somehow and go from there...

Herm...
0
 
Eddie ShipmanAll-around developerCommented:
but WHY?
0
 
wildzeroAuthor Commented:
So I can fill them out
0
 
Eddie ShipmanAll-around developerCommented:
ANy particular site you are working with or just in general?
0
 
wildzeroAuthor Commented:
Just in general, I've got everything working but the cross-domain thing....
:)
0
 
wildzeroAuthor Commented:
Thanks everyone for there feedback...
0
 
wildzeroAuthor Commented:
Crap was ment to hit A!
0
All Courses

From novice to tech pro — start learning today.