欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
.Net 虚拟框架的实现原理 DNGuard HVM 专业版 v2.7 正式发布。
未知  form关闭时的一个奇特现象
[ 发布日期:17年前 (2007-09-21) ]   [ 来自:rick@博客园 ] [分类:C# .Net编程]
今天查一个错误时发现这个问题。

有一个frmEdit。在Closing事件里面判断数据是否修改,然后提示用户是否需要保存数据。

提供了三个按钮,yes,no,cancel。

yes:保存数据,关闭窗体。

no:直接关闭窗体。

cancel:不关闭窗体。
实际运行,点yes,cancel,处理都对,但是点 no,就会重复弹出这个对话框,

如果一直点 no的话,就会一直出现。
看一眼代码没有发现明显问题,实际调试才发现问题所在。

代码如下:
private void frmEdit_Closing(object sender, System.ComponentModel.CancelEventArgs e)

{

 if(DataChanged)

 {

  DialogResult dr=MessageBox.Show(this,"数据已修改,是否保存?", this.Text,MessageBoxButtons.YesNoCancel,MessageBoxIcon.Information,MessageBoxDefaultButton.Button3);

  if(dr==DialogResult.Yes)

  {

   SaveData();   

  }

                else if (dr == DialogResult.No)

                {

                    this.Close();

                }

           else

                 e.Cancel = true;

 }

}
经调试发现 是 this.Close() 的问题,在执行这个函数后,程序有进这个事件处理过程了。

修正方式很简单,注释掉这句代码就 OK 了。
估计在 form的close函数调用了 closing事件。

用reflector看了一下其代码。

处理方式:

close里面判断窗体是否已经创建,如果已经创建则 SendMessage(0x10, 0, 0);
然后窗体消息处理函数收到这个msg会 调用 wmclose 函数。

wmclose 调用了 OnClosing 函数,然后触发了 OnClosing事件。
除了这些还有一些很奇特的现象:

实际上调用是嵌套的,我在 this.Close();后面加上一句 MessageBox.Show(e.Cancel.ToString());
然后第一次点 no,第二次 点 cancel。

点完 Cancel 之后会看到 msgbox 提示信息是 False。

说明又在第一次事件处理过程中了,而且 e.Cancel仍然是 False

可是这样 窗体确仍然没有关闭
最奇怪的是第二个现象[/b]:

窗体上放了一个 exit的按钮,把按钮设置为 form 的 CancelButton。

进行了前面的操作之后,再点这个 exit 的按钮, closing 事件不触发了,窗体直接关闭了
如果不是点 exit 按钮,而是点右上角的 X 按钮,就能够再次触发 closing 事件。

然后就又和前面一样了。




2007-09-21 12:29 Kevin Zhong
else if (dr == DialogResult.No)
{
this.Close();
}
Closing已经是Close的过程了,所以不能再用Close



2007-09-21 11:50 TTT
要想拦截窗体关闭,重写窗体的WndProc就行了,不管以什么方式关,不会有任何问题,,干嘛搞这么麻烦。
另外你说的也不是什么奇怪现像。少见多怪还放首页上。

protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0112 && (int)m.WParam == 0xf060)
{
DialogResult dr = MessageBox.Show("真的要关闭吗?", "关闭程序", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dr == DialogResult.No)
{
return;
}
}
base.WndProc(ref m);
}




2007-09-21 14:32 TTT
@瑞克
关于你的第二个问题,我很奇怪,奇怪的是我并没有发现些问题,一切都很正常,closing closed事件都正常的发生,不管是点exit还是点“X”关闭。请楼主看一下是否有笔误。
支持(0) 反对(0)
   回复 引用 删除
#21楼 [楼主] 2007-09-21 14:45 紫雨轩 .Net
@TTT
首先,在closing事件里面使用我贴的那个有问题的代码,不是修正后的正确代码。

操作步骤
1.点击 exit 按钮。
2. 点击 msg 的no 。
3. 点击 msg 的 cancel 。
这时窗体 不会关闭。

4 再点击 exit 按钮。
引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/211
复制引用地址https://www.rickw.cn/trackback/211/GBK
[ 分类:C# .Net编程  | 查看:3644 ]

暂时没有评论,快来发表一个评论吧。
发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5