Welcome Guest Search | Active Topics | Sign In | Register

Issue when working with popup Options
ozheek
Posted: Friday, November 4, 2016 9:12:25 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
I am catching event when new window are created and starting working with new created WebView.

But problem when I am trying to Capture() image of the WebView it returns null.
GetContentAreaSize() and GetScrollOffset() are always (0,0);

Tested with http://www.popuptest.com/
ozheek
Posted: Friday, November 4, 2016 9:55:13 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
I tried to make test project and found it works correctly.

Proably something with configuration in my app. I am investigation it.

Intersting that Handle of created window is 0, when page is loaded correctly, I use URL and can get HTML of the document:
http://prntscr.com/d38zwv

Maybe you can give me advice what is wrong?
ozheek
Posted: Friday, November 4, 2016 9:59:07 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
Wehn I capture image with parameters Capture(new Rectangle(0, 0, Width, Height)) it returns image instead of null.
ozheek
Posted: Friday, November 4, 2016 10:13:46 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
I found why it happens. If I created webview with specific Width and Height:
WebView view = runner.CreateWebView(1000, 1000);

then issue that I described above will appear. If I created WebView without width and height it works good.

If you need, I can make a test project.

eo_support
Posted: Saturday, November 5, 2016 6:34:32 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Sure. Please create a test project and send it to us.

Thanks!
ozheek
Posted: Saturday, November 5, 2016 6:56:14 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
I have sent you a test project, please check it.
eo_support
Posted: Thursday, November 10, 2016 8:54:17 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

We have looked into the test project you sent to us. The root of the problem you are accessing the WebView in two different threads and created a race condition in your code. Specifically, NewWindow event is fired does not mean the new WebView is ready. In fact the flow is like this:

1. User or code tries to open a new window in an existing WebView;
2. A new WebView is created but not initialized;
3. NewWindow is fired and user accept the new WebView (or user can choose not to accept it and the flow ends here);
4. The new WebView is initialized;

The key here is the WebView is initialized after NewWindow is fired. If you access the new WebView in another thread between step 3 and step 4 it will fail.

Generally, you should not access the same WebView from multiple threads because the WebView is thread specific. In your case, you can try to enclose the call inside ThreadRunner.Send, that will marshal the call to the ThreadRunner's thread and it will only be called after step 4. That should resolve the issue for you.

Thanks!
ozheek
Posted: Thursday, November 10, 2016 9:55:07 AM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
Hi,

probably you didn't understand the issue. I changed the code, make all requests via ThreadRunner.Send(), wait till WebView is created and loaded. It still doesn't help. And I think it won't help as if I create view in other way it works.

WebView view = runner.CreateWebView(); // It works
WebView view = runner.CreateWebView(1000, 1000); // It doesn't work

In any case I fixed the issue by myself, I create WebView without specifying the size of it and later I just resize it.
eo_support
Posted: Thursday, November 10, 2016 10:04:26 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
I don't think you understand what we tried to tell you. The issue does not have anything to do with the WebView size. It's a racing condition in two different threads in your code that is triggered by certain timing sequence. When you create the WebView in a different size, it changes the amount of time certain steps takes (for example, a larger WebView takes more time to do the initial rendering). That timing change triggers the racing conditions that you run into. Without fixing the racing condition itself, it can still manifest in all sorts of different scenarios --- for example, you might run into the same problem when you run the code on a slower or faster machine, or when somehow the computer "choke" for a second due to a background task while you are creating the WebView. All these can change the timing sequence of your code and trigger the same problem that you thought you "fixed" by creating a WebView without specifying size.

Unless you are extremely familiar with such multi-thread problems, a good start for you is to put everything inside ThreadRunner.Send so that they all run inside a single thread. If you still run into problems, we can then look into that and help you further.
ozheek
Posted: Thursday, November 10, 2016 9:36:23 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
Thank you for the explaining. Probably I described the issue not correctly. If you checked my code, you can see that I create WebView and access it methods from a single thread. Moreover I tried to wrap everything in ThreadRunner.Send() and I still receive the same issue.

If you can change my code and send me back the correct version, probably I can understand better what's wrong. For now tried everything (sleeping after WebView created, waiting while WebView created, using ThreadRunner, using single thread etc.) and it doesn't work for me.

In any case I fixed the issue for myself and it works, I tested it in multi threads with different sizes of WebViews and websites, will do more tests as you advised.

eo_support
Posted: Friday, November 11, 2016 8:52:14 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

The root of the problem is when you call WebView.Capture, the WebView is not ready yet. We will look into this and see if we can provide an easy way to make sure/check whether the WebView is ready.

Thanks!
ozheek
Posted: Friday, November 11, 2016 8:55:08 AM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
Hi,

bu if WebView is not ready why it allows me to load url? Moreover I can execute JavaScript code and receive HTML of the document, for example.
eo_support
Posted: Friday, November 11, 2016 8:57:40 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

The first WebView (the "view" variable in your code) is ready. The second WebView (the "_newWebView" variable in your code) is NOT ready when you call _newWebView.Capture(). That's why image2 is null and this is what caused the NullReferenceException.

Thanks!
ozheek
Posted: Friday, November 11, 2016 9:04:39 AM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
If WebView is not ready, can I still execute JavaScript or other methods?

Before calling Capture() I called var html = _newWebView.GetHtml(); and received the HTML of the WebView.
eo_support
Posted: Friday, November 11, 2016 9:12:06 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

It's possible. In order for the WebView to be ready for capture, the DOM/JavaScript engine has to be ready first, then the internal window is initialized and the actual layout/rendering/buffer is built/updated. Because the browser engine is optimized for speed, it often delay rendering when its still busy with other things. That means the browser engine is ready to run JavaScript before it can ever "display" anything at all. If you call capture in this state, then you will receive null.

Thanks!
ozheek
Posted: Friday, November 11, 2016 9:32:50 AM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
Thank you, now it's totally clear for me.

The question is how to know if WebView is ready for capturing the image? As I understood you don't have a solution for that now?
eo_support
Posted: Friday, November 11, 2016 9:46:56 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

For your particular case you can use LoadCompleted:

Code: C#
void view_NewWindow(object sender, NewWindowEventArgs e)
{
    _newWebView = e.WebView;
    e.Accepted = true;
    _newWebView.LoadCompleted += (sender2, e2) =>
    {
        System.Drawing.Image image = _newWebView.Capture();
        ...save the image....
    };
}



In our next build you will be able to use:

Code: C#
void view_NewWindow(object sender, NewWindowEventArgs e)
{
    _newWebView = e.WebView;
    e.Accepted = true;
    _newWebView.QueueScriptCall(() =>
    {
        System.Drawing.Image image = _newWebView.Capture();
        ...save the image....
    });
}


The difference between these two is usually QueueScriptCall will be done much sooner than LoadCompleted. So you will be able to use this method if you want to capture screen shot as soon as possible.

Thanks!
ozheek
Posted: Friday, November 11, 2016 5:23:48 PM
Rank: Advanced Member
Groups: Member

Joined: 8/29/2016
Posts: 64
I tried the first code and it still returns null when I try to Capture. Have you tried to change my test project and it works for you?

I really like the idea of the second code, I can use it in many variations. Looking forward to try it.
eo_support
Posted: Saturday, November 12, 2016 12:47:22 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

We have posted a new build. We tested this build with your test app for both cases (LoadCompleted and QueueScriptCall) and they work fine. If you still have problems, please send us an updated test app and we will investigate further.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.