【问题标题】:Shut down a ATL application cleanly彻底关闭 ATL 应用程序
【发布时间】:2010-10-03 23:50:42
【问题描述】:

我已经开发了一个控制台 ATL 应用程序并且想要捕获关闭?、退出?、终止?事件,以便我可以关闭日志文件并在退出时执行常规清理。

如何捕获因某人在任务管理器中结束 .exe 而导致的“终止”事件?

编辑:

这是一个控制台应用程序,我已经附加了主类。您能否指出我应该在哪里以及如何使用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();
        }
    }

【问题讨论】:

  • 您的问题实际上是关于 ATL,而不是 C++;考虑更改问题的标题...
  • 你有一个消息泵,当你得到 WM_QUIT 时应该退出 while 循环。还要检查 GetMessage 文档,因为您的消息循环可能存在错误。

标签: c++ atl exit-handler


【解决方案1】:

您无法从任务管理器的“进程”选项卡中捕获“结束进程”。如果一个程序可以捕获它,你会如何杀死它?

要响应任务管理器中应用程序选项卡上的“结束进程”,请在主窗口中处理 WM_CLOSE 消息。

这假定您的 ATL 应用程序是 Windows GUI 应用程序。如果是控制台应用,需要看SetConsoleCtrlHandler。

【讨论】:

    【解决方案2】:

    捕捉 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;
        }
    }
    

    /L

    【讨论】:

      【解决方案3】:

      当然,让你的例子终止,在 control_handler 替换

      g_terminate = true;
      

      PostMessage(HWND_BROADCAST, WM_CLOSE, 0, 0);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        • 2013-05-23
        • 1970-01-01
        • 2015-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多