当前位置: 首页 > 编程语言 > C#

强制以编程方式关闭MessageBoxShare

时间:2023-04-11 11:12:18 C#

以编程方式强制关闭MessageBox让我给你一个背景。我们有一个应用程序(中等大小),它在不同的地方(数百个)使用MessageBox.Show(....)。这些消息框是工作流的一部分,用于通知、警告或获取用户的输入。如果没有活动,应用程序应在一定时间后自动注销。我们要求当应用程序注销时,它只是简单地清理会话数据,清除视图并隐藏自己,以便在下次启动时它不必经过启动过程,这在时间上是昂贵的。一切正常,但在屏幕上有一些消息框并且用户离开机器而没有响应消息框的情况下,然后应用程序由于没有活动而退出。问题是消息框不会消失。隐藏应用程序时如何关闭打开的消息框(如果有)?谢谢。这是一段基于UIAutomation(一个很酷但仍未使用的API)的代码,它试图关闭当前进程的所有模态窗口(包括使用MessageBox打开的窗口)://////如果有任何模态窗口,则尝试关闭模态窗口.///publicstaticvoidCloseModalWindows(){//获取主窗口AutomationElementroot=AutomationElement.FromHandle(Process.GetCurrentProcess().MainWindowHandle);如果(root==null)返回;//它应该实现窗口模式对象模式;如果(!root.TryGetCurrentPattern(WindowPattern.Pattern,输出模式))返回;WindowPattern窗口=(WindowPattern)模式;if(window.Current.WindowInteractionState!=WindowInteractionState.ReadyForUserInteraction){//获取子窗口foreach(AutomationElementelementinroot.FindAll(TreeScope.Children,newPropertyCondition(AutomationElement.ControlTypeProperty,ControlType.Window))){//嗯。..这真的是一扇窗户吗?if(element.TryGetCurrentPattern(WindowPattern.Pattern,outpattern)){//如果准备就绪,尝试关闭它WindowPatternchildWindow=(窗口模式)模式;如果(childWindow.Current.WindowInteractionState==WindowInteractionState.ReadyForUserInteraction){childWindow.Close();}}}}}例如,如果您有一个WinForms应用程序,当您按下某个按钮1弹出一个MessageBox时,您仍然可以使用Windows“关闭窗口”菜单(右键单击任务栏)关闭该应用程序:privatevoidbutton1_Click(objectsender,EventArgse){MessageBox.Show("别点我,我要自动关闭!");}protectedoverridevoidWndProc(refSystem.Windows.Forms.Messagem){constintWM_SYSCOMMAND=0x0112;constintSC_CLOSE=0xF060;if(m.Msg==WM_SYSCOMMAND)//即使显示模态MessageBox也会发送{if((int)m.WParam==SC_CLOSE){CloseModalWindows();关闭();}}base.WndProc(refm);您可以在代码的其他地方使用CloseModalWindows,这只是一个示例MSDN论坛上的此链接显示了如何使用FindWindow并发送WM_CLOSE消息来关闭消息框。虽然问题是.NET/WindowsCE,但它可能会解决您的问题并且值得一看第一个问题:如果将消息框用作工作流的一部分,以编程方式关闭消息框不会导致流程更改/继续吗?我认为您有三种选择创建您自己的消息框类版本,该类打开一个对话框窗口,该对话框窗口看起来像具有附加功能的消息框,因此它会在一段时间后自动关闭。在c#中实现类似的东西以编程方式关闭消息框。http://www.codeproject.com/KB/dialog/AutoCloseMessageBox.aspx从中断工作流中删除消息框。这可能是最好的解决方案,因为它以编程方式关闭消息框的声音会导致工作流继续/更改,甚至可能导致显示另一个可能不合适的消息框。但很明显,解决根本问题可能是最好的,但并不总是最简单的。1和2需要在单独的线程中完成,因此您需要考虑其含义,因为显示消息框将被阻止。这是我使用SendKeys的一个例子——经过测试和工作:假设我们有一个带有后台工作和按钮的表单。单击按钮-启动工作人员并显示消息框。在workerDoWork事件中休眠5秒,然后发送回车键-消息框关闭。privatevoidbutton1_Click(objectsender,EventArgse){backgroundWorker1.RunWorkerAsync();MessageBox.Show("关闭这条消息!");}privatevoidbackgroundWorker1_DoWork(objectsender,DoWorkEventArgse){Thread.Sleep(5000);发送密钥。SendWait("{Enter}");//orEsc}假设您可以编辑调用MessageBox.Show()方法的代码,我建议不要使用MessageBox。相反,只需使用您自己的自定义窗体,在其上调用ShowDialog()来执行与MessageBox类基本相同的操作。然后你有窗体本身的实例,你可以在该实例上调用Close()来关闭它。这是一个很好的例子。我认为最简洁的方法是实现您自己的消息框表单classMyMessageBox:Form{privateMyMessageBoxcurrentForm;//当前活动的消息框publicstaticShow(....){//与MessageBox.Show//相同。..}publicstaticShow(...){//定义额外的重载}publicstaticCloseCurrent(){if(currentForm!=null)currentForm.Close();}//...}在我的一些大型项目中,我发现此方法也可用于其他目的(例如自动记录错误消息等)。我的第二个想法是使用GetTopWindow()(或一些其他WIN32函数)获取应用程序的当前顶级窗口并向其发送WM_CLOSE消息。我使用.net2,这两种方法都使用相同的技巧。当窗体不可见或没有真正的UI时,使用MessageBox.Show从这个存根窗体打开MessageBox.Show(this,"message")。保留表单处理程序并关闭它:staticexternIntPtrSendMessage(IntPtrhWnd,UInt32Msg,IntPtrwParam,IntPtrlParam);或者将表单保存为类参数并使用FormX.Close()。由于Form是MessageBox的所有者,关闭它会关闭MessageBox。请参看“几秒钟后关闭一个MessageBox”中的DmitryGpost超时到达后自动关闭MessageBoxusingSystem.Runtime.InteropServices;使用系统线程;使用System.Windows.Forms;公共类AutoClosingMessageBox{System.Threading.Timer_timeoutTimer;字符串_标题;AutoClosingMessageBox(字符串文本,字符串标题,int超时){_caption=caption;_timeoutTimer=newSystem.Threading.Timer(OnTimerElapsed,null,timeout,System.Threading.Timeout.Infinite);MessageBox.Show(文本,标题);}publicstaticvoidShow(stringtext,stringcaption,inttimeout){newAutoClosingMessageBox(text,caption,timeout);}voidOnTimerElapsed(objectstate){IntPtrmbWnd=FindWindow(null,_caption);如果(mbWnd!=IntPtr.Zero)SendMessage(mbWnd,WM_CLOSE,IntPtr.Zero,IntPtr.Zero);_timeoutTimer.Dispose();}constintWM_CLOSE=0x0010;[System.Runtime.InteropServices.DllImport("user32.dll",SetLastError=true)]staticexternIntPtrFindWindow(stringlpClassName,stringlpWindowName);[System.Runtime.InteropServices.DllImport("user32.dll",CharSet=System.Runtime.InteropServices.CharSet.Auto)]staticexternIntPtrSendMessage(IntPtrhWnd,UInt32Msg,IntPtrwParam,IntPtrlParam);}并通过AutoClosingMessageBox.Show("Content","Title",TimeOut);调用它为此创建您自己的控件并实现您想要的行为作为一个选项,也许有一个计时器来关闭此MessageBox。以上是C#学习教程:强制以编程方式关闭MessageBox分享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢