7

WindowsコンソールアプリケーションでCtrl+Cを押したときに何が起こるかを確認するためのサンプルを作成しました。

bool    TerminationFlag=true;

int main()
{
    g_hTerminateEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
    ::SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
    while(1)
    {
        if(TerminationFlag == false)
        {
            break;
        }
    }
    return 0;
}

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{

    if (dwCtrlType == CTRL_C_EVENT ||
        dwCtrlType == CTRL_BREAK_EVENT ||
        dwCtrlType == CTRL_CLOSE_EVENT)
    {
        TerminationFlag=false;
        ::SetEvent(g_hTerminateEvent);
        return TRUE;
    }
    return FALSE;
}

ctrl + cを押すと、VisualStudioでデバッグの開始オプションを使用してコードを実行してコードをテストしました。次のメッセージが表示されます。

0x7c87647dでの最初のチャンスの例外

続行オプションを押すとTerminationFlag=false;、コントロールハンドラーでCtrl + Cを処理したにもかかわらず、コードが行に表示されます。何が問題なのか教えていただけますか?

4

2 に答える 2

14

問題の説明から、MicrosoftVisualStudioを使用していると思います。発生する最初の可能性のある例外は、デバッグ環境によってトラップされるCTRL-Cイベントです。これは予想される動作です。

これを無視することを選択できます。[デバッグ]メニュー/[例外]/[Win32例外]に移動し、[スロー]列メニューからCONTROL-Cチェックを外します。これにより、デバッガーは、ユーザーが処理していない場合にのみCONTROL-Cで中断します。下の画像を参照してください。

ここに画像の説明を入力してください

ちなみに、フラグをポーリングせずに終了イベントを待つ必要があります。あなたは次のようなものが欲しいかもしれません:

#include "windows.h"
#include <iostream>
HANDLE g_hTerminateEvent;

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{

    if (dwCtrlType == CTRL_C_EVENT ||
        dwCtrlType == CTRL_BREAK_EVENT ||
        dwCtrlType == CTRL_CLOSE_EVENT)
    {
        std::cout << "Terminating" << std::endl;
        SetEvent(g_hTerminateEvent);

        return TRUE;
    }
    return FALSE;
}
int main()
{
    g_hTerminateEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
    SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);

    DWORD result = WaitForSingleObject(g_hTerminateEvent, INFINITE);
    return 0;
}
于 2012-11-03T07:57:13.190 に答える
1

デバッガーでこの種のことを実行すると、デバッガーなしで実行する場合と同じ画像が得られることはありません。デバッガーでは、通常、コンソールの入出力を行うシステム関数をステップオーバーすることはできません。デバッガーは、ここでシステムと対話することを避けられません。

ここで続行するための最も信頼できる方法は、トレースです。

これは質問に直接答えないかもしれません。

ps現在のコードサンプルでは、​​イベントは必要ありません。

MSDNからの更新:

Value   Meaning
 0 CTRL_C_EVENT

キーボード入力またはGenerateConsoleCtrlEvent関数によって生成された信号のいずれかからCTRL+C信号を受信しました。

于 2012-11-03T07:18:06.287 に答える