WatiN and .net winforms WebBrowser control - is DialogWatcher possible?

筅森魡賤 提交于 2019-11-29 02:39:31

I have just upgraded to newest version of WatiN (head revision - 1166 - in trunk: https://watin.svn.sourceforge.net/svnroot/watin/trunk/src/). Since there was a change in original DialogWatcher class it is now possible to use existing DialogWatcher with fewer code.

Create class:

public class WebBrowserIE : IE
{
    private IntPtr hwnd;

    public WebBrowserIE(WebBrowser webBrowserControl)
        : base(webBrowserControl.ActiveXInstance, false)
    {
        hwnd = webBrowserControl.FindForm().Handle;
        StartDialogWatcher();
    }

    public override IntPtr hWnd
    {
        get
        {
            return hwnd;
        }
    }

    protected override void Dispose(bool disposing)
    {
        hwnd = IntPtr.Zero;
        base.Dispose(disposing);
    }
}

Use it instead of original IE class and see disappearing javascript alert dialog:

var ie = new WebBrowserIE(webBrowser1);
var thread = new Thread(() =>
{
    ie.GoTo("http://www.plus2net.com/javascript_tutorial/window-alert.php");
    ie.Button(Find.ByValue("Click here to display alert message")).Click();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

Warning: Create WebBrowserIE instance outside the thread. Otherwise you will have to modify this class to avoid cross-thread operation when reading Handle property of Form.

prostynick

Oh man, this question comes up so many times and I always writing something like: But with a little bit of hacking you can create your own based on original DialogWatcher class (from: How to use watin with WebBrowser control?), so I dug in my source code to find it and I will just show how I did it. Maybe it's not perfect, but it works and I didn't have any problems with it.

  1. Create FormDialogWatcher class by copying original DialogWatcher, changing class name, namespace etc.
  2. I have deleted following fields and methods from original class. This is probably not needed, but you will probably use only one instance of WebBrowser controll, so you don't really need this code and I am not sure if it will work properly after the changes without deleting this. To delete:

    • private static IList<DialogWatcher> dialogWatchers
    • public static DialogWatcher GetDialogWatcher(IntPtr mainWindowHwnd)
    • public static DialogWatcher GetDialogWatcherFromCache(IntPtr mainWindowHwnd)
    • public static void CleanupDialogWatcherCache()
    • public void IncreaseReferenceCount()
    • public void DecreaseReferenceCount()
    • public int ReferenceCount { get; private set; }
    • private bool IsWindowOfIexploreProcess(Window window)
  3. In Start() method replace this:

    if (new Window(MainWindowHwnd).Exists())
    {
        var winEnumerator = new WindowsEnumerator();
        var windows = winEnumerator.GetWindows(win => true);
    

    with this:

    var mainWindow = new Window(MainWindowHwnd);
    if (mainWindow.Exists())
    {
        var winEnumerator = new WindowsEnumerator();
        var windows = winEnumerator.GetWindows(window => window.ProcessID == mainWindow.ProcessID);
    

    (the only real difference is inside GetWindows call)

  4. In HandleWindow(Window window) remove this line:

    if (!IsWindowOfIexploreProcess(window)) return;
    

That's all! To start it, just create it: new FormDialogWatcher(Handle) where Handle is just a property of Form. You can probably create it after creating IE object in your example code (LOL, I've just figured out, that there is my nick name in question :)) - Form_Load or something like that. It will start immediately (see constructor) and the main loop will break after the window cease to exist.

EDIT: Be aware that if you set this class (or WatiN settings) to close unhandled dialogs, then even your MessageBox.Show will be closed :)

EDIT 2 (important!): Whole explanation above is related to original DialogWatcher class taken from WatiN SVN trunk revision 1056. Direct link to this revision and file: http://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision=1056&content-type=text/plain&pathrev=1056

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!