C# 无需用户输入,以编程方式拆卸MessageBox

C# 无需用户输入,以编程方式拆卸MessageBox,c#,.net,winforms,messagebox,C#,.net,Winforms,Messagebox,我经常使用MessageBox为用户弹出警报消息。我的特定应用程序可以设置为远程运行,因此有时用户在计算机前,有时用户可能数小时甚至数天不在计算机前。有时,我会使用MessageBox弹出警报消息,但一段时间后,警报不再相关。例如,我弹出一个警报,指出由于某些条件未满足,任务无法完成。几分钟后,该标准得到满足,任务开始。该消息框不再相关 在消息不再相关的情况下,我希望能够以编程方式关闭MessageBox。这可能吗?目前,我使用以下方法在线程中创建我的MessageBox对象: new Thre

我经常使用
MessageBox
为用户弹出警报消息。我的特定应用程序可以设置为远程运行,因此有时用户在计算机前,有时用户可能数小时甚至数天不在计算机前。有时,我会使用
MessageBox
弹出警报消息,但一段时间后,警报不再相关。例如,我弹出一个警报,指出由于某些条件未满足,任务无法完成。几分钟后,该标准得到满足,任务开始。该
消息框
不再相关

在消息不再相关的情况下,我希望能够以编程方式关闭
MessageBox
。这可能吗?目前,我使用以下方法在线程中创建我的
MessageBox
对象:

new Thread(() => MessageBox.Show("Some text", "Some caption")).Start();

我这样做是为了让应用程序可以在后台继续工作,而不会被
消息框
停止。有什么建议吗?

请对您的条件例外,以了解何时启动msgbox或何时启动msgbox。例如:

if (criteria)
{
    new Thread(() => MessageBox.Show("Some text", "Some caption")).Start();
}
else
{
    //do nothing
}

您可能需要考虑消息的日志文件,以及在主窗体中嵌入的ReXTrimeBox(或多行文本框),然后可以在其中发布消息(每行1个,连同时间戳)。至于你的messagebox问题,我不确定是否有(好的)方法以编程方式关闭它们。(中止线程将不起作用)。

这对我有效

public partial class Form1 : Form
{
    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

    [DllImport("user32.Dll")]
    static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);

    const UInt32 WM_CLOSE = 0x0010;

    Thread thread;

    public Form1()
    {
        InitializeComponent();

        thread = new Thread(ShowMessageBox);
        thread.Start();
    }

    void CloseMessageBox()
    {
        IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, "Caption");
        if (hWnd != IntPtr.Zero)
            PostMessage(hWnd, WM_CLOSE, 0, 0);

        if (thread.IsAlive)
            thread.Abort();
    }

    static void ShowMessageBox()
    {
        MessageBox.Show("Message", "Caption");
    }
}
现在可以使用
CloseMessageBox()
关闭消息框

但是请记住,
CloseMessageBox()
ShowMessageBox()中的标题必须相同


可能通过一个全局变量,但这取决于您。

为什么不创建一个自定义消息框?你可以让它显示一段固定的时间,或者直到你的应用程序通过代码关闭它

创建自定义消息框(表单类的子类)的实例并将其另存为变量(例如
MyMessageBox
),然后使用
MyMessageBox.show()显示它
。如果要取下它,请调用
MyMessageBox.Close()


如果在另一个线程中打开它时关闭它时遇到问题,请尝试调用
MyMessageBox.Invoke(新操作(()=>{MyMessageBox.Close();}))将运行命令
MyMessageBox.Close()MyMessageBox
,以避免引起问题。

如果使用DevExpress,则可以执行以下操作:
应用程序具有包含所有打开的应用程序窗体的属性。您无法找到特定的messagebox,但可以关闭所有XtraMessageBox。或者,如果您在某个任务/线程中运行MessageBox,请在关闭前检查它

您可以使用下面的类轻松创建MessageBox:

using System;
using System.Runtime.InteropServices;

public class MsgBox
{
    [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    static extern bool EndDialog(IntPtr hDlg, int nResult);

    [DllImport("user32.dll")]
    static extern int MessageBoxTimeout(IntPtr hwnd, string txt, string caption,
        int wtype, int wlange, int dwtimeout);

    const int WM_CLOSE = 0x10;

    public static int Show(string text, string caption, int milliseconds, MsgBoxStyle style)
    {
        return MessageBoxTimeout(IntPtr.Zero, text, caption, (int)style, 0, milliseconds);
    }

    public static int Show(string text, string caption, int milliseconds, int style)
    {
        return MessageBoxTimeout(IntPtr.Zero, text, caption, style, 0, milliseconds);
    }
    public static int Show(string text, string caption, int milliseconds)
    {
        return MessageBoxTimeout(IntPtr.Zero, text, caption, 0, 0, milliseconds);
    }
}

public enum MsgBoxStyle
{
    OK = 0, OKCancel = 1, AbortRetryIgnore = 2, YesNoCancel = 3, YesNo = 4,
    RetryCancel = 5, CancelRetryContinue = 6,

    RedCritical_OK = 16, RedCritical_OKCancel = 17, RedCritical_AbortRetryIgnore = 18,
    RedCritical_YesNoCancel = 19, RedCritical_YesNo = 20,
    RedCritical_RetryCancel = 21, RedCritical_CancelRetryContinue = 22,

    BlueQuestion_OK = 32, BlueQuestion_OKCancel = 33, BlueQuestion_AbortRetryIgnore = 34,
    BlueQuestion_YesNoCancel = 35, BlueQuestion_YesNo = 36,
    BlueQuestion_RetryCancel = 37, BlueQuestion_CancelRetryContinue = 38,

    YellowAlert_OK = 48, YellowAlert_OKCancel = 49, YellowAlert_AbortRetryIgnore = 50,
    YellowAlert_YesNoCancel = 51, YellowAlert_YesNo = 52,
    YellowAlert_RetryCancel = 53, YellowAlert_CancelRetryContinue = 54,

    BlueInfo_OK = 64, BlueInfo_OKCancel = 65, BlueInfo_AbortRetryIgnore = 66,
    BlueInfo_YesNoCancel = 67, BlueInfo_YesNo = 68,
    BlueInfo_RetryCancel = 69, BlueInfo_CancelRetryContinue = 70,
}
用法:

MsgBox.Show("this is content", "this is caption", 3000);

也许你需要一些定制的信息框。我正朝那个方向倾斜。只是想知道是否有一种方法可以通过现有的
MessageBox
实现这一点。我讨厌重新发明轮子。事实上,这并不是所谓的“重新发明轮子”
,如果你还想要一些定制外观,那是唯一的方法,也不需要太多工作。我不认为有任何方法可以从标准的
MessageBox
开始,你也可以使用一些
Win32
函数来创建一些无模式的MessageBox,尽管我从未尝试过。顺便说一句,我想你的MessageBox只有一个按钮
OK
,因此与用户的交互不是真的必要,您可以尝试使用某种类型的
通知窗口来代替。但正如他所说的,可能在当前时间未满足cirteria,但稍后会满足,因此消息将不相关,但仍将保持打开状态。问题是如何删除MessageBox,而不是如何启动它。我怀疑是否有任何向下投票者跳到这里,这个答案将收到至少2张向下投票者票。在我的测试(Windows 7)中,它与MessageBox.Show(这是“中止?”、AlertCaption、MessageBoxButtons.OKCancel)一起使用,但与MessageBox.Show(这是“中止?”)不一起使用,AlertCaption,MessageBoxButtons.YesNo)。后者不会发生任何情况(警报保持打开状态)。有什么想法吗?我注意到在YesNo对话框中按Esc键不起作用(因此WM_CLOSE消息不起任何作用)。你知道应该向窗口发送什么来让它做出“否”的响应吗?嗯,它看起来很复杂,有人提到它在非英语窗口上不起作用。我想我必须重构我的UI,以便它能使用OK/CULL,而不是Yes/No.Andy,有C++方法来将MexEdbox移动到指定的位置吗?