システムからの通知をウインドウプロシージャという関数で受信するという特徴があります。アプリケーションはこのタイミングでクリーンアップ処理を行うことができます。SetConsoleCtrlHandlerを呼び出してハンドラ関数を追加することになります。Add);HandlerRoutineは、ハンドラ関数のアドレスを指定します。Addは、ハンドラ関数を追加する場合にTRUEを指定し、削除する場合にFALSEを指定します。コンソールに対して発生したイベントを表す定数が送られます。ハンドラ関数のプロトタイプは次のようになります。dwCtrlType);dwCtrlTypeは、発生したイベントを表す定数が格納されます。次に、定義されている定数を示します。CTRL+Cの組み合わせが押されたことを意味する。FALSEを返すと既定のハンドラによってExitProcessが呼ばれる。プロセスを終了させたくない場合はTRUEを返す。CTRL+BREAKの組み合わせが押されたことを意味する。FALSEを返すと既定のハンドラによってExitProcessが呼ばれる。プロセスを終了させたくない場合はTRUEを返す。コンソールが閉じられたことを意味する。FALSEを返すと既定のハンドラによってExitProcessが呼ばれる。TRUEを返しても終了してしまうようである。ユーザーがログオフしようとしていることを意味する。FALSEを返すと既定のハンドラによってExitProcessが呼ばれる。TRUEを返すと終了確認のダイアログが表示される。システムがシャットダウンしようとしていることを意味する。FALSEを返すと既定のハンドラによってExitProcessが呼ばれる。TRUEを返すと終了確認のダイアログが表示される。既定のハンドラ関数が予め追加されています。プロセスが終了することになります。通常これは既定のハンドラ関数です。アプリケーションが明示的にイベントを発生させたい場合は、GenerateConsoleCtrlEventを呼び出します。dwProcessGroupId);dwCtrlEventは、生成するイベントの種類を表す定数を指定します。CTRL_C_EVENTとCTRL_BREAK_EVENTだけが指定可能です。dwProcessGroupIdは、プロセスグループのIDを指定します。0を指定すると、呼び出し側プロセスのコンソールを共有する全てのプロセスにイベントが発生します。次に関数の呼び出し例を示します。0);このようにすると、CTRL_BREAK_EVENTが引数としてハンドラ関数が呼ばれることになります。Breakキーがキーボードに存在しない場合は、このコードを実行することで効果を確認できます。今回のプログラムは、SetConsoleCtrlHandlerを呼び出す例を示しています。第1引数に指定した関数がハンドラ関数として追加されます。上記の例ではTRUEを返しています。よって、CTRL+Cの押下によってプロセスが終了することはありません。このイベントの場合はどんな値を返してもプロセスが終了することになるようです。処理しないイベントについては、FALSEを返すようにします。コンソールを単一で閉じるコンソールを閉じるとプロセスが終了するという仕様は、場合によっては不都合になることがあります。ウインドウを表示するアプリケーションが、デバッグ目的でコンソールに逐次データを書き込むものとしましょう。プロセスが終了してしまう必要はありません。これが非常に難しいのです。戻り値を通じて終了を拒否することはできません。コンソールといえどそれはウインドウですから、ウインドウをサブクラス化すればWM_CLOSEを検出できるように思えます。サブクラス化が成功することはありません。この方法も利用することができません。妥協案として考えたのは、コンソールの「閉じる」ボタンを無効にする方法です。ユーザーには「閉じる」ボタンを押す代わりに、CTRL+Cでコンソールを閉じてもらいます。ここでTRUEを返せばプロセスが終了することはありません。FALSE;}「閉じる」ボタンを無効にするには、システムメニューの項目を削除するだけです。システムメニューにはSC_CLOSEというIDを持った項目がありますから、これをRemoveMenuで削除します。すると、「閉じる」ボタンが無効になることに加えて、システムメニューから「閉じる」を選択することができなくなります。これをGetSystemMenuの第1引数に指定します。これは非常に重要です。コンソールだけが閉じられたように見せるためにFreeConsoleを呼び出す必要があります。