Skux Deluxe
Skux Deluxe

Reputation: 88

Window messages in windows application with no window

I have an application that I want to run in the background with no visible windows or consoles. To accomplish this, I create a windows application but I do not create a window. The application needs to do some cleanup when requested to close (i.e. when the user logs off). How can I determine when to close? Can I simply create a message loop which handles the WM_CLOSE message? But then I have no WndProc to handle the WM_CLOSE message.

Upvotes: 5

Views: 6211

Answers (3)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

Do not bother with creating a dummy window, there is a much easier way to handle shutdown / exit control events in a windowless application. To do this, you use a little known Win API function called: SetConsoleCtrlHandler (...)

Here is an example of how to use the 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;
}

I had to learn about this a couple of years ago because some middle-ware was not properly cleaning up its resources when my console application was terminated with Ctrl + C. I discovered it by accident when I was looking at the stack trace. It is worth mentioning that this supercedes the standard signal handler for events like Ctrl + C.

By the way, even though it is called a "Console Control Handler," it works perfectly fine in applications that use WinMain (...) instead of main (...).

Upvotes: 7

Remus Rusanu
Remus Rusanu

Reputation: 294177

To create an application that runs in the background, create a service. A service can respond to the ServiceMain calls.

If you insist on creting a front end application, there are basically no legit reasons for applications to try to hide their main window. You executable image can be either GUI (IMAGE_SUBSYSTEM_WINDOWS_GUI) or console (IMAGE_SUBSYSTEM_WINDOWS_CUI), and you cannot mix them, see How do I write a program that can be run either as a console or a GUI application. If you choose a GUI application then you are expected to create a message pump. You may choose to create a hidden window as your 'main' window. You will get WM_QUERYENDSESSION and WM_ENDSESSION on this hidden window (which are the messages you're interested in, not WM_CLOSE).

On the other hand a console app will have to handle signals, like Andon already showed you.

Choose your poison. I strongly suggest to go the service route, as is the proper avenue for a 'background' application.

Upvotes: 2

Eric Brown
Eric Brown

Reputation: 13932

A couple of options:

  1. Create a window, but don't set the WS_VISIBLE flag.
  2. Create a message-only window.

The difference would be that invisible windows receive broadcast messages, while message-only windows do not.

Upvotes: 3

Related Questions