5

I try to get the name of all forms of the loaded page. I have done this:

procedure TForm2.Button2Click(Sender: TObject);
var
  L: TStringList;
begin
  L := TStringList.Create;

  try
    Chromium1.Browser.MainFrame.VisitDomProc(
      procedure (const doc: ICefDomDocument)
        procedure IterateNodes(Node: ICefDomNode);
        begin
          if not Assigned(Node) then Exit;
          repeat
            if Node.ElementTagName = 'FORM' then
              L.Add(Node.GetElementAttribute('name'));

            if Node.HasChildren then IterateNodes(Node.FirstChild);

            Node := Node.NextSibling;
          until not Assigned(Node);
        end;
      begin
        IterateNodes(doc.Body);
      end
    );

    ShowMessage(L.Text);
  finally
    FreeAndNil(L);
  end;
end;

But I don't have any result. Any idea?

Thanks

cadetill
  • 1,552
  • 16
  • 24

2 Answers2

3

With XE2 Update 4

I have realized that the program flow continues when running the procedure parameter so that upon reaching the ShowMessage still has not run this procedure and therefore the TStringList is empty.

I have put a boolean variable control and it worked right, but this is not a elegant solution.

Here the new code:

procedure TForm2.Button2Click(Sender: TObject);
var
  L: TStringList;
  Finish: Boolean;
begin
  L := TStringList.Create;
  Finish := False;

  try
    Chromium1.Browser.MainFrame.VisitDomProc(
      procedure (const doc: ICefDomDocument)
        procedure IterateNodes(Node: ICefDomNode);
        begin
          if not Assigned(Node) then Exit;
          repeat
            if SameText(Node.ElementTagName, 'FORM') then
            begin
              L.Add(Node.GetElementAttribute('name'));
            end;

            if Node.HasChildren then
              IterateNodes(Node.FirstChild);

            Node := Node.NextSibling;
          until not Assigned(Node);
        end;
      begin
        IterateNodes(doc.Body);
        Finish := True;
      end
    );

    repeat Application.ProcessMessages until (Finish);
    ShowMessage(L.Text);
  finally
    FreeAndNil(L);
  end;
end;
cadetill
  • 1,552
  • 16
  • 24
  • I'm sure you can wait on something, or ask for a callback when iteration is complete. – David Heffernan Oct 13 '12 at 12:12
  • I've no experience with that control. Where's the documentation? – David Heffernan Oct 14 '12 at 12:56
  • @David, I don't think there's a documentation for Delphi CEF wrapper. I'm prefering the [`C++ documentation`](http://magpcss.org/ceforum/apidocs/projects/(default)/CefDOMVisitor.html), but it differs a lot from a Delphi wrapper in many ways. – TLama Oct 14 '12 at 13:14
  • @cadetill, I'll check this deeper today's evening, but don't you rather use non-anonymous method for this ? It will IMHO be more inspectional... (it doesn't surely mean that I want to overlook the problem you have :-) – TLama Oct 15 '12 at 09:20
  • @David: I think that no exist documentation. The URL from project is http://code.google.com/p/delphichromiumembedded/ – cadetill Oct 15 '12 at 20:22
  • Shame on me. Of course, this happens because `VisitDom` called throught the `VisitDomProc` method [`is asynchronous`](http://stackoverflow.com/questions/10670452/how-to-get-elements-by-name-in-delphi-chromium-embedded#comment13848626_10673526). That's the reason, why it happens to you. You call the `VisitDomProc` method, but your program flow continues immediately to the next line. So, your workaround is on a place! +1 – TLama Oct 16 '12 at 17:16
1

I managed to get the whole page like this:

  1. Inject a DOM element - text.
ChromiumWB.Browser.MainFrame.ExecuteJavaScript('$("body").prepend(''<input type="text" id="msoftval" value=""/>'')', '', 0);
  1. Use jquery or js to get body html into injected element.
mResult := '';
ChromiumWB.Browser.MainFrame.ExecuteJavaScript('$("#msoftval").val($("body").html());', '', 0);
ChromiumWB.Browser.MainFrame.VisitDomProc(getResult);
while mResult = '' do Application.ProcessMessages;
Memo1.Text := mResult;
  1. wait untill 'VisitDomProc' finish- make it sync.
procedure TForm44.getResult(const doc: ICefDomDocument);
var
  q: ICefDomNode;
begin
  q := doc.GetElementById('msoftval');
  if Assigned(q) then
    mResult := q.GetValue
  else
    mResult := '-';
end;
Fernando M. Pinheiro
  • 610
  • 1
  • 10
  • 21
user2005049
  • 510
  • 1
  • 5
  • 26