如何检测区分外部 wm_close 与 form.close() 内部触发

发布于 2024-11-27 12:14:56 字数 716 浏览 0 评论 0原文

这是一个 C# 应用程序,作为通知图标位于托盘中,并执行其操作,直到有人右键单击它并选择关闭(菜单选项),或者它从外部应用程序或操作系统(例如在重新启动期间)获取 wm_close。

protected override void WndProc(ref Message m)
{
   case  Win32.WmClose:
  //recvd message to shutdown
   Program.Log.InfoFormat("Shutdown received at {0}", DateTime.Now);
   CleanUp();
   this.Close(); //this is the main form
   break;

   //other case statements here
}

//somewhere else on menu exit of notify icon
 private void toolStripMenuItemExit_Click(object sender, EventArgs e)
 {
        Program.Log.InfoFormat("Manual EXIT at {0}", DateTime.Now);
        CleanUp();
        this.Close(); //this is the main form
 }

this.close() 触发另一个 WM_CLOSE,使应用程序陷入混乱。处理这种情况的正确方法是什么?谢谢

This is a C# app that sits in the tray as a notifyicon and does its stuff until someone right clicks it and selects close (menu option) or it gets a wm_close from an external app or by the operating system say during a reboot.

protected override void WndProc(ref Message m)
{
   case  Win32.WmClose:
  //recvd message to shutdown
   Program.Log.InfoFormat("Shutdown received at {0}", DateTime.Now);
   CleanUp();
   this.Close(); //this is the main form
   break;

   //other case statements here
}

//somewhere else on menu exit of notify icon
 private void toolStripMenuItemExit_Click(object sender, EventArgs e)
 {
        Program.Log.InfoFormat("Manual EXIT at {0}", DateTime.Now);
        CleanUp();
        this.Close(); //this is the main form
 }

The this.close() triggers another WM_CLOSE sending the app in a tailspin. What is the correct way to handle this situation ? thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若水般的淡然安静女子 2024-12-04 12:14:56

处理表单 Closing 事件。每当您想退出时,只需调用 Close();,并使任何其他操作依赖于关闭事件内的关闭,而不是在 WndProctoolStripMenuItemExit_Click 处处理它,所以:

private void OnFormCloseing(object sender, FormClosingEventArgs e)
{
    string reason = string.Empty;
    switch (e.CloseReason)
    {
        case CloseReason.UserClosing:
            reason = "Manual EXIT";
            break;

        case CloseReason.WindowsShutDown:
            reason = "Shutdown received";
            break;
    }
    Program.Log.InfoFormat(reason + " at {0}", DateTime.Now);
    CleanUp();
}

private void toolStripMenuItemExit_Click(object sender, EventArgs e)
{
    this.Close(); //this is the main form
}

CloseReason 的更多成员此处

Handle form Closing event. and whenever you want to exit just call Close();, and make any other operation rely on closing inside the closing event instead of handling it at WndProc and toolStripMenuItemExit_Click, so:

private void OnFormCloseing(object sender, FormClosingEventArgs e)
{
    string reason = string.Empty;
    switch (e.CloseReason)
    {
        case CloseReason.UserClosing:
            reason = "Manual EXIT";
            break;

        case CloseReason.WindowsShutDown:
            reason = "Shutdown received";
            break;
    }
    Program.Log.InfoFormat(reason + " at {0}", DateTime.Now);
    CleanUp();
}

private void toolStripMenuItemExit_Click(object sender, EventArgs e)
{
    this.Close(); //this is the main form
}

More members of CloseReason here.

衣神在巴黎 2024-12-04 12:14:56

从 toolStripMenuItemExit_Click 和 WndProc 中删除 CleanUp() 调用。

在主窗口窗体中添加一个 FormClosing() 事件处理程序(假设您有一个)。再说一遍,假设您有一个主窗体窗口,为什么要有 WndProc?

CleanUp() 只会执行一次,但您仍然会有两条日志消息,尽管两条消息都是准确的。

Remove the CleanUp() call from both toolStripMenuItemExit_Click and WndProc.

Add a FormClosing() event handler in the main window form (assuming you have one). Again, assuming you have a main form window, why do you have a WndProc at all?

The CleanUp() will only be done once, but you will still have two log messages, though both are accurate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文