📄 screensavertest.cs
字号:
using System;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace ScreenSaver_Control
{
public partial class ScreenSaverTest : Form
{
private System.Threading.Timer killTimer;
private int killState = 1;
private int killPeriod = 8000; // msec
private int timerState = STOPPED;
private bool ssIsActive = false;
private int ssTimeout = 5; // sec
private Int32 ssSaveTimeout = 0;
private IntPtr hThisWnd = IntPtr.Zero;
private const int STOPPED = 0;
private const int RUNNING = 1;
private const int FALSE = 0;
private const int TRUE = 1;
// This delegate enables asynchronous calls for setting
// the text property on a TextBox control.
delegate void SetTextCallback( string text );
public ScreenSaverTest( )
{
InitializeComponent( );
TimerCallback timerDelegate = new TimerCallback( KillTimer_Elapsed );
killTimer = new System.Threading.Timer( timerDelegate, null, System.Threading.Timeout.Infinite, killPeriod );
// Save off this Window's handle. Used in the kill event handler.
hThisWnd = ScreenSaver.GetForegroundWindow( );
// Save off the original Settings values
ssIsActive = ScreenSaver.GetScreenSaverActive( );
ssSaveTimeout = ScreenSaver.GetScreenSaverTimeout( );
UpdateSettingsValues( );
}
private void buttonActivate_Click( object sender, EventArgs e )
{
// Toggle Screen Saver Active
ScreenSaver.SetScreenSaverActive( ( ScreenSaver.GetScreenSaverActive( ) ) ? FALSE : TRUE );
UpdateSettingsValues( );
}
private void buttonUpdateTimeout_Click( object sender, EventArgs e )
{
ScreenSaver.SetScreenSaverTimeout( ssTimeout );
UpdateSettingsValues( );
}
private void buttonRefresh_Click( object sender, EventArgs e )
{
UpdateSettingsValues( );
}
private void buttonRestore_Click( object sender, EventArgs e )
{
// Restore original screen saver settings
ScreenSaver.SetScreenSaverActive( ( ssIsActive ) ? TRUE : FALSE );
ScreenSaver.SetScreenSaverTimeout( ssSaveTimeout );
UpdateSettingsValues( );
}
private void UpdateSettingsValues( )
{
valueScreensaverActive.Text = ScreenSaver.GetScreenSaverActive( ).ToString( );
valueScreensaverTimeout.Text = ScreenSaver.GetScreenSaverTimeout( ).ToString( );
buttonActivate.Text = ( ScreenSaver.GetScreenSaverActive( ) ) ? "Deactivate" : "Activate";
}
private void entryScreensaverTimeout_ValueChanged( object sender, EventArgs e )
{
ssTimeout = ( int ) entryScreensaverTimeout.Value;
}
private void entryKillPeriod_ValueChanged( object sender, EventArgs e )
{
killPeriod = ( int ) entryKillPeriod.Value * 1000; // convert to msec
}
private void buttonStartStopTimer_Click( object sender, EventArgs e )
{
timerState = ( timerState == RUNNING ) ? STOPPED : RUNNING;
if( timerState == RUNNING )
{
// Start the kill event timer
killTimer.Change( 0, killPeriod );
entryKillPeriod.Enabled = false;
entryScreensaverTimeout.Enabled = false;
buttonStartStopTimer.Text = "Stop Timer";
}
else
{
// Stop the kill event from triggering
killTimer.Change( System.Threading.Timeout.Infinite, killPeriod );
entryKillPeriod.Enabled = true;
entryScreensaverTimeout.Enabled = true;
buttonStartStopTimer.Text = "Start Timer";
}
}
// Kill event timer handler
private void KillTimer_Elapsed( object state )
{
// Toggle kill state to indicate activity
killState = ( killState == 1 ) ? 0 : 1;
this.SetText( killState.ToString( ) );
// Stop the screen saver if it's active and running, otherwise reset the screen saver timer.
// Apparently it's possible for GetScreenSaverRunning( ) to return TRUE before the
// screen saver has time to actually become the foreground application. So...
// Make sure we're not the foreground window to avoid killing ourself.
if( ScreenSaver.GetScreenSaverActive( ) )
{
if( ScreenSaver.GetScreenSaverRunning( ) )
{
if( ScreenSaver.GetForegroundWindow( ) != hThisWnd )
ScreenSaver.KillScreenSaver( );
}
else
{
// Reset the screen saver timer, so the screen saver doesn't turn on until after a full
// timeout period. If killPeriod is less than ssTimeout the screen saver should never activate.
ScreenSaver.SetScreenSaverActive( TRUE );
}
}
}
private void SetText( string text )
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if( valueKillState.InvokeRequired )
{
SetTextCallback d = new SetTextCallback( SetText );
this.Invoke( d, new object[ ] { text } );
}
else
{
valueKillState.Text = text;
}
}
private void ScreenSaverTest_FormClosing( object sender, FormClosingEventArgs e )
{
// Restore original screen saver settings
ScreenSaver.SetScreenSaverActive( ( ssIsActive ) ? TRUE : FALSE );
ScreenSaver.SetScreenSaverTimeout( ssSaveTimeout );
}
}
#region ScreenSaver Class
public static class ScreenSaver
{
// Signatures for unmanaged calls
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool SystemParametersInfo( int uAction, int uParam, ref int lpvParam, int flags );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool SystemParametersInfo( int uAction, int uParam, ref bool lpvParam, int flags );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern int PostMessage( IntPtr hWnd, int wMsg, int wParam, int lParam );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern IntPtr OpenDesktop( string hDesktop, int Flags, bool Inherit, uint DesiredAccess );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool CloseDesktop( IntPtr hDesktop );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDesktopWindowsProc callback, IntPtr lParam );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool IsWindowVisible( IntPtr hWnd );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
public static extern IntPtr GetForegroundWindow( );
// Callbacks
private delegate bool EnumDesktopWindowsProc( IntPtr hDesktop, IntPtr lParam );
// Constants
private const int SPI_GETSCREENSAVERACTIVE = 16;
private const int SPI_SETSCREENSAVERACTIVE = 17;
private const int SPI_GETSCREENSAVERTIMEOUT = 14;
private const int SPI_SETSCREENSAVERTIMEOUT = 15;
private const int SPI_GETSCREENSAVERRUNNING = 114;
private const int SPIF_SENDWININICHANGE = 2;
private const uint DESKTOP_WRITEOBJECTS = 0x0080;
private const uint DESKTOP_READOBJECTS = 0x0001;
private const int WM_CLOSE = 16;
// Returns TRUE if the screen saver is active (enabled, but not necessarily running).
public static bool GetScreenSaverActive( )
{
bool isActive = false;
SystemParametersInfo( SPI_GETSCREENSAVERACTIVE, 0, ref isActive, 0 );
return isActive;
}
// Pass in TRUE(1) to activate or FALSE(0) to deactivate the screen saver.
public static void SetScreenSaverActive( int Active )
{
int nullVar = 0;
SystemParametersInfo( SPI_SETSCREENSAVERACTIVE, Active, ref nullVar, SPIF_SENDWININICHANGE );
}
// Returns the screen saver timeout setting, in seconds
public static Int32 GetScreenSaverTimeout( )
{
Int32 value = 0;
SystemParametersInfo( SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0 );
return value;
}
// Pass in the number of seconds to set the screen saver timeout value.
public static void SetScreenSaverTimeout( Int32 Value )
{
int nullVar = 0;
SystemParametersInfo( SPI_SETSCREENSAVERTIMEOUT, Value, ref nullVar, SPIF_SENDWININICHANGE );
}
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0, ref isRunning, 0 );
return isRunning;
}
// From Microsoft's Knowledge Base article #140723: http://support.microsoft.com/kb/140723
// "How to force a screen saver to close once started in Windows NT, Windows 2000, and Windows Server 2003"
public static void KillScreenSaver( )
{
IntPtr hDesktop = OpenDesktop( "Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS );
if( hDesktop != IntPtr.Zero )
{
EnumDesktopWindows( hDesktop, new EnumDesktopWindowsProc( KillScreenSaverFunc ), IntPtr.Zero );
CloseDesktop( hDesktop );
}
else
{
PostMessage( GetForegroundWindow( ), WM_CLOSE, 0, 0 );
}
}
private static bool KillScreenSaverFunc( IntPtr hWnd, IntPtr lParam )
{
if( IsWindowVisible( hWnd ) )
PostMessage( hWnd, WM_CLOSE, 0, 0 );
return true;
}
}
#endregion
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -