注:本文适用.net 2.0+的winform项目

目的:

  • 点击页面中的target="_blank"链接时,弹出新窗体
  • 页面中有window.close()操作时,关闭窗体

上述窗体是指WebBrowser所在的Form,基本上,上述目的就是让该窗体表现得像个正常浏览器而已。

一、弹出新窗体

WebBrowser(下称wb)自带NewWindow事件,所以直接注册该事件即可:

private void wb_NewWindow(object sender, CancelEventArgs e)
{
e.Cancel = true;//这句加不加在我的环境里没区别,不加也不会导致打开外部浏览器
new FmWebBrowser(wb.StatusText).Show(); //FmWebBrowser即我的承载wb的窗体,本类构造函数接受一个url,Show之后会令wb访问该url。另外,该事件进入时,wb的StatusText几乎可以断定就是所点链接的href,极端情况以后遇到再说
}

二、响应页面中的window.close以关闭本窗体

由于wb没有现成的Close之类的事件,所以这个要稍稍折腾一下,就是给它加上这个事件,核心要解决的问题,就是让wb知道页面执行了window.close(),解决了这个,剩下就是把这事通知出去而已。

  1. 让wb知道页面执行了window.close(),并引发特定事件

    方法是网上抄的,原理是页面执行window.close()时wb会收到一个特定的win32消息,于是可以重载wb的WndProc方法来处理这个消息,这就需要继承wb写一个子类,子类如下:

    using System;
    using System.Security.Permissions;
    using System.Windows.Forms; namespace AhDung.WinForm.Controls
    {
    /// <summary>
    /// 增强型浏览器
    /// </summary>
    public class WebBrowserEx : WebBrowser
    {
    /// <summary>
    /// 当WebBrowser关闭后
    /// </summary>
    public event EventHandler WindowClosed; protected void OnWindowClosed(EventArgs e)
    {
    if (WindowClosed != null) { WindowClosed(this, e); }
    } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == 0x210/*WM_PARENTNOTIFY*/)
    {
    int wp = m.WParam.ToInt32(); int X = wp & 0xFFFF;
    if (X == 0x2/*WM_DESTROY*/)//若收到该消息,引发WindowClosed事件
    {
    OnWindowClosed(EventArgs.Empty);
    }
    } base.WndProc(ref m);
    }
    }
    }
  2. 剩下就简单了,宿主窗体响应WebBrowserEx的WindowClosed事件,关闭自身就好。当然首先要把之前的WebBrowser换成上述WebBrowserEx,代码段:
    private WebBrowserEx wbex = new WebBrowserEx();
    ... public FmMain()
    {
    wbex.WindowClosed += wbex_WindowClosed;
    ...
    } void wbex_WindowClosed(object sender, System.EventArgs e)
    {
    this.Close();
    }

- 文毕 -

【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体的更多相关文章

  1. 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘

    [C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...

  2. JavaScript-打开新窗口(window.open)和 关闭窗口(window.close)

    JavaScript-打开新窗口 open() 方法可以查找一个已经存在或者新建的浏览器窗口. 语法: window.open([URL], [窗口名称], [参数字符串]) 参数说明: URL:可选 ...

  3. vue中$router.push打开新窗口

    在vue中使用 this.$router.push({ path:  '/home' }) 默认是替代本窗口 如果想新开一个窗口,可以使用下面的方式: let routeData = this.$ro ...

  4. JavaScript-打开新窗口

    open()方法可以查找一个已经存在或者新建一个新的浏览器窗口. 语法:window.open([URL], [窗口名称], [参数字符串]) 参数解释: URL:可选参数,在窗口中显示网页的网址或路 ...

  5. JS页面跳转和打开新窗口方式

    1.window.location.href=URL : 在本窗体打开一个新的页面,也是最常用的一种方法: 2.window.open(URL)  :  在一个新的窗口打开一个新的页面: 3.loca ...

  6. C# webBrowser 开新窗口保持Session(转)

    首先为项目添加引用 Microsoft Internet Controls public Form1() { InitializeComponent(); this.webBrowser1.Allow ...

  7. HTML页面中解决内容元素随窗口变化布局变乱问题

    1.给body加上一个min-width最小宽度,以px为单位,这样当页面变小时,当达到你所设置的最小宽度,body的宽度不再改变,超出的部分会用横向滚动条显示,其内所有元素的布局也不会受影响. 2. ...

  8. 使“Cmder Here”菜单在Tab页开新窗口

    Cmder是一个非常好用的的控制台命令行,我们在实际使用的时候,经常通过如下指令将其注册到右键菜单: Cmder.exe /REGISTER ALL 这样就可以在任意文件夹下快速打开Cmder,并且能 ...

  9. 【JS学习】慕课网2-7 练习题:制作新按钮,“新窗口打开网站” ,点击打开新窗口。

    要求: 1.新窗口打开时弹出确认框,是否打开 提示: 使用 if 判断确认框是否点击了确定,如点击弹出输入对话框,否则没有任何操作. 2.通过输入对话框,确定打开的网址,默认为 http://www. ...

随机推荐

  1. ASP.NET MVC开发:Web项目开发必备知识点

    最近加班加点完成一个Web项目,使用Asp.net MVC开发.很久以前接触的Asp.net开发还是Aspx形式,什么Razor引擎,什么MVC还是这次开发才明白,可以算是新手. 对新手而言,那进行A ...

  2. 【云知道】LoadRunner 录制问题集锦

    关键词:各路录制小白汇集于此 虽然知道君对录制不感冒,但总是看到扎堆的人说这些问题,忍不住要站出来了. 百度虽好,帮助了很多小白,但关键是百度并没有排除错误内容,经过历史的几年传播,错的都快变对的了, ...

  3. 使用Git Bash远程添加分支和简单部署你的静态页面

    新建一个分支:git branch mybranch(mybranch你的分支名字) 切换到你的新分支: git checkout mybranch 将新分支发布在github上: git push ...

  4. ViewController respondsToSelector 错误的解决方法

    原因解析:(来自别人博客分析)某个公共类或系统提供的控件,存在delegate方法,当创建此公共控件的容器类已经销毁,而这个控件对应的服务是在其它run loop中进行的,控件销毁或者需要进行状态通知 ...

  5. 基于select的python聊天室程序

    python网络编程具体参考<python select网络编程详细介绍>. 在python中,select函数是一个对底层操作系统的直接访问的接口.它用来监控sockets.files和 ...

  6. 判断一个对象是jQuery对象还是DOM对象

    今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...

  7. Sass用法指南

    写在前面的话:随着CSS文件越来越大,内容越来越复杂,对其进行很好的维护将变的很困难.这时CSS预处理器就能够帮上大忙了,它们往往拥有变量.嵌套.继承等许多CSS不具备的特性.有很多CSS预处理器,这 ...

  8. 如何在 TFS 中使用 Git

    对 Charley Blog 的代码进行版本控制的想法由来已久,在代码建立之初其实已经使用过 TFS 进行控制,只是后期没能好好用起来,加之后来系统环境的变化导致TFS连接丢失,便算是正式放弃了版本控 ...

  9. 关于python中的flush问题

    今天写了一个控制台下的进度条小程序,遇到了关于flush的问题,在这里小小的总结一下. 首先在要flush的字符串必须后边加上'\r'(回车) 将数据送入缓冲区这样在新打印字符的时候就可以将原来的显示 ...

  10. iOS实现UICollectionViewDataSource与Controller的分离

    之前每次用到UICollectionView的时候都会都需要在Controller里面去实现DataSource & Delegate方法 单独Delegate方法还好不是很多, 但是再加上D ...