WebBrowser в WPF все еще открывает ссылку в новом окне - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу создать навигацию "в браузере", при которой при нажатии на ссылку, которая будет отображаться в новом окне (IE), я хочу, чтобы она отменялась, и вместо этого проводилась навигация в браузере.У меня есть поиск и я следую некоторым руководствам, но не могу запретить навигацию по окну в браузере.Вот что я делаю: -

Пример ссылки.

XAML: -

<WebBrowser Name="HostWeb" Navigating="HostWeb_Navigating" LoadCompleted="HostWeb_LoadCompleted" DockPanel.Dock="Top"/>

CS: -

using mshtml;
    public partial class MainWindow : Window
    {
        Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
        public MainWindow()
        {
            InitializeComponent();
            HostWeb.Navigate("https://www.booking.com");
        }

    private void HostWeb_Navigating(object sender, NavigatingCancelEventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                ProgressGrid.Visibility = Visibility.Visible;
                if (e.Uri.OriginalString == "https://www.booking.com/content/terms.html")
                {
                    // Cancel navigation of this URL. This will be load into Generic List to find with LINQ
                    e.Cancel = true;
                }
                else
                {
                    NavigatedURI = e.Uri.OriginalString;
                }
            }), DispatcherPriority.Background);
        });
    }
    private void HostWeb_LoadCompleted(object sender, NavigationEventArgs e)
    {

        Task.Factory.StartNew(() =>
        {
            ProgressGrid.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { ProgressGrid.Visibility = Visibility.Hidden; }));

            IServiceProvider serviceProvider = (IServiceProvider)HostWeb.Document;
            Guid serviceGuid = SID_SWebBrowserApp;
            Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
            SHDocVw.IWebBrowser2 myWebBrowser2 = (SHDocVw.IWebBrowser2)serviceProvider.QueryService(ref serviceGuid, ref iid);
            SHDocVw.DWebBrowserEvents_Event wbEvents = (SHDocVw.DWebBrowserEvents_Event)myWebBrowser2;
            wbEvents.NewWindow += new SHDocVw.DWebBrowserEvents_NewWindowEventHandler(OnWebBrowserNewWindow);
        });
    }

    void OnWebBrowserNewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
    {
        Processed = true;
        HostWeb.Navigate(URL);
    }

    private void BrowseBack_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = ((HostWeb != null) && (HostWeb.CanGoBack));
    }
    private void BrowseBack_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        HostWeb.GoBack();
    }
    private void BrowseForward_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = ((HostWeb != null) && (HostWeb.CanGoForward));
    }
    private void BrowseForward_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        HostWeb.GoForward();
    }
    private void GoToHome_Click(object sender, RoutedEventArgs e)
    {
        HostWeb.Navigate("https://www.booking.com");
    }
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
   [return: MarshalAs(UnmanagedType.IUnknown)]
   object QueryService(ref Guid guidService, ref Guid riid);
}

Второй подход - я не могу его завершить, потому что HostWeb.ActiveXInstance;не существует в SHDocVw: -

Пример ссылки.

using SHDocVw;

public MainWindow()
{
    InitializeComponent();
    WebBrowser_V1 axBrowser = (WebBrowser_V1)HostWeb.ActiveXInstance;
    axBrowser.NewWindow += AxBrowser_NewWindow;
    HostWeb.Navigate("https://www.booking.com");
}

private void HostWeb_LoadCompleted(object sender, NavigationEventArgs e)
{

    Task.Factory.StartNew(() =>
    {
        ProgressGrid.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { ProgressGrid.Visibility = Visibility.Hidden; }));

        HTMLDocument htmlDoc = (HTMLDocument)HostWeb.Document;
        IHTMLElementCollection htmlElementCollection = htmlDoc.getElementsByTagName("A");

        //Set All Anchore Target As _self For Stop Opening New Window......
        foreach (IHTMLElement curElement in htmlElementCollection)
        {
            string targetAtt = curElement.getAttribute("target");
            if (targetAtt == "_blank" || targetAtt == "_top" || targetAtt == "_parent" || targetAtt == "Array")
            {
                curElement.removeAttribute("target");
                curElement.setAttribute("target", "_self");
            }
        }
    });
}
void AxBrowser_NewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
{
    // cancel the PopUp event  
    Processed = true;
    // send the popup URL to the WebBrowser control  
    HostWeb.Navigate(URL);
}

Пример использования Booking.com веб, как предотвратить открытие новоговкладка / новое окно до того, как оно откроется, и перейдите по нему через текущий браузер (открыть новую вкладку / окно на текущей странице)?

ДОПОЛНИТЕЛЬНО: Учитывая booking.comНа странице, имеющей 4 основных меню [Проживание, Авиабилеты, Прокат автомобилей, Такси в аэропорту], при нажатии ни на одну из них, она не появится, и не попадет на события HostWeb_Navigating.

1 Ответ

0 голосов
/ 25 февраля 2019

Пожалуйста, обратитесь к этой статье TechNet .

Вы добавляете ссылку на COM-> Microsoft Internet Controls и обрабатываете событие LoadCompleted:

static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
    [return: MarshalAs(UnmanagedType.IUnknown)]
    object QueryService(ref Guid guidService, ref Guid riid);
}

private void WebBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
    IServiceProvider serviceProvider = (IServiceProvider)webBrowser.Document;
    Guid serviceGuid = SID_SWebBrowserApp;
    Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
    SHDocVw.IWebBrowser2 myWebBrowser2 = (SHDocVw.IWebBrowser2)serviceProvider.QueryService(ref serviceGuid, ref iid);
    SHDocVw.DWebBrowserEvents_Event wbEvents = (SHDocVw.DWebBrowserEvents_Event)myWebBrowser2;
    wbEvents.NewWindow += new SHDocVw.DWebBrowserEvents_NewWindowEventHandler(OnWebBrowserNewWindow);
}

private void OnWebBrowserNewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers,
    ref bool Processed)
{
    Processed = true;
    webBrowser.Navigate(URL);
}

XAML:

<WebBrowser x:Name="webBrowser" Source="http://booking.com" LoadCompleted="WebBrowser_LoadCompleted" />
...