网上有很多嵌入的解决方案,这边记录一个整理较好的网站https://www.cnblogs.com/SavionZhang/p/15169863.html
我自己测试了chrome内核和ie内核去加载Web,ChromiumWebBrowser不存在该问题。这里针对IE内核,也就是WPF自带的Web嵌入组件WebBrowser,在实现窗口自定义的时候,会让网页不显示的问题做出解决方案。一般我们的创久自定义都会设置WindowStyle="None" AllowsTransparency="True"
,问题就在AllowsTransparency这个窗口属性上,当我们将它设置为true,因为WPF的渲染绘制机制会绘制不出加载的Web页面(内容有但是没有UI)。因此这里需要这样设置WindowStyle="None" AllowsTransparency="False" ResizeMode="CanMinimize"
,AllowsTransparency=“False” 时会是我们的窗口自定义样式出现原本窗口的背景,这个时候就需要ResizeMode=“CanMinimize”。但同时,也会让自己的窗口无法拖拽大小。这里可以自己去实现以下拖拽大小的代码:
在窗口的最外层增加一圈
然后在定义的这一圈上加上
对应的响应方法为:
public HwndSource _HwndSource;
private const int WM_SYSCOMMAND = 0x112;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private Dictionary cursors = new Dictionary
{
{ResizeDirection.Top, Cursors.SizeNS},
{ResizeDirection.Bottom, Cursors.SizeNS},
{ResizeDirection.Left, Cursors.SizeWE},
{ResizeDirection.Right, Cursors.SizeWE},
{ResizeDirection.TopLeft, Cursors.SizeNWSE},
{ResizeDirection.BottomRight, Cursors.SizeNWSE},
{ResizeDirection.TopRight, Cursors.SizeNESW},
{ResizeDirection.BottomLeft, Cursors.SizeNESW}
};
void Window_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (Mouse.LeftButton != MouseButtonState.Pressed)
{
FrameworkElement element = e.OriginalSource as FrameworkElement;
if (element != null && !element.Name.Contains("Resize")) this.Cursor = Cursors.Arrow;
}
}
catch (Exception ex)
{
LogOutput.WriteErrorLog("Window_MouseMove error : " + ex.Message);
}
}
private void ResizePressed(object sender, MouseEventArgs e)
{
try
{
FrameworkElement element = sender as FrameworkElement;
ResizeDirection direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), element.Name.Replace("Resize", ""));
this.Cursor = cursors[direction];
if (e.LeftButton == MouseButtonState.Pressed) ResizeWindow(direction);
}
catch (Exception ex)
{
LogOutput.WriteErrorLog("ResizePressed Move error : " + ex.Message);
}
}
private void ResizeWindow(ResizeDirection direction)
{
try
{
var _vm = this.DataContext as AppStoreUIViewModel;
var handle = AppStoreUIViewModel.FindWindow(null, "uMRAppStore");
SendMessage(handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
}
catch (Exception ex)
{
LogOutput.WriteErrorLog("ResizeWindow error : " + ex.Message);
}
}
private void ResizePressed(object sender, MouseButtonEventArgs e)
{
try
{
FrameworkElement element = sender as FrameworkElement;
ResizeDirection direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), element.Name.Replace("Resize", ""));
this.Cursor = cursors[direction];
if (e.LeftButton == MouseButtonState.Pressed) ResizeWindow(direction);
}
catch(Exception ex)
{
LogOutput.WriteErrorLog("ResizePressed Btn error : " + ex.Message);
}
}
可见IE的繁琐性,所以还是建议使用Chorme,如果平台不做限制,可以使用较新的EDGE的内核控件。
因项目限制,所以我后面用的都是IE内核的。在使用的过程中发现,加载网页后,会出像两个问题。
一个是安全协议报错。这里我才去的是跳过策略校验。增加辅助类:
public static class WebBrowserExtensions
{
///
/// 过滤网页加载错误信息弹窗
///
///
///
public static void SuppressScriptErrors(this WebBrowser webBrowser, bool hide)
{
try
{
FieldInfo fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
if (fiComWebBrowser == null) return;
object objComWebBrowser = fiComWebBrowser.GetValue(webBrowser);
if (objComWebBrowser == null) return;
objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide });
}
catch(Exception ex)
{
LogOutput.WriteErrorLog("SuppressScriptErrors error : " + ex.Message);
}
}
}
在每个加载网页的地方 WebBrowserExtensions.SuppressScriptErrors(AppStoreWindow.detial.wb, true);
另一个问题就是会弹出“安全警报”窗口,这里我的处理是增加一个定时器,在弹出时进行快速关闭:
timerCheckWebAlert.Interval = 20;
timerCheckWebAlert.Enabled = true;
timerCheckWebAlert.Elapsed += new System.Timers.ElapsedEventHandler(TimerCheckWebAlert_Elapsed);
//使用定时器来检查是否出现窗口,如果有就关闭
private void TimerCheckWebAlert_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
IntPtr hwnd = FindWindow(null, "安全警报");
if (hwnd != IntPtr.Zero)
{
IntPtr btnhwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "是(&Y)");
if (btnhwnd != IntPtr.Zero)
{
SendMessage(btnhwnd, WM_CLICK, 0, 0);//先移上去
SendMessage(btnhwnd, WM_CLICK, 0, 0);//再点击
}
}
IntPtr hwndweb = FindWindow(null, "Web 浏览器");
if (hwndweb != IntPtr.Zero)
{
IntPtr btnhwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "是(&Y)");
if (btnhwnd != IntPtr.Zero)
{
SendMessage(btnhwnd, WM_CLICK, 0, 0);
SendMessage(btnhwnd, WM_CLICK, 0, 0);
}
}
IntPtr hwndEn = FindWindow(null, "security alert");
if (hwndEn != IntPtr.Zero)
{
IntPtr btnhwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "是(&Y)");
if (btnhwnd != IntPtr.Zero)
{
SendMessage(btnhwnd, WM_CLICK, 0, 0);
SendMessage(btnhwnd, WM_CLICK, 0, 0);
}
}
}
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private int WM_CLICK = 0x00F5;
[System.Runtime.InteropServices.DllImport("user32")]
public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动鼠标
public const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
public const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
public const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
public static extern bool SetF(IntPtr hWnd); //设置此窗体为活动窗体
这里也是在GitHub上看到了一个大神自己重构了一下CefSharp的库,直接替换本地的packages下就可以了。
这里GitHub上的包下了,大家可以尝试再去找找。这里有个CSDN的包,大家可以尝试。https://blog.csdn.net/ldy597321444/article/details/84677752?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-9-84677752-blog-120221096.pc_relevant_3mothn_strategy_and_data_recovery&spm=1001.2101.3001.4242.6&utm_relevant_index=12