Welcome, Guest. Please login or register.
Login with username, password and session length

News:
Dear visitors, please register to stay updated with the latest info on Task Se7en, Moznet and other products
Pages: [1]
  Print  
Author Topic: GFXe without a Form  (Read 5383 times)
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« on: December 29, 2010, 04:27:42 PM »

Hi,

Is there a way to use GFXe/XULRunner without a windows form?  Can a hidden window be created that is the Window Handle?

Thanks,

Steve
Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #1 on: December 30, 2010, 08:12:29 AM »

Hi,

Is there a way to use GFXe/XULRunner without a windows form?  Can a hidden window be created that is the Window Handle?

Thanks,

Steve

You can use it without a form easily..

psuedo code:

Code:
void UseBrowser()
{
  GeckoWebBrowser wb = new GeckoWebBrowser();
  wb.CreateControl(); //<-- this is the key!
  wb.DocumentCompleted += delegate{ MessageBox.Show(wb.Url.AbsoluteUri); };
  wb.Navigate("http://www.google.com");
}

Best Regards,
Scott
Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #2 on: December 30, 2010, 04:30:38 PM »

Hi Scott,

Thanks for getting back to me.  I've tried what you suggest but using the following code instead:


            var autoEvent = new AutoResetEvent(false);
            using (var wb = new GeckoWebBrowser())
            {
                wb.CreateControl(); //<-- this is the key!
                wb.DocumentCompleted += delegate
                                            {
                                                Debug.WriteLine("DocumentCompleted called");
                                                using (var bmp = new Bitmap(1024, 768))
                                                {
                                                    using (var g = Graphics.FromImage(bmp))
                                                    {
                                                        var hdc = g.GetHdc();
                                                        PrintWindow(wb.Handle, hdc, 0);
                                                        g.ReleaseHdc();
                                                    }
                                                    bmp.Save(@"c:\Users\Current User\Desktop\browser_new.jpg",
                                                             System.Drawing.Imaging.ImageFormat.Jpeg);
                                                    autoEvent.Set();
                                                }
                                                Debug.WriteLine("Bitmap creation completed");
                                            };
                if (wb.Created)
                {
                    Debug.WriteLine("About to call Navigate...");
                    wb.Navigate("http://www.google.com");
                    Debug.WriteLine("Navigate called, waiting for completion");
                    // Wait up to 10 seconds for this to complete
                    autoEvent.WaitOne(20000);
                    if (wb.Document != null)
                    {
                        Debug.WriteLine("Have a document");
                    }
                    Debug.WriteLine("Complete.");
                }
                else
                {
                    Debug.WriteLine("Control not created");
                }
            }



Unfortunately the DocumentCompleted delegate never calls and if you put a breakpoint in the check for a document you'll find that the URL remains "about:blank" which indicates to me that it's unable to retrieve anything.  As well, the autoEvent never gets set so it eventually times out (after 20 seconds).

I'm running this as a Unit Test to keep things extremely simple.

Thanks again for helping with this.

Steve


« Last Edit: December 30, 2010, 04:32:56 PM by sgoyette » Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #3 on: December 30, 2010, 08:30:00 PM »

You have it all wrapped up in a 'Using' statement -- that's your killer right there. I've discussed this issue with someone on the GeckoFX forum before. If you remove the 'Using' statement it should be fine.

Please use code blocks for inline source next time, thanks.

Best Regards,
Scott
Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #4 on: December 30, 2010, 10:00:50 PM »

Hi Scott,

I added the using statements after to clean up the code for posting to the forum. Unfortunately this doesn't seem to work either way.

Steve
Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #5 on: December 30, 2010, 10:12:56 PM »


This works just fine for me..

Code:
GeckoWebBrowser wb = new GeckoWebBrowser();
wb.CreateControl();
wb.DocumentCompleted += (x, y) => {
    MessageBox.Show(wb.Url.AbsoluteUri);
};
wb.Navigate("http://google.com");

If it doesn't work after swapping out the code in the DocumentCompleted handler then it's a problem with whatever code you add Wink

Best Regards,
Scott
Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #6 on: December 31, 2010, 01:45:26 AM »

Hi Scott,

So I'm still unable to get this to work.  Here's what I've done.

1.) Create a new Project with type "Test Project"
2.) Edit the UnitTest1.cs file that automagically gets created and erase everything inside the class declaration and replace with this:


        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            var profileDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) +
            "\\MySoftwareCompany\\MySoftware\\DefaultProfile";
            if (!System.IO.File.Exists(profileDirectory))
            {
                System.IO.Directory.CreateDirectory(profileDirectory);
            }

            var path = System.Reflection.Assembly.GetExecutingAssembly().Location;
            Xpcom.Initialize(System.IO.Path.GetDirectoryName(path) + "\\XULRunner");
        }

        [TestMethod]
        public void TestMethod1()
        {
            GeckoWebBrowser wb = new GeckoWebBrowser();
            wb.CreateControl();
            wb.DocumentCompleted += (x, y) =>
                                        {
                                            MessageBox.Show(wb.Url.AbsoluteUri);
                                        };
            wb.Navigate("http://google.com");
        }

    }



3.) Create a new folder in the project directory named "XULRunner" and copy the XULRunner files there.

4.) In the project include the XULRunner files and set them to "Copy ALways" in the properties

5.) Run all unit tests in project

What will happen is that the messagebox will never show and if you examing the URL it will still be about:blank.  Debugging into Navigate shows that isBusy flag is set and stop doesn't seem to have any effect.  As a result no navigation is actually performed.

If it will help I would be happy to send you a sample p[roject illustrating this.

Steve













Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #7 on: December 31, 2010, 01:57:58 AM »

I don't know if it's helpful but on further investigation WebNav.LoadURI is returning 0 and the method (as a result) returns false.

Steve
Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #8 on: December 31, 2010, 03:54:09 AM »

I can't get it to work in a test project at all but, then again I may  be doing something wrong as I don't write test units. I do know for certain, in 'normal' projects, GeckoFx/GFXe can definitely be used without a form.

Best Regards,
Scott
Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #9 on: December 31, 2010, 04:04:15 AM »

What do you mean by "Regular Project"? Have you tried it in a non Winforms based project? I.e. A web or dll class library?

Steve
Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #10 on: December 31, 2010, 06:06:10 AM »

What do you mean by "Regular Project"? Have you tried it in a non Winforms based project? I.e. A web or dll class library?

Steve

I followed your step sequence from the post above to create a Test Project and it flat out won't work. Completely fails initialization. In Winforms/WPF and dll projects it works just fine without a backing window.

Best regards,
Scott
Logged
sgoyette
Newbie
*
Offline Offline

Canada Canada

Posts: 7


View Profile
« Reply #11 on: January 03, 2011, 08:11:02 PM »

Ok, I figured this out.  The problem with a unit test, web or dll project (non winforms) is that there is no message pump and various creation and event handlers require this.  The solution is to do the following:


GeckoWebBrowser wb = new GeckoWebBrowser();
wb.CreateControl();
wb.DocumentCompleted += (x, y) =>
                                        {
                                            MessageBox.Show(wb.Url.AbsoluteUri);
                                        };

// This steps forces windows to process any events
while ( wb.IsBusy )
   System.Windows.Forms.Application.DoEvents();
wb.Navigate("www.google.com")
while ( wb.IsBusy )
   System.Windows.Forms.Application.DoEvents();

So that's fixed that problem.  Now I've gone onto other items and run into another problem.  I'm trying to use the GeckoHttpActivityObserver and am getting an exception that I can't catch (and probably wouldn't want to):

W, 50560, 13, 2011/01/03, 09:17:30.448, QTAgent32.exe, AgentExecution: Exception while calling TestAdapter.Run: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

To be clear, this has nothing to do with being in a unit test as running in a dll or even in a winforms application causes this same exception to be thrown.  The code is simple enought:

       GeckoHTTPActivityObserver.HttpActivityChanged += HttpActivityHandler;
       GeckoHTTPActivityObserver.Observe = true;   

        private static void HttpActivityHandler( object sender, GeckoHTTPActivityEventArgs e )
        {
            Debug.Write("HttpActivity::observeActivity ");
        }

What will happen is that it will run for a bit and dump the debug messages and then crash with the exception above.  If you turn off the observer everything works swimmingly.  It doesn't always stop in the same place and different URLs make no difference.

Any thoughts?

Steve
Logged
Scott
Imagineer - Developer
Administrator
Sr. Member
*****
Offline Offline

United States United States

Posts: 480



View Profile WWW
« Reply #12 on: January 04, 2011, 03:19:17 PM »

Ok, I figured this out.  The problem with a unit test, web or dll project (non winforms) is that there is no message pump and various creation and event handlers require this.  The solution is to do the following:

[_code_] ommitted
It's quite odd that you cannot get this to work outside of a window/form as I have successfully gotten it to work from a code block inside the control itself.

So that's fixed that problem.  Now I've gone onto other items and run into another problem.  I'm trying to use the GeckoHttpActivityObserver and am getting an exception that I can't catch (and probably wouldn't want to):
[_removed_] for brevity..

Http activity observer is something that I'll have to dig into further when I have the time. I know that there are some XR interface members that just love to dish out access violations at random times and this class uses a few of them.

Best Regards,
Scott
Logged
Pages: [1]
  Print  
 
Jump to: