From d91286e0aa2ca456c9bab1b57290f98ab2ff91e0 Mon Sep 17 00:00:00 2001 From: Will Hilton Date: Thu, 17 Sep 2015 23:33:36 -0400 Subject: [PATCH] Initial project based on (Write a Screensaver that Actually Works)[http://www.codeproject.com/Articles/14081/Write-a-Screensaver-that-Actually-Works] --- InvisibleLockScreen.csproj | 104 +++ InvisibleLockScreen.sln | 22 + InvisibleLockScreenSaver.cs | 80 +++ Pixie.cs | 41 ++ Properties/AssemblyInfo.cs | 33 + Properties/Resources.Designer.cs | 63 ++ Properties/Resources.resx | 117 ++++ Properties/Settings.Designer.cs | 26 + Properties/Settings.settings | 7 + Screensaver.cs | 1062 ++++++++++++++++++++++++++++++ 10 files changed, 1555 insertions(+) create mode 100644 InvisibleLockScreen.csproj create mode 100644 InvisibleLockScreen.sln create mode 100644 InvisibleLockScreenSaver.cs create mode 100644 Pixie.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 Properties/Resources.Designer.cs create mode 100644 Properties/Resources.resx create mode 100644 Properties/Settings.Designer.cs create mode 100644 Properties/Settings.settings create mode 100644 Screensaver.cs diff --git a/InvisibleLockScreen.csproj b/InvisibleLockScreen.csproj new file mode 100644 index 0000000..4634e63 --- /dev/null +++ b/InvisibleLockScreen.csproj @@ -0,0 +1,104 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {AEF1E602-2461-4F2B-A4F1-153CABF4F09C} + WinExe + Properties + InvisbleLockScreen + InvisbleLockScreen + v2.0 + + + + + 2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + False + .NET Framework 3.5 SP1 + true + + + + + + copy "$(TargetFileName)" "$(TargetName).scr" /y + + \ No newline at end of file diff --git a/InvisibleLockScreen.sln b/InvisibleLockScreen.sln new file mode 100644 index 0000000..b9dd24e --- /dev/null +++ b/InvisibleLockScreen.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvisibleLockScreen", "InvisibleLockScreen.csproj", "{AEF1E602-2461-4F2B-A4F1-153CABF4F09C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AEF1E602-2461-4F2B-A4F1-153CABF4F09C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEF1E602-2461-4F2B-A4F1-153CABF4F09C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEF1E602-2461-4F2B-A4F1-153CABF4F09C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEF1E602-2461-4F2B-A4F1-153CABF4F09C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/InvisibleLockScreenSaver.cs b/InvisibleLockScreenSaver.cs new file mode 100644 index 0000000..0a4717f --- /dev/null +++ b/InvisibleLockScreenSaver.cs @@ -0,0 +1,80 @@ +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Text; +using Screensavers; + +namespace InvisibleLockscreen +{ + class TransparentLockSaver : Screensaver + { + public TransparentLockSaver() + : base(FullscreenMode.SingleWindow) + { + this.Initialize += new EventHandler(PixieSaver_Initialize); + this.Update += new EventHandler(PixieSaver_Update); + + this.SettingsText = "rei@thefraser.com"; + } + + [STAThread] + static void Main() + { + TransparentLockSaver ps = new TransparentLockSaver(); + ps.Run(); + } + + Random rand = new Random(); + public Random Rand + { + get { return rand; } + } + + public void AddPixie(Sprite pixie) + { + pixies.Add(pixie); + } + + List pixies = new List(); + + void PixieSaver_Update(object sender, EventArgs e) + { + DoUpdate(); + DoRender(); + } + + int interval; + + void DoUpdate() + { + if (interval == 5) + { + pixies.Add(new Sprite(this)); + interval = 0; + } + interval++; + + for (int i = 0; i < pixies.Count; i++) + if (pixies[i].Update()) + { + pixies.RemoveAt(i); + i--; + } + } + + void DoRender() + { + Graphics0.Clear(Color.LightGray); + + foreach (Sprite pixie in pixies) + pixie.Draw(); + } + + void PixieSaver_Initialize(object sender, EventArgs e) + { + //Update enough times to fill the screen with pixies + //for (int i = 0; i < Window0.Size.Height; i++) + // DoUpdate(); + } + } +} diff --git a/Pixie.cs b/Pixie.cs new file mode 100644 index 0000000..40940f3 --- /dev/null +++ b/Pixie.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using Screensavers; + +namespace InvisibleLockscreen +{ + class Sprite + { + public Sprite(TransparentLockSaver screensaver) + { + this.screensaver = screensaver; + y = 0; + x = screensaver.Rand.Next(screensaver.Window0.Size.Width); + tendency = screensaver.Rand.Next(25, 75); + } + + readonly static Brush brush = new Pen(Color.Green).Brush; + int tendency; + int x, y; + private TransparentLockSaver screensaver; + + public virtual bool Update() + { + y++; + int num = screensaver.Rand.Next(100); + if (num < tendency) + x++; + else + x--; + + return y >= screensaver.Window0.Size.Height; + } + + public virtual void Draw() + { + screensaver.Graphics0.DrawString("Will is Amazing", new Font("OCR A Extended", 8), brush, new PointF(x, y)); + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3fe85c7 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("InvisibleLockScreen")] +[assembly: AssemblyDescription("An invisible screensaver with password protection.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("InvisibleLockScreen")] +[assembly: AssemblyCopyright("Copyright © Will Hilton 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7b01be7b-2fb2-40cb-af6e-d49426147ea2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..569d968 --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace InvisbleLockScreen.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("InvisbleLockScreen.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs new file mode 100644 index 0000000..13b5a3c --- /dev/null +++ b/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace InvisbleLockScreen.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Properties/Settings.settings b/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Screensaver.cs b/Screensaver.cs new file mode 100644 index 0000000..2225754 --- /dev/null +++ b/Screensaver.cs @@ -0,0 +1,1062 @@ +#region Usage notice +/* + * Screensaver.cs + * + * (c) Rei Miyasaka 2006 + * rei@thefraser.com + * + * Last updated 2006.05.16 + * + * You may use this code for any purpose, in part or in whole, on two conditions: + * 1. I cannot be held legally responsible for any damage or problems caused by this code. + * 2. If you make something cool using this code, give me a shout and tell me about it. + * + */ +#endregion + +using System; +using System.Windows.Forms; +using System.Drawing; +using System.Collections; +using System.Text; +using System.Runtime.InteropServices; + +namespace Screensavers +{ + /// + /// Provides initialization, timing and windowing facilities for screensavers. + /// + public abstract class Screensaver + { + /// + /// Creates a new with the given fullscreen mode. + /// + /// A value indicating the fullscreen windowing mode. + protected Screensaver(FullscreenMode fullscreenMode) + { + this.fullscreenMode = fullscreenMode; + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + Framerate = 30; + + framerateTimer.Elapsed += new System.Timers.ElapsedEventHandler(framerateTimer_Elapsed); + framerateTimer.Start(); + } + + /// + /// Creates a new that runs one window per screen. + /// + protected Screensaver() + : this(FullscreenMode.MultipleWindows) + { + } + + void framerateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + achievedFramerate = updatesThisSec; + updatesThisSec = 0; + if (OneSecondTick != null) + OneSecondTick(this, new EventArgs()); + } + + /// + /// Occurs before the screensaver windows close. + /// + public event EventHandler Exit; + + #region Multimedia Timer + + [DllImport("winmm.dll")] + static extern int timeSetEvent(int delay, int resolution, TimeCallback callback, int user, int mode); + + [DllImport("winmm.dll")] + static extern int timeKillEvent(int id); + + [DllImport("winmm.dll")] + static extern int timeGetTime(); + + [DllImport("user32.dll")] + public static extern bool LockWorkStation(); + + delegate void TimeCallback(uint id, uint msg, IntPtr user, IntPtr param1, IntPtr param2); + + TimeCallback timerCallback; + + int timerId; + + void StartUpdating() + { + timerCallback = new TimeCallback(TimerCallback); + //TIME_KILL_SYNCHRONOUS = 0x0100 + //TIME_PERIODIC = 0x0001 + timerId = timeSetEvent((int)(1000/(double)framerate), 0, timerCallback, 0, 0x0101); + + while (timerCallback != null) + { + updateEvent.WaitOne(); + DoUpdate(); + Application.DoEvents(); + updateEvent.Reset(); + } + + } + + void StopUpdating() + { + timerCallback = null; + timeKillEvent(timerId); + updateEvent.WaitOne(); + } + + System.Threading.ManualResetEvent updateEvent = new System.Threading.ManualResetEvent(false); + + void TimerCallback(uint id, uint msg, IntPtr user, IntPtr param1, IntPtr param2) + { + updateEvent.Set(); + } + + System.Timers.Timer framerateTimer = new System.Timers.Timer(1000); + + /// + /// Occurs once each second on a thread separate from the window thread. + /// + public event EventHandler OneSecondTick; + + int framerate; + + /// + /// Gets or sets the target framerate. + /// + public int Framerate + { + get { return framerate; } + set + { + if (value < 0) + throw new ArgumentOutOfRangeException(); + if (timerCallback != null) + { + StopUpdating(); + framerate = value; + StartUpdating(); + } + else + framerate = value; + } + } + + #endregion + + [StructLayout(LayoutKind.Sequential)] + struct RECT + { + public int left, top, right, bottom; + } + + [DllImport("user32.dll")] + static extern bool GetClientRect(IntPtr handle, out RECT rect); + [DllImport("user32.dll")] + static extern bool IsWindowVisible(IntPtr handle); + + static Rectangle GetClientRect(IntPtr handle) + { + RECT rect; + GetClientRect(handle, out rect); + return Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom); + } + + /// + /// Occurs when the screensaver should process its logic and render. + /// + public event EventHandler Update; + + event EventHandler PreUpdate; + event EventHandler PostUpdate; + + int achievedFramerate; + int updatesThisSec; + + /// + /// Actual framerate achieved. This value is updated once each second. + /// + public int AchievedFramerate + { + get { return achievedFramerate; } + } + + void DoUpdate() + { + if (screensaverMode == ScreensaverMode.Preview && !IsWindowVisible(windowHandle)) + { + StopUpdating(); + if (Exit != null) + Exit(this, new EventArgs()); + previewShutdownEvent.Set(); + return; + } + + if (PreUpdate != null) + PreUpdate(this, new EventArgs()); + if (Update != null) + Update(this, new EventArgs()); + if (PostUpdate != null) + PostUpdate(this, new EventArgs()); + updatesThisSec++; + } + + ScreensaverMode ProcessCommandLine() + { + string[] args = Environment.GetCommandLineArgs(); + + if (args.Length == 1 && IsScr) + return ScreensaverMode.Settings; + + if (args.Length < 2) + throw new FormatException(); + + if (args[1].ToLower().StartsWith("/c")) + { + return ScreensaverMode.Settings; + } + + switch (args[1].ToLower()) + { + case "w": + return ScreensaverMode.Windowed; + case "/s": + return ScreensaverMode.Normal; + case "/p": + if (args.Length < 3) + { + throw new FormatException(); + } + try + { + windowHandle = (IntPtr)uint.Parse(args[2]); + return ScreensaverMode.Preview; + } + catch (FormatException) + { + throw new FormatException(); + } + default: + throw new FormatException(); + } + } + + bool IsScr + { + get + { + return System.IO.Path.GetExtension(System.Reflection.Assembly.GetExecutingAssembly().CodeBase). + Equals(".scr", StringComparison.InvariantCultureIgnoreCase); + } + } + + /// + /// Start the screensaver in windowed mode if the file extension is not scr, unless a mode is specified in the command line. + /// Otherwise, if the file extension is scr, start the screensaver in config mode. + /// + public void Run() + { + Run(ScreensaverMode.Windowed); + } + + /// + /// Start the screensaver in the specified mode unless one is specified in the command line. + /// + /// The mode in which to run the screensaver. This value cannot be . + public void Run(ScreensaverMode mode) + { + if (mode == ScreensaverMode.Preview && windowHandle == IntPtr.Zero) + throw new ArgumentException("Cannot explicity run in preview mode", "mode"); + + if (isEnded) + throw new Exception("This screensaver has already finished running"); + + try + { + this.screensaverMode = ProcessCommandLine(); + } + catch (FormatException) + { + this.screensaverMode = mode; + } + + try + { + switch (screensaverMode) + { + case ScreensaverMode.Windowed: + RunWindowed(); + break; + case ScreensaverMode.Settings: + ShowSettingsDialog(); + break; + case ScreensaverMode.Normal: + if (!closeOnMouseMoveOverride) + closeOnMouseMove = true; + if (!closeOnClickOverride) + closeOnClick = true; + if (!closeOnKeyboardInputOverride) + closeOnKeyboardInput = true; + + RunNormal(); + break; + case ScreensaverMode.Preview: + RunPreview(); + break; + } + } + finally + { + isEnded = true; + } + + } + + FullscreenMode fullscreenMode = FullscreenMode.SingleWindow; + ScreensaverMode screensaverMode; + + /// + /// Gets the current running mode of the screensaver. + /// + public ScreensaverMode Mode + { + get { return screensaverMode; } + } + + IntPtr windowHandle = IntPtr.Zero; + + /// + /// Occurs after the windows are created, before the screensaver runs. + /// + public event EventHandler Initialize; + + bool closeOnMouseMove; + bool closeOnMouseMoveOverride; + + /// + /// Gets or sets a value indicating whether or not the screensaver should close when the user moves the mouse. + /// + /// This value is true by default in all modes except . + public bool CloseOnMouseMove + { + get { return closeOnMouseMove; } + set { closeOnMouseMove = value; closeOnMouseMoveOverride = true; } + } + + bool closeOnClick; + bool closeOnClickOverride; + + /// + /// Gets or sets a value indicating whether or not the screensaver should close when the user clicks the mouse. + /// + /// This value is true by default in all modes except . + public bool CloseOnClick + { + get { return closeOnClick; } + set { closeOnClick = value; closeOnClickOverride = true; } + } + + bool closeOnKeyboardInput; + bool closeOnKeyboardInputOverride; + + /// + /// Gets or sets a value indicating whether or not the screensaver should close when the user presses a key. + /// + /// This value is true by default in all modes except . + public bool CloseOnKeyboardInput + { + get { return closeOnKeyboardInput; } + set { closeOnKeyboardInput = value; closeOnKeyboardInputOverride = true; } + } + + WindowCollection windows; + + /// + /// Gets a collection of all of the running screensaver windows. + /// + public WindowCollection Windows + { + get { return windows; } + } + + Window window0; + + /// + /// Gets the primary screensaver window. + /// + public Window Window0 + { + get + { + if(window0 != null) + return window0; + + if (windows == null || windows.Count == 0) + return null; + + window0 = windows[0]; + + return window0; + } + } + + Graphics graphics0; + + /// + /// Gets the GDI graphics object for the primary window. + /// + public Graphics Graphics0 + { + get + { + if (graphics0 != null) + return graphics0; + + if (Window0 == null) + return null; + + graphics0 = Window0.Graphics; + return graphics0; + } + } + + string settingsText; + + /// + /// Gets or sets text to be displayed in the default settings message box. + /// + public string SettingsText + { + get { return settingsText; } + set { settingsText = value; } + } + + /// + /// Shows the settings dialog, or, by default, shows a message box indicating the assembly name, version and copyright information. + /// + protected virtual void ShowSettingsDialog() + { + System.IO.StringWriter sw = new System.IO.StringWriter(); + System.Reflection.AssemblyName name = System.Reflection.Assembly.GetExecutingAssembly().GetName(); + sw.WriteLine(name.Name); + sw.WriteLine("Version " + name.Version); + + object[] attribs = + System.Reflection.Assembly.GetExecutingAssembly(). + GetCustomAttributes(typeof(System.Reflection.AssemblyDescriptionAttribute), false); + if (attribs != null && attribs.Length != 0) + { + System.Reflection.AssemblyDescriptionAttribute desc = attribs[0] as System.Reflection.AssemblyDescriptionAttribute; + if (desc.Description != string.Empty) + { + sw.WriteLine(desc.Description); + } + } + + attribs = + System.Reflection.Assembly.GetExecutingAssembly(). + GetCustomAttributes(typeof(System.Reflection.AssemblyCopyrightAttribute), false); + if (attribs != null && attribs.Length != 0) + { + System.Reflection.AssemblyCopyrightAttribute copyright = attribs[0] as System.Reflection.AssemblyCopyrightAttribute; + if (copyright.Copyright != string.Empty) + { + sw.WriteLine(); + sw.WriteLine(copyright.Copyright); + } + } + + if (settingsText != null && settingsText != string.Empty) + { + sw.WriteLine(); + sw.WriteLine(SettingsText); + } + + MessageBox.Show(sw.ToString(), "PixieSaver", MessageBoxButtons.OK); + } + + System.Threading.AutoResetEvent previewShutdownEvent = new System.Threading.AutoResetEvent(false); + + private void RunPreview() + { +#if DEBUG + System.Diagnostics.Debugger.Launch(); +#endif + windows = new WindowCollection(new Window[] { new Window(this, windowHandle) }); + InitializeAndStart(); + previewShutdownEvent.WaitOne(); + } + + private void RunNormal() + { + Cursor.Hide(); + switch (fullscreenMode) + { + case FullscreenMode.SingleWindow: + RunNormalSingleWindow(); + break; + case FullscreenMode.MultipleWindows: + RunNormalMultipleWindows(); + break; + } + } + + private void RunNormalMultipleWindows() + { + //List windows = new List(); + ArrayList windows = new ArrayList(); + + Form primary = new Form(); + primary.StartPosition = FormStartPosition.Manual; + primary.Location = Screen.PrimaryScreen.Bounds.Location; + primary.Size = Screen.PrimaryScreen.Bounds.Size; + primary.BackColor = Color.Black; +#if !DEBUG + primary.TopMost = true; +#endif + primary.FormBorderStyle = FormBorderStyle.None; + primary.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; + + foreach (Screen screen in Screen.AllScreens) + { + if (screen == Screen.PrimaryScreen) + continue; + + Form form = new Form(); + form.Owner = primary; + form.BackColor = Color.Black; +#if !DEBUG + form.TopMost = true; +#endif + form.StartPosition = FormStartPosition.Manual; + form.Location = screen.Bounds.Location; + form.Size = screen.Bounds.Size; + form.FormBorderStyle = FormBorderStyle.None; + form.Text = primary.Text; + + windows.Add(new Window(this, form)); + } + + windows.Insert(0, new Window(this, primary)); + + primary.Load += delegate(object sender, EventArgs e) + { + foreach (Window window in this.windows) + { + if (window.Form.Owner == null) + continue; + window.Form.Show(); + } + }; + + this.windows = new WindowCollection(windows.ToArray(typeof(Window)) as Window[]); + + primary.Show(); + InitializeAndStart(); + } + + private void RunNormalSingleWindow() + { + Form form = new Form(); + Rectangle rect = GetVirtualScreenRect(); + form.Location = rect.Location; + form.Size = rect.Size; + form.BackColor = Color.Black; +#if !DEBUG + form.TopMost = true; +#endif + form.FormBorderStyle = FormBorderStyle.None; + form.StartPosition = FormStartPosition.Manual; + form.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; + + windows = new WindowCollection(new Window[] { new Window(this, form) }); + + form.Show(); + InitializeAndStart(); + } + + static Rectangle GetVirtualScreenRect() + { + Screen[] screens = Screen.AllScreens; + Rectangle rect = Rectangle.Empty; + foreach (Screen screen in Screen.AllScreens) + rect = Rectangle.Union(rect, screen.Bounds); + return rect; + } + + private void RunWindowed() + { + + Form form = new Form(); + form.FormBorderStyle = FormBorderStyle.FixedSingle; + form.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; + form.StartPosition = FormStartPosition.CenterScreen; + form.BackColor = Color.Black; +#if !DEBUG + form.TopMost = true; +#endif + form.MaximizeBox = false; + form.ClientSize = new Size((int)(Screen.PrimaryScreen.WorkingArea.Width * 0.9), (int)(Screen.PrimaryScreen.WorkingArea.Height * 0.9)); + + windows = new WindowCollection(new Window[] { new Window(this, form) }); + + form.Show(); + InitializeAndStart(); + } + + void InitializeAndStart() + { + if (Initialize != null) + Initialize(this, new EventArgs()); + + if (Window0 != null && Window0.Form != null) + Window0.Form.FormClosing += new FormClosingEventHandler(Form_FormClosing); + + StartUpdating(); + } + + void Form_FormClosing(object sender, FormClosingEventArgs e) + { + StopUpdating(); + LockWorkStation(); + if (Exit != null) + Exit(this, new EventArgs()); + e.Cancel = false; + } + + #region IDisposable Members + + bool isEnded = false; + + #endregion + + void OnMouseMove() + { + //if (closeOnMouseMove) + //{ + // if (Window0.Form != null) + // Window0.Form.Close(); + // else + // Application.Exit(); + //} + } + + void OnKeyboardInput() + { + if (closeOnMouseMove) + { + if (Window0.Form != null) + Window0.Form.Close(); + else + Application.Exit(); + } + } + + void OnMouseClick() + { + if (closeOnMouseMove) + { + if (Window0.Form != null) + Window0.Form.Close(); + else + { + Application.Exit(); + } + } + } + + /// + /// Represents a screensaver window. + /// + public class Window + { + internal Window(Screensaver screensaver, Form form) + { + this.screensaver = screensaver; + this.form = form; + this.size = form.ClientSize; + this.graphics = form.CreateGraphics(); + this.handle = form.Handle; + + form.MouseMove += new MouseEventHandler(form_MouseMove); + form.MouseClick += new MouseEventHandler(form_MouseClick); + form.MouseDoubleClick += new MouseEventHandler(form_MouseDoubleClick); + form.MouseDown += new MouseEventHandler(form_MouseDown); + form.MouseUp += new MouseEventHandler(form_MouseUp); + form.MouseWheel += new MouseEventHandler(form_MouseWheel); + + form.KeyDown += new KeyEventHandler(form_KeyDown); + form.KeyUp += new KeyEventHandler(form_KeyUp); + form.KeyPress += new KeyPressEventHandler(form_KeyPress); + + //form.BackColor = Color.Lime; + //form.TransparencyKey = Color.Lime; + form.Opacity = 0.3; + + this.screensaver.PreUpdate += new EventHandler(screensaver_PreUpdate); + this.screensaver.PostUpdate += new EventHandler(screensaver_PostUpdate); + } + + internal Window(Screensaver screensaver, IntPtr handle) + { + this.screensaver = screensaver; + this.handle = handle; + this.graphics = Graphics.FromHwnd(handle); + this.size = GetClientRect(handle).Size; + + this.screensaver.PreUpdate += new EventHandler(screensaver_PreUpdate); + this.screensaver.PostUpdate += new EventHandler(screensaver_PostUpdate); + } + + bool doubleBuffer = false; + bool doubleBufferSet = false; + + /// + /// Gets or sets a value indicating whether or not the Graphics object should be double buffered. + /// Set to false if the Graphics object will not be used. + /// + public bool DoubleBuffer + { + get + { + if (!doubleBufferSet) + DoubleBuffer = true; + return doubleBuffer; + } + set + { + doubleBufferSet = true; + if (doubleBuffer != value) + { + doubleBuffer = value; + if (doubleBuffer) + SetDoubleBuffer(); + else + UnsetDoubleBuffer(); + } + else + doubleBuffer = value; + } + } + + private void SetDoubleBuffer() + { + graphicsSwap = graphics; + BufferedGraphicsManager.Current.MaximumBuffer = this.Size; + buffer = BufferedGraphicsManager.Current.Allocate(graphicsSwap, new Rectangle(0, 0, Size.Width, Size.Height)); + graphics = buffer.Graphics; + } + + private void UnsetDoubleBuffer() + { + buffer.Dispose(); + graphics = graphicsSwap; + buffer = null; + graphicsSwap = null; + } + + BufferedGraphics buffer; + Graphics graphicsSwap; + + void screensaver_PreUpdate(object sender, EventArgs e) + { + } + + void screensaver_PostUpdate(object sender, EventArgs e) + { + if(doubleBuffer) + { + buffer.Render(graphicsSwap); + } + } + + #region Keyboard and Mouse Events + + void form_KeyPress(object sender, KeyPressEventArgs e) + { + if (KeyPress != null) + KeyPress(this, e); + screensaver.OnKeyboardInput(); + } + + void form_KeyUp(object sender, KeyEventArgs e) + { + if (KeyUp != null) + KeyUp(this, e); + screensaver.OnKeyboardInput(); + } + + void form_KeyDown(object sender, KeyEventArgs e) + { + if (KeyDown != null) + KeyDown(this, e); + screensaver.OnKeyboardInput(); + } + + void form_MouseWheel(object sender, MouseEventArgs e) + { + if (MouseWheel != null) + MouseWheel(this, e); + screensaver.OnMouseClick(); + } + + void form_MouseUp(object sender, MouseEventArgs e) + { + if (MouseUp != null) + MouseUp(this, e); + screensaver.OnMouseClick(); + } + + void form_MouseDown(object sender, MouseEventArgs e) + { + if (MouseDown!= null) + MouseDown(this, e); + screensaver.OnMouseClick(); + } + + void form_MouseDoubleClick(object sender, MouseEventArgs e) + { + if (MouseDoubleClick != null) + MouseDoubleClick(this, e); + screensaver.OnMouseClick(); + } + + void form_MouseClick(object sender, MouseEventArgs e) + { + if (MouseClick != null) + MouseClick(this, e); + screensaver.OnMouseClick(); + } + + //Keep track of the initial mouse position since we want to ignore the MouseMove messages that are fired right when the form is created. + Point mousePosition = Point.Empty; + + void form_MouseMove(object sender, MouseEventArgs e) + { + if (MouseMove != null) + MouseMove(this, e); + + if (mousePosition == Point.Empty) + mousePosition = e.Location; + else if (mousePosition != e.Location) + screensaver.OnMouseMove(); + } + + /// + /// Occurs when the mouse is moved over this window. + /// + public event MouseEventHandler MouseMove; + /// + /// Occurs when the mouse is clicked inside this window. + /// + public event MouseEventHandler MouseClick; + /// + /// Occurs when the mouse is double clicked inside this window. + /// + public event MouseEventHandler MouseDoubleClick; + /// + /// Occurs when the mouse wheel is moved inside this window. + /// + public event MouseEventHandler MouseWheel; + /// + /// Occurs when a mouse button goes up inside this window. + /// + public event MouseEventHandler MouseUp; + /// + /// Occurs when a mouse button goes down inside this window. + /// + public event MouseEventHandler MouseDown; + + /// + /// Occurs when a key goes down. + /// + public event KeyEventHandler KeyDown; + /// + /// Occurs when a key is released. + /// + public event KeyEventHandler KeyUp; + /// + /// Occurs when a key is pressed. + /// + public event KeyPressEventHandler KeyPress; + + #endregion + + object tag; + + /// + /// Gets or sets a tag value. + /// + public object Tag + { + get { return tag; } + set { tag = value; } + } + + Screensaver screensaver; + + /// + /// Gets the for which this window was created. + /// + public Screensaver Screensaver + { + get { return screensaver; } + } + + Form form; + + /// + /// Gets the form encapsulating this window. + /// This property is null if the screensaver is running in preview mode. + /// + public Form Form + { + get { return form; } + } + + IntPtr handle; + + /// + /// Gets the native handle of the window. + /// + public IntPtr Handle + { + get { return handle; } + } + + Size size; + + /// + /// Gets the size of the window. + /// + public Size Size + { + get { return size; } + } + + Graphics graphics; + + /// + /// Gets the GDI graphics object for this window. + /// + public Graphics Graphics + { + get + { + //Only set double buffering if the Graphics object is being used. + if (!doubleBufferSet) + DoubleBuffer = true; + return graphics; + } + } + + /// + /// Gets the screen on which this window resides + /// + public Screen Screen + { + get + { + return Screen.FromHandle(handle); + } + } + + /// + /// Gets the display device index to use with this window. + /// + public int DeviceIndex + { + get + { + Screen thisScreen = Screen; + for (int i = 0; i < Screen.AllScreens.Length; i++) + if (Screen.AllScreens[i].Equals(thisScreen)) + return i; + throw new ApplicationException(); + } + } + } + + /// + /// Represents a collection of screensaver windows. + /// + public class WindowCollection : IEnumerable + { + internal WindowCollection(Window[] windows) + { + this.windows = windows; + } + + Window[] windows; + + /// + /// Gets the window at the given index. + /// + /// The zero-based index of the screensaver window. + /// The window at the given index. + public Window this[int index] + { + get { return windows[index]; } + } + + /// + /// Gets the number of screensaver windows available. + /// + public int Count + { + get { return windows.Length; } + } + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return windows.GetEnumerator(); + } + + #endregion + } + } + + /// + /// Specifies the types of multiple monitor support to make available. + /// + public enum FullscreenMode + { + /// + /// Single window covering all monitors. + /// + SingleWindow, + /// + /// Multiple windows, one for each monitor. + /// + MultipleWindows + } + + /// + /// Specifies the mode in which to run the screensaver. + /// + public enum ScreensaverMode + { + /// + /// Show a the settings dialog. + /// + Settings, + /// + /// Render inside the preview box of the Windows Display Properties. + /// + Preview, + /// + /// Run the screensaver in full screen mode. + /// + Normal, + /// + /// Run the screensaver inside a fixed-sized window. + /// + Windowed + } +} \ No newline at end of file