Выключите приложение ATL аккуратно - PullRequest
1 голос
/ 28 января 2009

Я разработал консольное приложение ATL и хочу перехватить закрытие ?, выйти ?, завершить? событие, чтобы я мог закрыть файлы журнала и выполнить общую очистку при выходе.

Как я могу перехватить событие 'terminate', которое может произойти, если кто-то завершит работу .exe в диспетчере задач?

EDIT:

Это консольное приложение, я прикрепил основной класс. Не могли бы вы указать, где и как я должен использовать 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();
        }
    }

Ответы [ 3 ]

4 голосов
/ 28 января 2009

Вы не можете перехватить «Завершить процесс» на вкладке «Процессы» в диспетчере задач. Если бы программа могла его перехватить, как бы вы ее убили?

Чтобы ответить на «Завершить процесс» на вкладке «Приложения» в диспетчере задач, обработайте сообщение WM_CLOSE в главном окне.

Это предполагает, что ваше приложение ATL является приложением Windows GUI. Если это консольное приложение, вам нужно взглянуть на SetConsoleCtrlHandler.

0 голосов
/ 29 января 2009

Конечно, чтобы завершить пример, в control_handler замените

g_terminate = true;

с

PostMessage(HWND_BROADCAST, WM_CLOSE, 0, 0);
0 голосов
/ 29 января 2009

Поймать Ctrl-C / Ctrl-Break не сложно. Просто вызовите SetConsoleCtrlHandler, чтобы указать, какая функция обратного вызова должна его обрабатывать.

(Надеюсь) иллюстрирующий пример:

#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;
    }
}

/ л

...