Hi,
My goal: User should be able to get the html source of a page, when clicked on a button. This event opens a new form with a geckoWebBrowser component and navigates to a given url. Once this is done it fires a documentCompleted event. Then I can start loading the DOM.
The problem: While the loading of the page needs time, I have to wait untill in the second form class the DOM (or just the value of a div) is loaded. This is exactly the problem! Every wait or loop stucks the second form (geckoBrowser) so I can't get the value.
This is the code of the first form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace mozillaFirefox2
{
public partial class Form1 : Form
{
string source = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//BackgroundWorker bw = new BackgroundWorker();
//bw.DoWork += new DoWorkEventHandler(bw_DoWork);
Browser br = new Browser();
//object parameters = br;
//bw.RunWorkerAsync(parameters);
br.navigate("http://www.google.com/#hl=en&q=superman&aq=f&aqi=&oq=&fp=1&cad=b");
Thread th = new Thread(delegate() { this.dw(br); });
th.Start();
th.Join(2000);
richTextBox1.AppendText(br.GetSource + "\n");
}
private void dw(Browser br)
{
while (br.workDone == false)
{
//donothing
}
source = br.GetSource;
}
//void bw_DoWork(object sender, DoWorkEventArgs e)
//{
// Browser br = (Browser)e.Argument;
// while (br.workDone == false)
// {
// //donothing
// }
// richTextBox1.AppendText(br.GetSource + "\n");
//}
}
}
This is the second:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace mozillaFirefox2
{
//Declare a delegate who points to a function / signature
public delegate void GotDataEventHandler(object sender, EventArgs e);
class Browser : Form
{
public event GotDataEventHandler GotData;
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.geckoWebBrowser1 = new Skybound.Gecko.GeckoWebBrowser();
this.SuspendLayout();
//
// geckoWebBrowser1
//
this.geckoWebBrowser1.Location = new System.Drawing.Point(14, 4);
this.geckoWebBrowser1.Name = "geckoWebBrowser1";
this.geckoWebBrowser1.Size = new System.Drawing.Size(261, 67);
this.geckoWebBrowser1.TabIndex = 2;
this.geckoWebBrowser1.DocumentCompleted += new EventHandler(geckoWebBrowser1_DocumentCompleted);
//Never forget this. Otherwise this error is raised "Cannot call Navigate() before the window handle is created"
this.geckoWebBrowser1.CreateControl();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(788, 577);
this.Controls.Add(this.geckoWebBrowser1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
public Skybound.Gecko.GeckoWebBrowser geckoWebBrowser1;
public string source = "";
public bool workDone = false;
public bool navCall = false;
[STAThread]
public Browser()
{
Skybound.Gecko.Xpcom.Initialize(@"C:\Program Files\Mozilla-Gecko ActiveX WebBrowserControl\xulrunner-1.9.1.2.en-US.win32\xulrunner");
Skybound.Gecko.GeckoPreferences.User["general.useragent.override"] = "Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)";
this.InitializeComponent();
this.Show();
}
public delegate void NavigationHandler(string url);
public void navigate(string url)
{
if (this.InvokeRequired)
{
object[] parameters = { url };
this.geckoWebBrowser1.Invoke(new NavigationHandler(navigate), parameters);
}
else
{
navCall = true;
this.geckoWebBrowser1.Navigate(url);
}
}
public string GetSource
{
get { return source; }
}
public string getSource()
{
return source;
}
public void geckoWebBrowser1_DocumentCompleted(object sender, EventArgs e)
{
if(navCall == true){
source = this.geckoWebBrowser1.Document.GetElementById("res").InnerHtml.ToString();
workDone = true;
navCall = false;
//
GotDataEventHandler gd;
lock (this)
{
gd = GotData;
}
if (gd != null)gd(this, EventArgs.Empty);
}
}
}
}
Now I should be able to just wait till I get an answer within the button1_Click function or catch the event within this function or a function on the second form so I can return this (than the code will wait by itself). Don't know how to do this.
Thanks in advance.