views:

487

answers:

4

Hi all,

I am a complete newbie to C++ so bear with me ;-)

I have developed a console ATL application and want to trap the close?, exit?, terminate? event so that I can close log files and perform a general cleanup on exit.

How can I trap the 'terminate' event that would result from someone ending the .exe in the task manager?

Appreciate any help. Thanks.

+4  A: 

You can't trap "End Process" from the Processes tab in Task Manager. If a program could trap it, how would you kill it?

To respond to "End Process" on the Applications tab in Task Manager, handle the WM_CLOSE message in your main window.

This assumes that your ATL app is a Windows GUI application. If it's a console application, you need to look at SetConsoleCtrlHandler.

Roger Lipscombe
A: 

Thanks for the quick reply.

It's a console application, I've attached the main class. Could you possibly point to where and how I should use SetConsoleCtrlHandler.

// Override CAtlExeModuleT members
int WinMain(int nShowCmd) throw()
{ 
 if (CAtlBaseModule::m_bInitFailed) //ctor failed somewhere
 {
  ATLASSERT(0);
  return -1;
 }

 HRESULT hr = S_OK;

 LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT

 if( ParseCommandLine( lpCmdLine, &hr ) )
 {
  if( SUCCEEDED( RegisterClassObjects( CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE ) ) )
  {
   CComPtr<IRORCAdapterMain> pAdapter;

   if( SUCCEEDED( pAdapter.CoCreateInstance( L"RORCAdapter.RORCAdapterMain" ) ) )
   {
    if( SUCCEEDED( pAdapter->StartAdapter() ) )
    {
     MSG msg;

     while( GetMessage( &msg, 0, 0, 0 ) )
      DispatchMessage( &msg );
    }
   }

   RevokeClassObjects();
  }
 }
You have a message pump there, when you get a WM_QUIT is should exit from the while loop.Also check GetMessage documentation because your message loop has a possible bug.
Ismael
Also, as you has been told if your program is terminated with "End Process" you will not get any message. If your program is terminated with "End Task" instead it should get WM_CLOSE.
Ismael
A: 

Catching Ctrl-C / Ctrl-Break is not to hard. Just call SetConsoleCtrlHandler to specify which call-back function should handle it.

(Hopefully) illustrating example:

#include <wincon.h>

bool g_terminate = false;

int main(void)
{
    SetConsoleCtrlHandler( control_handler, TRUE );

    while ( !g_terminate )
    {
       doWork();
    }    
}


int WINAPI control_handler ( DWORD dwCtrlType )
{
    switch( dwCtrlType )
    {
        case CTRL_BREAK_EVENT:  
        case CTRL_C_EVENT:      
            g_terminate = true;
            return 1;
        default:
            return 0;
    }
}

/L

leiflundgren
A: 

Off course, to have you example terminating, in control_handler replace

g_terminate = true;

with

PostMessage(HWND_BROADCAST, WM_CLOSE, 0, 0);
leiflundgren