//******************************************************************************************************
// Events.cs - Gbtc
//
// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 12/28/2006 - Pinal C. Patel
// Generated original version of source code.
// 08/31/2007 - Darrell Zuercher
// Edited code comments.
// 09/15/2008 - J. Ritchie Carroll
// Converted to C#.
// 09/29/2008 - Pinal C. Patel
// Entered code comments.
// 09/14/2009 - Stephen C. Wills
// Added new header and license agreement.
// 09/22/2011 - J. Ritchie Carroll
// Added Mono implementation exception regions.
// 12/14/2012 - Starlynn Danyelle Gilliam
// Modified Header.
//
//******************************************************************************************************
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace GSF.Console
{
///
/// Defines a set of consumable events that can be raised by a console application.
///
///
/// Note that no events will be raised by this class when running under Mono deployments, the class
/// remains available in the Mono build as a stub to allow existing code to still compile and run.
///
///
/// This example shows how to subscribe to console application events:
///
/// using System;
/// using GSF.Console;
///
/// class Program
/// {
/// static void Main(string[] args)
/// {
/// // Subscribe to console events.
/// Events.CancelKeyPress += Events_CancelKeyPress;
/// Events.ConsoleClosing += Events_ConsoleClosing;
/// Events.EnableRaisingEvents();
///
/// Console.ReadLine();
/// }
///
/// static void Events_CancelKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
/// {
/// // Abort processing.
/// }
///
/// static void Events_ConsoleClosing(object sender, System.ComponentModel.CancelEventArgs e)
/// {
/// // Put clean-up code.
/// }
/// }
///
///
public static class Events
{
private enum ConsoleEventType
{
CancelKeyPress = 0,
BreakKeyPress = 1,
ConsoleClosing = 2,
UserLoggingOff = 5,
SystemShutdown = 6
}
private delegate bool ConsoleWindowEventHandler(ConsoleEventType controlType);
private static ConsoleWindowEventHandler s_handler;
#if !MONO
// TODO: See if there a standard POSIX way to pickup similar events
[DllImport("kernel32.dll", EntryPoint = "SetConsoleCtrlHandler")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetConsoleWindowEventRaising(ConsoleWindowEventHandler handler, [MarshalAs(UnmanagedType.Bool)] bool enable);
#endif
///
/// Occurs when CTRL+C signal is received from keyboard input.
///
///
/// method must be called to enable event publication.
///
public static event EventHandler CancelKeyPress;
///
/// Occurs when CTRL+BREAK signal is received from keyboard input.
///
///
/// method must be called to enable event publication.
///
public static event EventHandler BreakKeyPress;
///
/// Occurs when the user closes the console application window.
///
///
/// method must be called to enable event publication.
///
public static event EventHandler ConsoleClosing;
///
/// Occurs when the user is logging off.
///
///
/// method must be called to enable event publication.
///
public static event EventHandler UserLoggingOff;
///
/// Occurs when the system is shutting down.
///
///
/// method must be called to enable event publication.
///
public static event EventHandler SystemShutdown;
///
/// Enables the raising of console application . Prior to calling this method, handlers
/// must be defined for the raised by a console application.
///
///
/// This method is currently ignored under Mono deployments.
///
public static void EnableRaisingEvents()
{
s_handler = HandleConsoleWindowEvents;
#if !MONO
// Member variable is used here so that the delegate is not garbage collected by the time it is called
// by WIN API when any of the control events take place.
// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=996045&SiteID=1
SetConsoleWindowEventRaising(s_handler, true);
#endif
}
///
/// Enables the raising of console application .
///
///
/// This method is currently ignored under Mono deployments.
///
public static void DisableRaisingEvents()
{
s_handler = HandleConsoleWindowEvents;
#if !MONO
SetConsoleWindowEventRaising(s_handler, false);
#endif
}
///
/// Delegate method that gets called when console application events occur.
///
private static bool HandleConsoleWindowEvents(ConsoleEventType controlType)
{
// ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.WIN32COM.v10.en/dllproc/base/handlerroutine.htm
// When this function does not return True, the default handler is called and the default action takes
// place.
switch (controlType)
{
case ConsoleEventType.CancelKeyPress:
CancelEventArgs ctrlCKeyPressEventData = new CancelEventArgs();
if ((object)CancelKeyPress != null)
CancelKeyPress(null, ctrlCKeyPressEventData);
if (ctrlCKeyPressEventData.Cancel)
return true;
break;
case ConsoleEventType.BreakKeyPress:
CancelEventArgs ctrlBreakKeyPressEventData = new CancelEventArgs();
if ((object)BreakKeyPress != null)
BreakKeyPress(null, ctrlBreakKeyPressEventData);
if (ctrlBreakKeyPressEventData.Cancel)
return true;
break;
case ConsoleEventType.ConsoleClosing:
CancelEventArgs consoleClosingEventData = new CancelEventArgs();
if ((object)ConsoleClosing != null)
ConsoleClosing(null, consoleClosingEventData);
if (consoleClosingEventData.Cancel)
return true;
break;
case ConsoleEventType.UserLoggingOff:
if ((object)UserLoggingOff != null)
UserLoggingOff(null, EventArgs.Empty);
break;
case ConsoleEventType.SystemShutdown:
if ((object)SystemShutdown != null)
SystemShutdown(null, EventArgs.Empty);
break;
}
return false;
}
}
}