没有窗口的Windows应用程序中的窗口消息

5

我有一个应用程序,希望在后台运行且没有可见的窗口或控制台。为了实现这一点,我创建了一个windows应用程序但没有创建窗口。当请求关闭应用程序时(例如用户注销时),它需要清理一些东西。那么如何确定何时关闭呢?我可以简单地创建一个消息循环来处理WM_CLOSE消息吗?但是我没有WndProc来处理WM_CLOSE消息。


所以你并没有一个Windows应用程序,而是一个在后台运行的程序,你想知道它是否被用户请求注销时终止了,对吗? - Grzegorz
通常创建一个窗口,但使用EnableWindow将其隐藏。 - Jabberwocky
3个回答

6
不必创建虚拟窗口,对于无窗口应用程序处理关机/退出控制事件有更简单的方法。为此,您可以使用一个鲜为人知的Win API函数:SetConsoleCtrlHandler (...) 以下是如何使用Control Handler的示例:
#include <windows.h> 

// You can fill-in your own behavior, this is just an example handler that
//   covers most of the most common events.
BOOL
ControlHandler (DWORD dwControlEvent) 
{ 
  switch (dwControlEvent) 
  { 
    // User wants to shutdown
    case CTRL_SHUTDOWN_EVENT: 
      return FALSE; 

    // User wants to logoff
    case CTRL_LOGOFF_EVENT: 
      return FALSE; 

    // Ctrl + C
    case CTRL_C_EVENT:
      return TRUE;

    // User wants to exit the "normal" way 
    case CTRL_CLOSE_EVENT:
      return TRUE;

    // Everything else, just ignore it...
    default:
      return FALSE; 
  } 
} 

int
main (void) 
{ 
  // Set the control handler so the app will be notified upon any special
  //   termination event.
  SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ControlHandler, TRUE); 

  //
  // Main Loop Here ...
  //

  return 0;
}

我几年前不得不学习这个知识,因为当我的控制台应用程序被使用 Ctrl + C 终止时,某些中间件没有正确清理其资源。我偶然在查看堆栈跟踪时发现了它。值得一提的是,这比标准信号处理程序的处理方式(例如 Ctrl + C)更为重要。

顺便说一下,尽管它被称为“控制台控制处理程序”,但在使用 WinMain (...) 而不是 main (...) 的应用程序中也可以完美地运行。


是的,我之前一直在使用那个,但我不想让用户看到任何东西,没有控制台,也没有窗口。即使我在启动时隐藏控制台,它也会闪烁出现,这是不可接受的。 - Skux Deluxe
你不需要控制台来使其工作,但服务方法肯定更加优雅。 - Andon M. Coleman
服务无法满足所有需求,例如由于安全性的原因无法访问用户输入或应用程序。因此,在用户帐户下运行隐藏应用程序是一种解决方案。 - TMa

3

有几个选择:

  1. 创建一个窗口,但不设置WS_VISIBLE标志。
  2. 创建一个仅消息窗口

区别在于,不可见窗口接收广播消息,而仅消息窗口不会接收。


2
要创建一个在后台运行的应用程序,请创建一个服务。服务可以响应ServiceMain调用。
如果您坚持要创建前端应用程序,基本上没有合法的理由让应用程序尝试隐藏其主窗口。您的可执行映像可以是GUI (IMAGE_SUBSYSTEM_WINDOWS_GUI)或控制台(IMAGE_SUBSYSTEM_WINDOWS_CUI),您不能混合使用它们,请参见如何编写既可以作为控制台应用程序又可以作为GUI应用程序运行的程序。如果您选择GUI应用程序,则需要创建消息泵。您可以选择将隐藏窗口作为“主”窗口。您将在此隐藏窗口上收到WM_QUERYENDSESSIONWM_ENDSESSION(这些是您感兴趣的消息,而不是WM_CLOSE)。
另一方面,控制台应用程序将需要处理信号,就像Andon已经向您展示的那样。
选择您的毒药。我强烈建议您走服务路线,因为这是一个“后台”应用程序的适当途径。

3
“没有正当理由让应用程序隐藏它们的主窗口”是一个相当有力的陈述,但也显然是错误的。有很多情况下,显示用户界面窗口是没有意义的,例如执行后台工作的子进程或只通过通知栏与用户进行交互的程序。这两种情况都不是严格意义上的服务,但仍然没有窗口。 - Tustin2121

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接