WPF中直接打开网页方法总结

最近一段时间,由于新项目的需要,实验了一下,在WPF Application中打开网页的方法,现总结如下:

本人一共实验过4种方法:

第一种方法:使用框架提供的空间WebBrowser(详见http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.aspx)来实验网页的载入,显示和导航。特点是方便,易于实现。缺点是如果遇到IE7.0以上不兼容的网页,会造成显示不正常的问题;解决的方法是修改注册表中IE的Render mode ,使之兼容IE8,详见

http://blogs.msdn.com/b/ie/archive/2009/03/10/more-ie8-extensibility-improvements.aspx

第二种方法:使用其他第三方可以集成浏览器到WPF Application ActiveX组件,失败原因:一共找到两个组件。

一个是MozillaFirefox的组件(http://www.iol.ie/~locka/mozilla/mozilla.htm),该组件针对的Firefox版本太低,现在的网友没有实际的意义;

一个是Google Chrome Activex的组件(http://social.msdn.microsoft.com/Forums/en/wpf/thread/207139d2-ecd1-4b54-a94b-4eb340f95a19),在论坛上看到的,有人找到了,可是我没有找到。据称,该组件没有托管的。

第三种方法:基本思路是使用Process.Start("iexplore.exe", " www.msn.com.cn")打开一个IE的窗口,然后再使用SetParent将该新窗口并入WPF的主窗口中。代码如下(其他函数声明见附录):

代码     var process = Process.Start("iexplore.exe", " www.msn.com.cn");

            process.WaitForInputIdle();

              //让IE准备好

            Thread.Sleep(3000);

            var ieHandle = FindWindow("ieframe", null);

            SetParent(ieHandle, this.Handle);

            int style = GetWindowLong(ieHandle, GWL_STYLE);

   SetWindowLong(ieHandle, GWL_STYLE, (style & ~WS_CAPTION));

具体的思路是:

Create a WindowsFormsHost and add it to a panel in your UI

Start the process (such as Notepad) using Process.Start

扫描二维码关注公众号,回复: 1116705 查看本文章

Call process.WaitForInputIdle

Use process.MainWindowHandle to get the window handle

Call SetWindowPos to set the process's window to the coordinates and Z Order of the HwndHost window

Hook both the HwndHost and the process.MainWindowHandle to detect size changes and repeat step 5.

第四种方法:基本思路是使用反射获得IE对象(InternetExplorer Object

http://msdn.microsoft.com/en-us/library/aa752084%28v=vs.85%29.aspx),然后设置相应的属性,最后将打开的新IE窗体,并入WPF程序中。

代码            System.Type oType =System.Type.GetTypeFromProgID("InternetExplorer.Application");

            object o = System.Activator.CreateInstance(oType);

            o.GetType().GetMembers();

            o.GetType().InvokeMember("menubar",

                System.Reflection.BindingFlags.SetProperty, null, o, new object[] { 0 });

            o.GetType().InvokeMember("toolbar",

                System.Reflection.BindingFlags.SetProperty, null, o, new object[] { 0 });

            o.GetType().InvokeMember("statusBar",

                System.Reflection.BindingFlags.SetProperty, null, o, new object[] { 0 });

            o.GetType().InvokeMember("addressbar",

                System.Reflection.BindingFlags.SetProperty, null, o, new object[] { 0 });

            o.GetType().InvokeMember("Visible",

                System.Reflection.BindingFlags.SetProperty, null, o, new object[] { true });

            o.GetType().InvokeMember("Navigate",

                System.Reflection.BindingFlags.InvokeMethod, null, o, new object[] { 你的URL });

   

            var ieHandle = FindWindow("ieframe", null);

            SetParent(ieHandle, this.Handle);

            int style = GetWindowLong(ieHandle, GWL_STYLE);

   SetWindowLong(ieHandle, GWL_STYLE, (style & ~WS_CAPTION));

附录:

定义User32的定义,可以在http://www.pinvoke.net/index.aspx中找到


代码[DllImport("USER32.DLL")]

        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 

        //Sets a window to be a child window of another window

        [DllImport("USER32.DLL")]

        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

 

        //Sets window attributes

        [DllImport("USER32.DLL")]

        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

 

        //Gets window attributes

        [DllImport("USER32.DLL")]

        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

 

        [DllImport("user32.dll", SetLastError = true)]

        internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

 

        [DllImport("user32.dll")]

        private static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);

 

        [DllImport("user32.dll")]

 

        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

 

        /// <summary>Enumeration of the different ways of showing a window using

        /// ShowWindow</summary>

        private enum WindowShowStyle : uint

        {

            /// <summary>Hides the window and activates another window.</summary>

            /// <remarks>See SW_HIDE</remarks>

            Hide = 0,

            /// <summary>Activates and displays a window. If the window is minimized

            /// or maximized, the system restores it to its original size and

            /// position. An application should specify this flag when displaying

            /// the window for the first time.</summary>

            /// <remarks>See SW_SHOWNORMAL</remarks>

            ShowNormal = 1,

            /// <summary>Activates the window and displays it as a minimized window.</summary>

            /// <remarks>See SW_SHOWMINIMIZED</remarks>

            ShowMinimized = 2,

            /// <summary>Activates the window and displays it as a maximized window.</summary>

            /// <remarks>See SW_SHOWMAXIMIZED</remarks>

            ShowMaximized = 3,

            /// <summary>Maximizes the specified window.</summary>

            /// <remarks>See SW_MAXIMIZE</remarks>

            Maximize = 3,

            /// <summary>Displays a window in its most recent size and position.

            /// This value is similar to "ShowNormal", except the window is not

            /// actived.</summary>

            /// <remarks>See SW_SHOWNOACTIVATE</remarks>

            ShowNormalNoActivate = 4,

            /// <summary>Activates the window and displays it in its current size

            /// and position.</summary>

            /// <remarks>See SW_SHOW</remarks>

            Show = 5,

            /// <summary>Minimizes the specified window and activates the next

            /// top-level window in the Z order.</summary>

            /// <remarks>See SW_MINIMIZE</remarks>

            Minimize = 6,

            /// <summary>Displays the window as a minimized window. This value is

            /// similar to "ShowMinimized", except the window is not activated.</summary>

            /// <remarks>See SW_SHOWMINNOACTIVE</remarks>

            ShowMinNoActivate = 7,

            /// <summary>Displays the window in its current size and position. This

            /// value is similar to "Show", except the window is not activated.</summary>

            /// <remarks>See SW_SHOWNA</remarks>

            ShowNoActivate = 8,

            /// <summary>Activates and displays the window. If the window is

            /// minimized or maximized, the system restores it to its original size

            /// and position. An application should specify this flag when restoring

            /// a minimized window.</summary>

            /// <remarks>See SW_RESTORE</remarks>

            Restore = 9,

            /// <summary>Sets the show state based on the SW_ value specified in the

            /// STARTUPINFO structure passed to the CreateProcess function by the

            /// program that started the application.</summary>

            /// <remarks>See SW_SHOWDEFAULT</remarks>

            ShowDefault = 10,

            /// <summary>Windows 2000/XP: Minimizes a window, even if the thread

            /// that owns the window is hung. This flag should only be used when

            /// minimizing windows from a different thread.</summary>

            /// <remarks>See SW_FORCEMINIMIZE</remarks>

            ForceMinimized = 11

        }

 

        public const UInt32 WS_POPUP = 0x80000000;

        //assorted constants needed

        public static int GWL_STYLE = -16;

        public static int WS_CHILD = 0x40000000; //child window

        public static int WS_BORDER = 0x00800000; //window with border

        public static int WS_DLGFRAME = 0x00400000; //window with double border but no title

        public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar

 

        public const UInt32 WS_THICKFRAME = 0x40000;

 

 

        public const UInt32 WS_SIZEBOX = WS_THICKFRAME;

 

        [StructLayout(LayoutKind.Sequential)]

        public struct RECT

        {

            public int Left;

            public int Top;

            public int Right;

            public int Bottom;

        }

 

        [DllImport("user32.dll")]

        static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);

备注:

1)         在一定的情况下,可以使用IEK模式满足用户的要求,不必一定要嵌入自己的程序中。详见http://support.microsoft.com/kb/154780

2)         在寻找的过程中,找了一下开源的项目,看有没有现成的wpf浏览器,结果没有找到。涉及的项目有Chromium WebBrowser WPFWebBrowserExwebbrowserc++adhoc

3)         在寻找的过程中,看到有人用WebApp.hta来实现网页的解析和载入,不过还是存在不兼容IE8.0的问题;


如果是直接调用默认浏览器打开网页建议使用进程直接打开,在这里可能会出现两种情况,如果这个链接是经过编码的打开网页后可能会出现乱码,在这里分享一下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SoftRGB.Controls
{
    public static class AppServices
    {
        /// <summary>
        /// 直接打开Uri类型的链接(经过转码后的string再经过tostring()会出现乱码,用另一个方法)
        /// </summary>
        /// <param name="uri"></param>
        public static void OpenUri(Uri uri)
        {
            if (uri != null)
            {
                try
                {
                    System.Diagnostics.Process.Start(uri.ToString());
                }
                catch
                {
                    RGBMessageBox.Show("网址是:" + uri.ToString(), "网络浏览器调用失败,请确定你的电脑中安装了网络浏览器!", RGBMesType.Warn);
                }
            }
        }

        /// <summary>
        /// 直接打开string类型的链接(可以是经过转码后的链接)
        /// </summary>
        /// <param name="uri"></param>
        public static void OpenUri(string uri)
        {
            if (!string.IsNullOrEmpty(uri))
            {
                try
                {
                    System.Diagnostics.Process.Start(uri);
                }
                catch
                {
                    RGBMessageBox.Show("网址是:" + uri.ToString(), "网络浏览器调用失败,请确定你的电脑中安装了网络浏览器!", RGBMesType.Warn);
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_23018459/article/details/80229481
今日推荐