wince/WinForm下实现一个自动关闭的MessageBox

news/2025/2/26 7:51:29

 

 WinForm 下我们可以调用MessageBox.Show 来显示一个消息对话框,提示用户确认等操作。在有些应用中我们需要通过程序来自动关闭这个消息对话框而不是由用户点击确认按钮来关闭。然而.Net framework 没有为我们提供自动关闭MessageBox 的方法,要实现这个功能,我们需要使用Window API 来完成。
      首先我们需要找到这个消息对话框的窗口句柄,一个比较简单的方法就是用 FindWindow API 来查找对应的窗体句柄。

第一种方法:

[DllImport("user32.dll", SetLastError = true)]
        
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 有了这两个API函数,我们就可以来关闭消息对话框了。思路是在调用MessageBox.Show 前启动一个后台工作线程,这个工作线程等待一定时间后开始查找消息对话框的窗口句柄,找到后调用EndDialog API 函数关闭这个消息对话框。不过这个方法有个问题,就是如果同时又多个同名的消息对话框(可能不一定是这个应用的),这样做可能会关错窗口,如何解决这个问题,我还没有想出比较好的方法,如果大家有更好的方法解决这个问题,不妨一起讨论讨论。
     
      我根据这个思路编写了延时关闭消息对话框的函数

 public void ShowMessageBoxTimeout(string text, string caption, 
            MessageBoxButtons buttons, int timeout)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(CloseMessageBox), 
                new CloseState(caption, timeout));
            MessageBox.Show(text, caption,buttons);
        }


这个函数中timeout 参数单位是毫秒,其他参数和MessageBox.Show的参数含义是一样的,这里不再详细说明。
   这个函数中首先利用线程池调用一个工作线程 CloseMessageBox ,并将对话框的标题和延时时间通过CloseState这个类传递给CloseMessageBox函数。
   CloseState 的定义如下:

 private class CloseState
        {
            private int _Timeout;

            /// <summary>
            /// In millisecond
            /// </summary>
            public int Timeout
            {
                get
                {
                    return _Timeout;
                }
            }

            private string _Caption;

            /// <summary>
            /// Caption of dialog
            /// </summary>
            public string Caption
            {
                get
                {
                    return _Caption;
                }
            }

            public CloseState(string caption, int timeout)
            {
                _Timeout = timeout;
                _Caption = caption;
            }
        }


最后就是CloseMessageBox函数了,直接看代码吧

         private   void  CloseMessageBox( object  state)
        
{
            CloseState closeState 
= state as CloseState;

            Thread.Sleep(closeState.Timeout);
            IntPtr dlg 
= FindWindow(null, closeState.Caption);

            
if (dlg != IntPtr.Zero)
            
{
                IntPtr result;
                EndDialog(dlg, 
out result);
            }

        }
 
第二种方法:

  //注意提示出现的是、否按钮 不能自动关闭

//例如这个提示就不能自动关闭:

//if (MessageBox.Show("是否接听?", "来电:" + num, MessageBoxButtons.YesNo,
//MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
               // {}

//以下是源码

   [DllImport("coredll.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("coredll.dll", CharSet = CharSet.Auto)]
        public static extern int PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        public const int WM_CLOSE = 0x10;

        private string _caption;//标题名字
//在弹出提示窗体,需为这个变量赋值
例如:
if (MessageBox.Show("是否接听?", "来电:" + num, MessageBoxButtons.YesNo,
MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {}
赋值就是:
_caption="来电:" + num;//明白


 [System.Runtime.InteropServices.DllImport("coredll")]
        public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);//参数:窗体句柄
        public const int SW_MINIMIZE = 6;
        public static string CodePath = "";

 

//这个方法直接调用就行,直接关闭当前show出的界面,根据那个标题名字

 private void KillMessageBox()
        {
            try
            {
                //查找MessageBox的弹出窗口,注意对应标题
                IntPtr ptr = FindWindow(null, this._caption);
                if (ptr != IntPtr.Zero)
                {
                    //查找到窗口则关闭
                    PostMessage(ptr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show("关闭show"+ex.ToString());
            }
        }


参考网上资料:http://www.csharpwin.com/csharpspace/1831.shtml

 

转载于:https://www.cnblogs.com/javaexam2/archive/2012/06/20/2632807.html


http://www.niftyadmin.cn/n/673068.html

相关文章

兴业证券:资产注入 资本市场的“盛宴”

2007-9-12 13:55:00 代码:作者:张忆东 来源: 兴业证券 出处: 顶点财经加入收藏复制链接给好友跳到低部一、资产注入—“盛宴”才刚刚开始 资产注入是大股东向上市公司出售优质资产&#xff0c;并从上市公司获取相应对价的一种资本运作形式。当大股东向上市公司注入全部主业资…

C# 常见图像处理效果

// 根据RGB&#xff0c;计算灰度值private int GetGrayColor(System.Drawing.Color color){int i (int)(0.299 * color.R 0.587 * color.G 0.114 * color.B);int i2 (color.R * 19595 color.G * 38469 color.B * 7472) >> 16;return i;}private void SetBitmap(Bit…

以房换房PK以房养房 适合自己才划算

作者 钟欣 居住在天津塘沽区的王女士&#xff0c;最近相中了一套位于开发区的房子&#xff0c;总房款为60万元。究竟是将塘沽区的老房子卖掉&#xff0c;拿着30万元售房收入&#xff0c;再添加一 些积蓄一次性购买开发区的房子&#xff0c;还是将老房子出租&#xff0c;并从银行…

DATA format 时间显示问题

{header:"购买时间",dataIndex:"buyTime",editor:new Ext.grid.GridEditor(new Ext.form.DateField({format:"Y-m-d",allowBlank:false,minValue:2007-12-14,disabledDays:[0,6]})),renderer:function(v){return v.format("Y-m-d");}}…

UFC/k1 VS中国散打!!!!!!!

美国的UFC和日本的PRIDE是世界上最著名的综合武术比赛&#xff08;MMA&#xff09;&#xff0c;他们的打法就是赤裸裸的公平较量&#xff0c;在不能挖眼&#xff0c;攻击裆部&#xff0c;咬人&#xff0c;带武器&#xff0c;掰手指头的规则下&#xff0c;可以使用任何打法。所以…

解决虚拟机卡 鼠标拖动很慢 有效解决办法

解决虚拟机卡 鼠标拖动很慢 有效解决办法 原文地址:http://micki.blogbus.com/logs/37335201.html 新建Windows2003虚拟机&#xff08;VMare&#xff09;后&#xff0c;当使用时鼠标移动很慢很卡&#xff0c;但是此时虚拟机并未被占用很多系统资源&#xff0c;如果用远程桌面…

VC6 MFC中ClassView视图中无法显示某个类的问题

近日在用VC6 MFC编写界面程序时&#xff0c;添加一个对话框资源并向工程中添加该对话框资源对应的类时&#xff0c;发现在工程源代码文件夹以及FileView视图中都能看见对话框类的定义&#xff0c;然而在ClassView视图中却无法看到该类的定义&#xff0c;此现象为VC6 MFC的bug&a…

(转)NHibernate 3.0在PetShop 3层架构中的应用

PetShop 及 NHibernate 对于.Net平台下的开发者一定很熟悉&#xff0c;前者是一个经典的软件开发架构&#xff0c;后者是是一个强大的ORM框架。 近期有一个项目&#xff0c;部分功能需要由原来的SQL Server数据改为Oracle数据&#xff0c;其中原来的DAL层用的是LINQ To SQL方式…