java messagebox 关闭_wince/WinForm下实现一个自动关闭的MessageBox

本文介绍了在WinForm环境下,如何通过调用Windows API来实现在特定时间后自动关闭MessageBox,提供了两种方法:一种是利用后台工作线程和EndDialog API,另一种是通过PostMessage API发送WM_CLOSE消息。此外,还给出了相关的代码示例。
摘要由CSDN通过智能技术生成

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

首先我们需要找到这个消息对话框的窗口句柄,一个比较简单的方法就是用 FindWindow API 来查找对应的窗体句柄。

第一种方法:

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

731655954c7be9d8835ece551b5385f8.pngstaticexternIntPtr FindWindow(stringlpClassName,stringlpWindowName);

有了这两个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;

///

/// In millisecond

///

public int Timeout

{

get

{

return _Timeout;

}

}

private string _Caption;

///

/// Caption of dialog

///

public string Caption

{

get

{

return _Caption;

}

}

public CloseState(string caption, int timeout)

{

_Timeout = timeout;

_Caption = caption;

}

}

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

731655954c7be9d8835ece551b5385f8.pngprivatevoidCloseMessageBox(objectstate)

24a924a57ba6b3f2b51fc9edb7ea4186.png{

1408c5260b2f05e450dee929db9be5f7.png            CloseState closeState=stateasCloseState;

1408c5260b2f05e450dee929db9be5f7.png

1408c5260b2f05e450dee929db9be5f7.png            Thread.Sleep(closeState.Timeout);

1408c5260b2f05e450dee929db9be5f7.png            IntPtr dlg=FindWindow(null, closeState.Caption);

1408c5260b2f05e450dee929db9be5f7.png

1408c5260b2f05e450dee929db9be5f7.pngif(dlg!=IntPtr.Zero)

715f2d05503b99d41f3b6ba2cdccc84d.png{

1408c5260b2f05e450dee929db9be5f7.png                IntPtr result;

1408c5260b2f05e450dee929db9be5f7.png                EndDialog(dlg,outresult);

5bcb1807ee3e00d2b3c225f0b3f5c751.png            }f466905a3bcb5dcef110eab799825254.png        }

第二种方法:

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

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

//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());

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值