diff --git a/Demo/App.config b/Demo/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/Demo/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Demo/Demo.csproj b/Demo/Demo.csproj
new file mode 100644
index 0000000..6e9d440
--- /dev/null
+++ b/Demo/Demo.csproj
@@ -0,0 +1,110 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B8318FEF-8FC2-44CF-A490-F4AFB70745E8}
+ WinExe
+ Demo
+ Demo
+ v4.7.2
+ 512
+ true
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ FormDemo.cs
+
+
+
+
+ FormDemo.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+ {7c49620c-5f61-4a4e-a6ca-166b18e4daa6}
+ SwitchWinForms
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/Demo/FormDemo.Designer.cs b/Demo/FormDemo.Designer.cs
new file mode 100644
index 0000000..2f8431e
--- /dev/null
+++ b/Demo/FormDemo.Designer.cs
@@ -0,0 +1,183 @@
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using SwitchWinForms; //Primary object for custom Titlebars, Body, Buttons, etc..
+
+namespace Demo
+{
+ partial class FormDemo
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private IContainer components = null;
+ private readonly Font DefaultButtonFont = new Font("Verdana", 12, FontStyle.Regular, GraphicsUnit.Pixel);
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(770, 488);
+ this.Name = "Form1";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+
+ }
+ #endregion
+
+ #region Added User code
+ ///
+ /// In use of SwitchWinForms.dll
+ ///
+ private void LoadSwitchWinForms()
+ {
+ _tbOptions = new SWFTitlebarOptions()
+ {
+ RoundedCorners = SWF_ARC_CORNERS.TopLeft | SWF_ARC_CORNERS.TopRight,
+ Icon = this.Icon.ToBitmap(),
+ RoundedRadius = 15,
+ Height = 30,
+ Padding = new Padding(2, 2, 2, 2),
+ BackColor = Color.FromArgb(255, 30, 30, 30),// SystemColors.ActiveCaption,
+ BorderColor = Color.Black,
+ BorderSize = 2,
+ ButtonsEnabled = SWF_TITLE_BUTTON.All,
+ Close = new SWFTitlebarOptions.ButtonsState() //customizing only the close and defaults for Min and Max/Norm
+ {
+ RoundedCorners = SWF_ARC_CORNERS.TopRight,
+ RoundedRadius = 5,
+ BorderColor = Color.Transparent,
+ BorderSize = 1,
+ BackColor = Color.Wheat,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = SWFUnicodeChars.CLOSE.ToString(),
+ Font = DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ },
+ Minimized = new SWFTitlebarOptions.ButtonsState() //customizing only the close and defaults for Min and Max/Norm
+ {
+ RoundedCorners = SWF_ARC_CORNERS.None,
+ RoundedRadius = 15,
+ BorderColor = Color.Transparent,
+ BorderSize = 1,
+ BackColor = Color.Wheat,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = SWFUnicodeChars.MIN.ToString(),
+ Font = DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ },
+ Maximize = new SWFTitlebarOptions.ButtonsState() //customizing only the close and defaults for Min and Max/Norm
+ {
+ RoundedCorners = SWF_ARC_CORNERS.None,
+ RoundedRadius = 15,
+ BorderColor = Color.Transparent,
+ BorderSize = 1,
+ BackColor = Color.Wheat,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = SWFUnicodeChars.MAX.ToString(),
+ Font = DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ },
+ Normal = new SWFTitlebarOptions.ButtonsState() //customizing only the close and defaults for Min and Max/Norm
+ {
+ RoundedCorners = SWF_ARC_CORNERS.None,
+ RoundedRadius = 15,
+ BorderColor = Color.Transparent,
+ BorderSize = 1,
+ BackColor = Color.Wheat,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = SWFUnicodeChars.NORM.ToString(),
+ Font = DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ },
+ TextSetup = new TextUtil.TextOptions()
+ {
+ //BackgroundImage = (Image)SWFBoxing.ImageFromFile(@"imgs\test.png"),
+ //BackgroundImageLayout = SWF_BG_IMG_LAYOUT.Tile,
+ //ReplaceImageColor = new List() { new ReplaceColor(Color.FromArgb(241, 81, 27), Color.Transparent, 100) },
+ Text = $"Demo v1",
+ Color = Color.Wheat,
+ Font = new Font("Verdana", 10, FontStyle.Bold),
+ HorizonalAlign = StringAlignment.Near,
+ VerticalAlign = StringAlignment.Center
+ },
+ };
+ _frmOptions = new SWFBoxingOptions()
+ {
+ Name = "FrmBody",
+ Type = SWF_BOX_TYPE.FormBody,
+ TitleBarHeight = _tbOptions.Height, //default is 30, if not set for SWF_BOX_TYPE.FormBody
+ RoundedCorners = SWF_ARC_CORNERS.BottomLeft | SWF_ARC_CORNERS.BottomRight,
+ RoundedRadius = 15,
+ BackColor = Color.FromArgb(255, 62, 62, 66),
+ BorderColor = Color.Black,
+ BorderSize = 2,
+ Location = new Point(0, 0),
+ Padding = new Padding(2),
+ Size = new Size(this.Width, this.Height),
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Wheat,
+ Text = "Gavin",
+ Font = new Font("Verdana", 24, FontStyle.Bold, GraphicsUnit.Pixel),
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center
+ },
+ };
+
+ _frmMain = new SWFBoxing(this, _frmOptions);
+ _titleBar = new SWFTitlebar(this, _tbOptions);
+ }
+
+ private SWFTitlebarOptions _tbOptions;
+ private SWFBoxingOptions _frmOptions;
+ private SWFTitlebar _titleBar;
+ private SWFBoxing _frmMain;
+ private SWFBoxing _btn1TileImg;
+ private SWFBoxing _btn2StretchImg;
+ private SWFBoxing _lblDisplay;
+ private SWFBoxing _txtInput;
+ #endregion
+ }
+}
+
diff --git a/Demo/FormDemo.cs b/Demo/FormDemo.cs
new file mode 100644
index 0000000..4775e99
--- /dev/null
+++ b/Demo/FormDemo.cs
@@ -0,0 +1,223 @@
+using System; //EventArgs - required by Form Events
+using System.Collections.Generic; //List
+using System.Drawing; //Color, SystemColors, Font, FrontStyle, GraphicsUnit, StringAlignment, Point, Size
+using System.Windows.Forms; //Form
+using SwitchWinForms; //Primary object for custom Titlebars, Body, Buttons, etc..
+
+namespace Demo
+{
+ public partial class FormDemo : Form
+ {
+ /*
+ //pre-set unicode characters.
+ string close_Text_Example1 = SWFUnicodeChars.CLOSE;
+ //custom unicode characters can be passed here..
+ string close_Text_Example2 = new SWFUnicodeChars(10062).ToString();
+ */
+ public FormDemo()
+ {
+ InitializeComponent();
+ this.Icon = (Icon)SWFBoxing.ImageFromFile(@"imgs\test.png");
+ this.LoadSwitchWinForms();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ //example of callback for form resize. Do this on or after load.
+ //anything prior can cause errors, because the form isn't ready yet.
+ _frmMain.Resize += Form1_Resize;
+
+ SetupButtons();
+ }
+ private void Form1_Resize(object sender, EventArgs e)
+ {
+ ResetSizes();
+ }
+ private void SetupButtons()
+ {
+ _btn2StretchImg = new SWFBoxing(this, new SWFBoxingOptions()
+ {
+ Name = "BtnStretchedButton",
+ RoundedCorners = SWF_ARC_CORNERS.TopLeft | SWF_ARC_CORNERS.BottomRight,
+ RoundedRadius = 80,
+ BackColor = Color.DarkGray,
+ BorderColor = Color.Black,
+ BorderSize = 1,
+ Location = new Point(100, 100),
+ Padding = new Padding(2),
+ Size = new Size(200, 200),
+ IsAnimatedButton = true,
+ Type = SWF_BOX_TYPE.Button,
+ Cursors = new SWFCursors(Cursors.Hand, Cursors.Default),
+ Shadowing = new ShadowingSetup()
+ {
+ Visibilty = SWF_TRANSPARENT_PERCENTAGE.Forty,
+ Color = Color.Black,
+ Depth = 20
+ },
+ TextSetup = new TextUtil.TextOptions()
+ {
+ BackgroundImage = (Image)SWFBoxing.ImageFromFile(@"imgs\test.png"),
+ BackgroundImageLayout = SWF_BG_IMG_LAYOUT.Stretch,
+ ReplaceImageColor = new List() {
+ new ReplaceColor(Color.FromArgb(104, 104, 25), Color.Transparent, 100),
+ new ReplaceColor(Color.White, Color.Transparent, 90)
+ },
+ Color = Color.Black,
+ Text = "Click Stretched Button",
+ Font = new Font("Verdana", 10, FontStyle.Bold, GraphicsUnit.Pixel),
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center
+ },
+ });
+
+ _btn2StretchImg.MouseUp += (sender, e) =>
+ {
+ lock (_lblDisplay.BoxingOptions.TextSetup)
+ {
+ SWFBoxing box = (SWFBoxing)sender;
+ _lblDisplay.BoxingOptions.TextSetup.Text = $"Name: \"{box.BoxingOptions.Name}\" - Text:\"{box.BoxingOptions.TextSetup.Text}\"";
+ }
+ };
+
+ _btn1TileImg = new SWFBoxing(this, new SWFBoxingOptions()
+ {
+ Name = "BtnTiledButton",
+ RoundedCorners = SWF_ARC_CORNERS.TopRight,
+ RoundedRadius = 40,
+ //BackColor = Color.Red,
+ BackColor = Color.Wheat,
+ BorderColor = Color.Black,
+ BorderSize = 1,
+ Location = new Point(_btn2StretchImg.BoxingOptions.Location.X + _btn2StretchImg.BoxingOptions.Size.Width + 30
+ , _btn2StretchImg.BoxingOptions.Location.Y),
+ Padding = new Padding(2),
+ Size = new Size(200, 200),
+ IsAnimatedButton = true,
+ Cursors = new SWFCursors(Cursors.Hand, Cursors.Default),
+ Type = SWF_BOX_TYPE.Button,
+ Shadowing = new ShadowingSetup()
+ {
+ Visibilty = SWF_TRANSPARENT_PERCENTAGE.Ten,
+ Color = Color.Black,
+ Depth = 5
+ },
+ TextSetup = new TextUtil.TextOptions()
+ {
+ BackgroundImage = (Image)SWFBoxing.ImageFromFile(@"imgs\test.png"),
+ BackgroundImageLayout = SWF_BG_IMG_LAYOUT.Tile,
+ ReplaceImageColor = new List() {
+ new ReplaceColor(Color.FromArgb(251, 188, 9), Color.Transparent, 90),
+ new ReplaceColor(Color.FromArgb(104, 104, 25), Color.Transparent) },
+ Color = Color.Black,
+ Text = "Click Tiled Button",
+ Font = new Font("Verdana", 10, FontStyle.Bold, GraphicsUnit.Pixel),
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center
+ },
+ });
+
+ _btn1TileImg.MouseUp += (sender, e) =>
+ {
+ lock (_lblDisplay.BoxingOptions.TextSetup)
+ {
+ SWFBoxing box = (SWFBoxing)sender;
+ _lblDisplay.BoxingOptions.TextSetup.Text = $"Name: \"{box.BoxingOptions.Name}\" - Text:\"{box.BoxingOptions.TextSetup.Text}\"";
+ }
+ };
+
+ _lblDisplay = new SWFBoxing(this, new SWFBoxingOptions()
+ {
+ Name = "LblDisplay",
+ BackColor = Color.FromArgb(60, 255, 255, 255),
+ BorderColor = Color.Black,
+ BorderSize = 1,
+ Padding = new Padding(2),
+ //Location = new Point(0, _frmMain.BoxingOptions.Size.Height), //handled at resize
+ //Size = new Size(_frmMain.BoxingOptions.Size.Width, 30), //handled at resize
+ Type = SWF_BOX_TYPE.Label,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = "Waiting for click",
+ Font = new Font("Verdana", 10, FontStyle.Bold, GraphicsUnit.Pixel),
+ HorizonalAlign = StringAlignment.Near,
+ VerticalAlign = StringAlignment.Center
+ },
+ });
+
+ _txtInput = new SWFBoxing(this, new SWFBoxingOptions()
+ {
+ Name = "TxtInput",
+ BackColor = Color.White,
+ BorderColor = Color.Black,
+ BorderSize = 1,
+ Padding = new Padding(2),
+ Cursors = new SWFCursors(Cursors.IBeam, Cursors.Default),
+ //Location = new Point(30, _lblDisplay.BoxingOptions.Location.Y - 40), //handled at resize
+ //Size = new Size(_frmMain.BoxingOptions.Size.Width - 60, 30), //handled at resize
+ Type = SWF_BOX_TYPE.TextBox,
+ TextSetup = new TextUtil.TextOptions()
+ {
+ Color = Color.Black,
+ Text = "[Email Here]",
+ ValidInputExpression = @"^((\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)\s*[;]{0,1}\s*)+$",
+ Font = new Font("Courier New", 12, FontStyle.Bold, GraphicsUnit.Pixel),
+ HorizonalAlign = StringAlignment.Near,
+ VerticalAlign = StringAlignment.Center
+ },
+ });
+
+ _txtInput.Exception += (sender, e) =>
+ {
+ lock (_txtInput.BoxingOptions.TextSetup)
+ {
+ SWFBoxing box = (SWFBoxing)sender;
+
+ string msg = $"{box.BoxingOptions.Name}: {e.Exception.Message}";
+ _lblDisplay.BoxingOptions.TextSetup.Text = msg;
+ MessageBox.Show(msg, "Exception");
+ this.Invalidate();
+ }
+ };
+
+ _txtInput.Success += (sender, e) =>
+ {
+ lock (_txtInput.BoxingOptions.TextSetup)
+ {
+ SWFBoxing box = (SWFBoxing)sender;
+
+ string msg = $"{box.BoxingOptions.Name}: {e.Message}";
+ _lblDisplay.BoxingOptions.TextSetup.Text = msg;
+ this.Invalidate();
+ }
+ };
+
+ ResetSizes();
+ }
+ private void ResetSizes()
+ {
+ Size reSize = new Size(this.ClientSize.Width, this.ClientSize.Height - _tbOptions.Height);
+
+ int w = (int)((double)reSize.Width * .3);
+ int h = (int)((double)reSize.Height * .3);
+ _btn1TileImg.BoxingOptions.Size = new Size(w, h);
+
+ w = (int)((double)reSize.Width);
+ h = (int)((double)reSize.Height);
+
+ int brd = _lblDisplay.BoxingOptions.BorderSize + 5;
+ _lblDisplay.BoxingOptions.Location = new Point(brd, h - 40);
+ _lblDisplay.BoxingOptions.Size = new Size(w - (brd * 2), 30);
+
+ _txtInput.BoxingOptions.Location = new Point(brd, _lblDisplay.BoxingOptions.Location.Y - 40);
+ _txtInput.BoxingOptions.Size = _lblDisplay.BoxingOptions.Size;
+ }
+ protected override void WndProc(ref Message m)
+ {
+ //this handles all form edges and button mouse overs for title.
+ if (_titleBar == null || !_titleBar.WndProc(ref m))
+ base.WndProc(ref m);
+ }
+ }
+}
diff --git a/Demo/FormDemo.resx b/Demo/FormDemo.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Demo/FormDemo.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Demo/Program.cs b/Demo/Program.cs
new file mode 100644
index 0000000..0c07285
--- /dev/null
+++ b/Demo/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Demo
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new FormDemo());
+ }
+ }
+}
diff --git a/Demo/Properties/AssemblyInfo.cs b/Demo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..eff49af
--- /dev/null
+++ b/Demo/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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("Demo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Demo")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[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("b8318fef-8fc2-44cf-a490-f4afb70745e8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Demo/Properties/Resources.Designer.cs b/Demo/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..8b245d3
--- /dev/null
+++ b/Demo/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// 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 Demo.Properties
+{
+
+
+ ///
+ /// 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 ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.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/Demo/Properties/Resources.resx b/Demo/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Demo/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/Demo/Properties/Settings.Designer.cs b/Demo/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..d196517
--- /dev/null
+++ b/Demo/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// 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 Demo.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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/Demo/Properties/Settings.settings b/Demo/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/Demo/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Demo/imgs/test.bmp b/Demo/imgs/test.bmp
new file mode 100644
index 0000000..793b541
Binary files /dev/null and b/Demo/imgs/test.bmp differ
diff --git a/Demo/imgs/test.gif b/Demo/imgs/test.gif
new file mode 100644
index 0000000..7a97f73
Binary files /dev/null and b/Demo/imgs/test.gif differ
diff --git a/Demo/imgs/test.ico b/Demo/imgs/test.ico
new file mode 100644
index 0000000..5906cf7
Binary files /dev/null and b/Demo/imgs/test.ico differ
diff --git a/Demo/imgs/test.jpg b/Demo/imgs/test.jpg
new file mode 100644
index 0000000..9c86e93
Binary files /dev/null and b/Demo/imgs/test.jpg differ
diff --git a/Demo/imgs/test.png b/Demo/imgs/test.png
new file mode 100644
index 0000000..a8d30bc
Binary files /dev/null and b/Demo/imgs/test.png differ
diff --git a/Demo/imgs/test.tif b/Demo/imgs/test.tif
new file mode 100644
index 0000000..4f01408
Binary files /dev/null and b/Demo/imgs/test.tif differ
diff --git a/SwitchWinForms.sln b/SwitchWinForms.sln
new file mode 100644
index 0000000..8cb7661
--- /dev/null
+++ b/SwitchWinForms.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33213.308
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SwitchWinForms", "SwitchWinForms\SwitchWinForms.csproj", "{7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{B8318FEF-8FC2-44CF-A490-F4AFB70745E8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B8318FEF-8FC2-44CF-A490-F4AFB70745E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B8318FEF-8FC2-44CF-A490-F4AFB70745E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B8318FEF-8FC2-44CF-A490-F4AFB70745E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B8318FEF-8FC2-44CF-A490-F4AFB70745E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DEBD63DC-842D-4950-8765-4C5C196429CF}
+ EndGlobalSection
+EndGlobal
diff --git a/SwitchWinForms/Handler/SWFBoxing.cs b/SwitchWinForms/Handler/SWFBoxing.cs
new file mode 100644
index 0000000..5c7fcac
--- /dev/null
+++ b/SwitchWinForms/Handler/SWFBoxing.cs
@@ -0,0 +1,485 @@
+using System;
+using System.Drawing;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ ///
+ /// Building custom boxes on your form.
+ ///
+ public class SWFBoxing : BoxMethods
+ {
+ #region Public Form Events and Delegates
+ //public delegate void SWFExceptionEventHandler(object sender, SWFMessageEventArgs e);
+ public delegate void SWFMessageHandler(object sender, SWFMessageEventArgs e);
+ public event MouseEventHandler MouseDown;
+ public event MouseEventHandler MouseUp;
+ public event MouseEventHandler MouseMove;
+ public event EventHandler MouseLeave;
+ public event EventHandler Resize;
+ public event PaintEventHandler Paint;
+ public event KeyEventHandler KeyUp;
+ public event KeyEventHandler KeyDown;
+ public event KeyPressEventHandler KeyPress;
+ public event SWFMessageHandler Exception;
+ public event SWFMessageHandler Success;
+ #endregion
+
+ #region Constructor
+ ///
+ /// Building custom boxes on your form.
+ ///
+ /// Form Handle => new SWFBoxing(this, ...)
+ ///
+ ///
+ public SWFBoxing(Form frm, SWFBoxingOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("Options is required.");
+ if (string.IsNullOrWhiteSpace(options.Name))
+ throw new ArgumentNullException($"Name property for this box is required.\nType: {options.Type}\nText: {options.TextSetup.Text}");
+
+ if (GetZIndex(ref options, out int z))
+ throw new ArgumentNullException($"'{options.Name}' already exists.");
+
+ options.TextSetup.TextCursor = options.TextSetup.Text.Length;
+
+ this.SetBoxOptions = options;
+ this.BoxingOptions.Parent = frm;
+ this.BoxingOptions.ZIndex = z;
+
+ BoxingLoc = new Rectangle(this.BoxingOptions.Location, this.BoxingOptions.Size);
+
+ SetupOptions();
+ }
+ #endregion
+
+ #region Private Properties
+ private Rectangle BoxingLoc { get; set; } = new Rectangle();
+ private bool IgnoreKeyPress { get; set; } = false;
+ private bool ButtonClicked { get; set; } = false;
+ private bool InputStart { get; set; } = false;
+ private bool IsInBounds { get; set; } = false;
+ private bool CursorChanged { get; set; } = false;
+ private string DefaultTip { get; set; } = string.Empty;
+ private SWFBoxingOptions SetBoxOptions { get; set; } = new SWFBoxingOptions();
+ #endregion
+
+ #region Public Properties
+
+ ///
+ /// All setup options for the object your creating. Can be passed in with Constructor or this property.
+ ///
+ public SWFBoxingOptions BoxingOptions { get { return SetBoxOptions; } }
+
+ ///
+ /// Get bounderies for this object.
+ ///
+ public Rectangle Rectangle { get { return BoxingLoc; } }
+
+ ///
+ /// Get location for this object.
+ ///
+ public Point Location { get { return BoxingLoc.Location; } }
+
+ ///
+ /// Get size for this object.
+ ///
+ public Size Size { get { return BoxingLoc.Size; } }
+
+ ///
+ /// Get left boundary for this object.
+ ///
+ public int Left { get { return BoxingLoc.X; } }
+
+ ///
+ /// Get top boundary for this object.
+ ///
+ public int Top { get { return BoxingLoc.Y; } }
+
+ ///
+ /// Get right boundary for this object.
+ ///
+ public int Right { get { return BoxingLoc.X + BoxingLoc.Width; } }
+
+ ///
+ /// Get bottom boundary for this object.
+ ///
+ public int Bottom { get { return BoxingLoc.Y + BoxingLoc.Height; } }
+ #endregion
+
+ #region Private Keyboard Events
+ private void MR_KeyUp(object sender, KeyEventArgs e)
+ {
+ KeyUp?.Invoke(this, e);
+ }
+ private void MR_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (this.BoxingOptions != null && this.InputStart)
+ {
+ bool changes = false;
+ string text = this.BoxingOptions.TextSetup.Text;
+
+ //KeyPress doesn't capture some keys. We must handle them here.
+ if (e.KeyCode == Keys.Right)
+ {
+ this.BoxingOptions.TextSetup.TextCursor++;
+ changes = true;
+ }
+ else if (e.KeyCode == Keys.Left)
+ {
+ this.BoxingOptions.TextSetup.TextCursor--;
+ changes = true;
+ }
+ else if (e.KeyCode == Keys.Delete)
+ {
+ Console.WriteLine($"KeyDown: {e.KeyCode}");
+ //only used for Delete at the moment.
+ if (!string.IsNullOrEmpty(text))
+ {
+ int textCursor = this.BoxingOptions.TextSetup.TextCursor;
+ if (text.Length - (textCursor) > 0)
+ {
+ string newText = text.Substring(0, textCursor);
+ newText += text.Substring(textCursor + 1, text.Length - (textCursor + 1));
+ text = newText;
+ changes = true;
+
+ if (textCursor - 1 > text.Length)
+ this.BoxingOptions.TextSetup.TextCursor--;
+ }
+ }
+ else
+ Console.WriteLine($"KeyDown: Nothing to {Keys.Delete}");
+ }
+ else if (e.KeyCode == Keys.Enter)
+ {
+ bool valid = true;
+ string validMessage = "No expression found";
+
+ lock (SetBoxOptions)
+ this.IgnoreKeyPress = true;
+
+ Console.WriteLine($"KeyDown: {e.KeyCode}");
+ if (this.BoxingOptions.TextSetup.ValidInputExpression != null)
+ {
+ string pattern = this.BoxingOptions.TextSetup.ValidInputExpression;
+ valid = Regex.Match(text, pattern, RegexOptions.IgnoreCase).Success;
+ if (valid)
+ validMessage = "Expression is valid";
+ }
+
+ if (valid)
+ {
+ changes = true;
+ this.InputStart = false;
+ this.BoxingOptions.TextSetup.TextCursor = text.Length;
+ Success?.Invoke(this,
+ new SWFMessageEventArgs(
+ validMessage
+ ));
+ }
+ else
+ {
+ Exception?.Invoke(this,
+ new SWFMessageEventArgs(
+ new Exception("Failed regex expression.")
+ ));
+ }
+ }
+ else if (e.KeyCode == Keys.Escape)
+ {
+ lock (SetBoxOptions)
+ {
+ this.IgnoreKeyPress = true;
+ this.InputStart = false;
+ }
+
+ Console.WriteLine($"KeyDown: {e.KeyCode}");
+ changes = true;
+ text = this.DefaultTip;
+ this.BoxingOptions.TextSetup.TextCursor = text.Length;
+ }
+ else if (e.KeyCode == Keys.Back)
+ {
+ Console.WriteLine($"KeyDown: {e.KeyCode}");
+ int textCursor = this.BoxingOptions.TextSetup.TextCursor;
+ if (!string.IsNullOrEmpty(text) && textCursor > 0)
+ {
+ string newText = text.Substring(0, textCursor - 1);
+ int size = text.Length > textCursor ? text.Length - textCursor : textCursor - text.Length;
+ newText += text.Substring(textCursor, size);
+ text = newText;
+
+ changes = true;
+ this.BoxingOptions.TextSetup.TextCursor--;
+ }
+ else
+ Console.WriteLine($"Nothing to {e.KeyCode}");
+
+ lock (SetBoxOptions)
+ this.IgnoreKeyPress = true;
+ }
+
+ if (this.BoxingOptions.TextSetup.TextCursor < 0)
+ this.BoxingOptions.TextSetup.TextCursor = 0;
+ else if (this.BoxingOptions.TextSetup.TextCursor > text.Length)
+ this.BoxingOptions.TextSetup.TextCursor = text.Length;
+
+ if (changes)
+ {
+ this.BoxingOptions.TextSetup.Text = text;
+ this.BoxingOptions.Parent.Invalidate();
+ }
+ }
+
+ KeyDown?.Invoke(this, e);
+ }
+ private void MR_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (this.BoxingOptions != null && this.InputStart)
+ {
+ lock (SetBoxOptions)
+ {
+ if (!this.IgnoreKeyPress)
+ {
+ Console.WriteLine($"KeyPress: {e.KeyChar}");
+
+ string text = this.BoxingOptions.TextSetup.Text;
+ int textCursor = this.BoxingOptions.TextSetup.TextCursor;
+
+ string newText = string.IsNullOrEmpty(text) || textCursor == 0 ? "" :
+ text.Substring(0, textCursor);
+ string subText = string.IsNullOrEmpty(text) || textCursor == 0 ? "" :
+ text.Substring(textCursor, text.Length - textCursor);
+
+ this.BoxingOptions.TextSetup.TextCursor++;
+
+ text = newText;
+ text += e.KeyChar.ToString();
+ text += subText;
+
+ this.BoxingOptions.TextSetup.Text = text;
+ this.BoxingOptions.Parent.Invalidate();
+
+ if (this.BoxingOptions.TextSetup.TextCursor < 0)
+ this.BoxingOptions.TextSetup.TextCursor = 0;
+ else if (this.BoxingOptions.TextSetup.TextCursor > text.Length)
+ this.BoxingOptions.TextSetup.TextCursor = text.Length;
+ }
+ else
+ Console.WriteLine($"KeyPress: Ignoring {e.KeyChar}");
+
+ this.IgnoreKeyPress = false;
+ }
+ }
+
+ KeyPress?.Invoke(this, e);
+ }
+ #endregion
+
+ #region Private Mouse Events
+ private void MR_MouseLeave(object sender, EventArgs e)
+ {
+ if (CursorChanged && this.BoxingOptions != null)
+ {
+ CursorChanged = false;
+ this.BoxingOptions.Parent.Cursor = Cursors.Default;
+ }
+ this.MouseLeave?.Invoke(this, e);
+ }
+ private void MR_MouseUp(object sender, MouseEventArgs e)
+ {
+ if (this.BoxingOptions != null && this.ButtonClicked && this.IsInBounds)
+ {
+ this.ButtonClicked = false;
+ this.BoxingOptions.Location = new Point(this.BoxingOptions.Location.X - this.BoxingOptions.Shadowing.Depth,
+ this.BoxingOptions.Location.Y - this.BoxingOptions.Shadowing.Depth);
+ this.BoxingOptions.Parent.Invalidate();
+ }
+
+ if (this.IsInBounds)
+ MouseUp?.Invoke(this, e);
+ }
+ private void MR_MouseDown(object sender, MouseEventArgs e)
+ {
+ if (this.BoxingOptions == null)
+ return;
+
+ if (IsClickable() && this.IsInBounds)
+ {
+ if (ImOnTop(this.BoxingOptions))
+ {
+ if (this.BoxingOptions.Type == SWF_BOX_TYPE.TextBox)
+ {
+ this.InputStart = true;
+ string text = this.BoxingOptions.TextSetup.Text;
+ this.DefaultTip = text;
+
+ if (text.StartsWith("[") && text.EndsWith("]"))
+ this.BoxingOptions.TextSetup.Text = "";
+ this.BoxingOptions.Parent.Invalidate();
+ }
+ else if (this.BoxingOptions.Type == SWF_BOX_TYPE.Button && this.BoxingOptions.Shadowing.Depth > 0)
+ {
+ this.ButtonClicked = true;
+ this.BoxingOptions.Location = new Point(this.BoxingOptions.Location.X + this.BoxingOptions.Shadowing.Depth,
+ this.BoxingOptions.Location.Y + this.BoxingOptions.Shadowing.Depth);
+ this.BoxingOptions.Parent.Invalidate();
+ }
+
+ this.MouseDown?.Invoke(this, e);
+ }
+ }
+ }
+ private void MR_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (this.BoxingOptions == null)
+ return;
+
+ if(Global.IsInBounds(this.BoxingOptions.Parent, e.Location, this.BoxingLoc))
+ {
+ if (ImOnTop(this.BoxingOptions))
+ {
+ this.IsInBounds = true;
+ bool isClickable = IsClickable();
+ Cursor cursor = GetCursorByType(this.BoxingOptions.Parent, this.BoxingOptions.Cursors.OnMove, out bool cursorChanged);
+
+ if (isClickable && cursorChanged)
+ {
+ this.BoxingOptions.Parent.Cursor = cursor;
+ this.CursorChanged = cursorChanged;
+ }
+
+ this.MouseMove?.Invoke(this, e);
+ }
+ }
+ else
+ {
+ //check to see if this object was in bounds, if not, then ignore..
+ if (this.IsInBounds)
+ {
+ this.IsInBounds = false;
+ this.BoxingOptions.Parent.Cursor = Cursors.Default;
+ this.CursorChanged = true;
+ this.MouseLeave?.Invoke(this, e);
+ }
+
+ if (this.ButtonClicked)
+ {
+ this.ButtonClicked = false;
+ this.BoxingOptions.Location = new Point(this.BoxingOptions.Location.X - this.BoxingOptions.Shadowing.Depth,
+ this.BoxingOptions.Location.Y - this.BoxingOptions.Shadowing.Depth);
+ this.BoxingOptions.Parent.Invalidate();
+ }
+ }
+ }
+ #endregion
+
+ #region Private Form Events
+ private void MR_Resize(object sender, EventArgs e)
+ {
+ this.BoxingLoc = new Rectangle(this.BoxingOptions.Location, this.BoxingOptions.Size);
+ this.BoxingOptions.Parent.Invalidate();
+ this.Resize?.Invoke(this, e);
+ }
+ private void MR_Paint(object sender, PaintEventArgs e)
+ {
+ Rectangle rec = e.ClipRectangle;
+ Graphics g = e.Graphics;
+ if (g != null &&
+ this.BoxingOptions.Location.X < this.BoxingOptions.Parent.Width &&
+ this.BoxingOptions.Location.Y < this.BoxingOptions.Parent.Height)
+ {
+ if (this.BoxingOptions.Type == SWF_BOX_TYPE.FormBody)
+ {
+ this.BoxingOptions.Location = new Point(0, this.BoxingOptions.TitleBarHeight - this.BoxingOptions.BorderSize);
+ this.BoxingOptions.Size = new Size(this.BoxingOptions.Parent.Width,
+ this.BoxingOptions.Parent.Height - this.BoxingOptions.TitleBarHeight);
+
+ //cannot do shadowing on the form, as it's not able to draw off the form.
+ //possibly in the future, sizing of the form instead so shadow shows up,
+ //however, since the real form is pink, it might not work.
+ this.BoxingOptions.Shadowing = null;
+ }
+
+ Rectangle titleBG = new Rectangle(this.BoxingOptions.Location, this.BoxingOptions.Size);
+
+ BoxInfo bi = Global.CreateBox(g, new BoxInfo()
+ {
+ BackColor = this.BoxingOptions.BackColor,
+ ForeColor = this.BoxingOptions.TextSetup.Color,
+ BorderColor = this.BoxingOptions.BorderColor,
+ BorderSize = this.BoxingOptions.BorderSize,
+ Rectangle = titleBG,
+ HAlign = this.BoxingOptions.TextSetup.HorizonalAlign,
+ VAlign = this.BoxingOptions.TextSetup.VerticalAlign,
+ Font = this.BoxingOptions.TextSetup.Font,
+ Text = this.BoxingOptions.TextSetup.Text,
+ Padding = this.BoxingOptions.Padding,
+ Shadowing = this.BoxingOptions.Shadowing,
+ BackgroundImage = this.BoxingOptions.TextSetup.BackgroundImage,
+ RoundedCorners = this.BoxingOptions.RoundedCorners,
+ RoundedRadius = this.BoxingOptions.RoundedRadius,
+ BackgroundImageLayout = this.BoxingOptions.TextSetup.BackgroundImageLayout,
+ ReplaceImageColor = this.BoxingOptions.TextSetup.ReplaceImageColor,
+ ButtonClicked = this.ButtonClicked,
+ TextCursor = this.BoxingOptions.TextSetup.TextCursor,
+ Type = this.BoxingOptions.Type,
+ InputStart = this.InputStart,
+ });
+
+ if (bi.BackgroundImageModified)
+ {
+ this.BoxingOptions.TextSetup.BackgroundImage = bi.BackgroundImage;
+ this.BoxingOptions.TextSetup.ReplaceImageColor = bi.ReplaceImageColor;
+ }
+
+ BoxingLoc = new Rectangle(this.BoxingOptions.Location, this.BoxingOptions.Size);
+ }
+ this.Paint?.Invoke(this, e);
+ }
+ #endregion
+
+ #region Private Methods
+ private bool IsClickable()
+ {
+ if (this.MouseDown != null ||
+ this.MouseUp != null ||
+ this.BoxingOptions.Type == SWF_BOX_TYPE.Button ||
+ this.BoxingOptions.Type == SWF_BOX_TYPE.TextBox)
+ return true;
+ else
+ return false;
+ }
+ private void SetupOptions()
+ {
+ this.BoxingOptions.Parent.MouseMove += MR_MouseMove;
+ this.BoxingOptions.Parent.MouseLeave += MR_MouseLeave;
+ this.BoxingOptions.Parent.MouseUp += MR_MouseUp;
+ this.BoxingOptions.Parent.MouseDown += MR_MouseDown;
+ this.BoxingOptions.Parent.Paint += MR_Paint;
+ this.BoxingOptions.Parent.Resize += MR_Resize;
+ this.BoxingOptions.Parent.KeyPress += MR_KeyPress;
+ this.BoxingOptions.Parent.KeyUp += MR_KeyUp;
+ this.BoxingOptions.Parent.KeyDown += MR_KeyDown;
+ }
+ #endregion
+
+ #region Public Static Methods
+ ///
+ /// Load image from file. Supported files types are (gif,bmp,ico,tif,jpg,png).
+ ///
+ public static object ImageFromFile(string path)
+ {
+ if (typeof(T).Name.ToLower() == "image")
+ return (object)Global.GetImage(path);
+ else if (typeof(T).Name.ToLower() == "icon")
+ return (object)Global.GetIcon(path);
+ else
+ return null;
+ }
+ #endregion
+ }
+}
diff --git a/SwitchWinForms/Handler/SWFTitlebar.cs b/SwitchWinForms/Handler/SWFTitlebar.cs
new file mode 100644
index 0000000..1d31bd4
--- /dev/null
+++ b/SwitchWinForms/Handler/SWFTitlebar.cs
@@ -0,0 +1,378 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Reflection;
+using System.IO;
+
+namespace SwitchWinForms
+{
+ ///
+ /// Creating a custome Titlebar, this replaces your exists. Do not use more that one instnace per project.
+ ///
+ public partial class SWFTitlebar : BoxMethods
+ {
+ #region Constructor
+ public SWFTitlebar(Form frm, SWFTitlebarOptions options = null)
+ {
+ if (frm == null)
+ {
+ SetLastError = new ArgumentNullException("Missing Form Object");
+ throw SetLastError;
+ }
+
+ if (frm.FormBorderStyle != FormBorderStyle.None)
+ frm.FormBorderStyle = FormBorderStyle.None;
+
+ //Ensure doublebuffered set on form.
+ //This stops major flickering.
+ SetDoubleBuffered(frm);
+
+ frm.BackColor = Color.FromArgb(192, 0, 191);
+ frm.TransparencyKey = frm.BackColor;
+
+ if (frm.MinimumSize.Width == 0 &&
+ frm.MinimumSize.Height == 0)
+ frm.MinimumSize = new Size(100, 100);
+
+ TitleOptions = options ?? new SWFTitlebarOptions();
+ TitleOptions.GetSetParent = frm;
+
+ if (TitleOptions.TextSetup != null && !TitleOptions.TextSetup.Empty)
+ TitleOptions.Parent.Text = TitleOptions.TextSetup?.Text;
+
+ SetupOptions();
+ }
+ #endregion
+
+ #region Private Form Events
+ private void Form_MouseUp(object sender, MouseEventArgs e)
+ {
+ this.Drag = false;
+ }
+ private void Form_MouseDown(object sender, MouseEventArgs e)
+ {
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Close) == SWF_TITLE_BUTTON.Close
+ && Global.IsInBounds(TitleOptions.Parent, e.Location, this.BtnCloseRec, Cursors.Hand))
+ {
+ TitleOptions.Parent.Close();
+ }
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Minimize) == SWF_TITLE_BUTTON.Minimize
+ && Global.IsInBounds(TitleOptions.Parent, e.Location, this.BtnMinRec, Cursors.Hand))
+ {
+ TitleOptions.Parent.WindowState = FormWindowState.Minimized;
+ }
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Maximize_Normal) == SWF_TITLE_BUTTON.Maximize_Normal
+ && Global.IsInBounds(TitleOptions.Parent, e.Location, this.BtnMaxRec, Cursors.Hand))
+ {
+
+ if (TitleOptions.Parent.WindowState == FormWindowState.Maximized)
+ TitleOptions.Parent.WindowState = FormWindowState.Normal;
+ else
+ TitleOptions.Parent.WindowState = FormWindowState.Maximized;
+ }
+ else if (TitleOptions.Height > e.Location.Y)
+ {
+ this.StartPoint = e.Location;
+ this.Drag = true;
+ }
+ }
+ private void Form_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (this.Drag)
+ {
+ // if we should be dragging it, we need to figure out some movement
+ Point p1 = new Point(e.X, e.Y);
+ Point p2 = TitleOptions.Parent.PointToScreen(p1);
+ Point p3 = new Point(p2.X - this.StartPoint.X,
+ p2.Y - this.StartPoint.Y);
+
+ TitleOptions.Parent.Location = p3;
+ }
+ else
+ {
+ if (Global.IsInBounds(TitleOptions.Parent, e.Location, TitleOptions.Rectangle)
+ && TitleOptions.Parent.Cursor != Cursors.Default)
+ {
+ int x = 0;
+ int t = 0;
+ int b = 0;
+
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Minimize) == SWF_TITLE_BUTTON.Minimize)
+ {
+ x = this.BtnMinRec.Left;
+ t = this.BtnMinRec.Top;
+ b = this.BtnMinRec.Top + this.BtnMinRec.Height;
+ }
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Maximize_Normal) == SWF_TITLE_BUTTON.Maximize_Normal)
+ {
+ x = this.BtnMaxRec.Left;
+ t = this.BtnMaxRec.Top;
+ b = this.BtnMaxRec.Top + this.BtnMaxRec.Height;
+ }
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Close) == SWF_TITLE_BUTTON.Close)
+ {
+ x = this.BtnCloseRec.Left;
+ t = this.BtnCloseRec.Top;
+ b = this.BtnCloseRec.Top + this.BtnCloseRec.Height;
+ }
+
+ if (e.X < x || e.Y < t || e.Y > b)
+ TitleOptions.Parent.Cursor = Cursors.Default;
+ }
+ }
+ }
+ private void Form_Resize(object sender, EventArgs e)
+ {
+ if ((TitleOptions.Parent.MinimumSize.Width == 0 &&
+ TitleOptions.Parent.MinimumSize.Height == 0) ||
+ (TitleOptions.Parent.MinimumSize.Width == 100 &&
+ TitleOptions.Parent.MinimumSize.Height == 100))
+ {
+ int w = 0;
+ int fWidth = TitleOptions.Parent.Width + (this.BtnMinRec.Width / 2);
+
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Minimize) == SWF_TITLE_BUTTON.Minimize && this.BtnMinRec.Height > 0)
+ w = fWidth - this.BtnMinRec.Left;
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Maximize_Normal) == SWF_TITLE_BUTTON.Maximize_Normal && this.BtnMaxRec.Height > 0)
+ w = fWidth - this.BtnMaxRec.Left;
+ else if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Close) == SWF_TITLE_BUTTON.Close && this.BtnCloseRec.Height > 0)
+ w = fWidth - this.BtnCloseRec.Left;
+
+ if (w > 0)
+ TitleOptions.Parent.MinimumSize = new Size(w, 100);
+ }
+
+ TitleOptions.Parent.Invalidate();
+ }
+ private void Form_Paint(object sender, PaintEventArgs e)
+ {
+ Graphics g = e.Graphics;
+ if (g != null)
+ {
+ TitleOptions.Location = new Point(0, 0);
+ TitleOptions.Size = new Size(TitleOptions.Parent.Width, TitleOptions.Height);
+
+ /*if ((TitleOptions.RoundedCorners & SWF_ARC_CORNERS.TopLeft) > 0 && TitleOptions.TextSetup.HorizonalAlign == StringAlignment.Near)
+ {
+ float f = ((float)TitleOptions.RoundedRadius) * 0.5F;
+ int extra = (int)Math.Floor(f);
+ TitleOptions.Padding = new Padding(TitleOptions.Padding.Left + extra, TitleOptions.Padding.Top, TitleOptions.Padding.Right, TitleOptions.Padding.Bottom);
+ }*/
+
+ BoxInfo boxInfo = new BoxInfo()
+ {
+ BackColor = TitleOptions.BackColor,
+ ForeColor = TitleOptions.TextSetup.Color,
+ BorderColor = TitleOptions.BorderColor,
+ BorderSize = TitleOptions.BorderSize,
+ Rectangle = TitleOptions.Rectangle,
+ HAlign = TitleOptions.TextSetup.HorizonalAlign,
+ VAlign = TitleOptions.TextSetup.VerticalAlign,
+ Font = TitleOptions.TextSetup.Font,
+ Text = TitleOptions.TextSetup.Text,
+ Padding = TitleOptions.Padding,
+ BackgroundImage = TitleOptions.TextSetup.BackgroundImage,
+ RoundedCorners = TitleOptions.RoundedCorners,
+ RoundedRadius = TitleOptions.RoundedRadius,
+ BackgroundImageLayout = TitleOptions.TextSetup.BackgroundImageLayout,
+ ReplaceImageColor = TitleOptions.TextSetup.ReplaceImageColor,
+ Type = SWF_BOX_TYPE.Titlebar,
+ Icon = TitleOptions.Icon
+ };
+
+ BoxInfo bi = Global.CreateBox(g, boxInfo); //title
+
+ if (bi.BackgroundImageModified)
+ {
+ TitleOptions.TextSetup.BackgroundImage = bi.BackgroundImage;
+ TitleOptions.TextSetup.ReplaceImageColor = bi.ReplaceImageColor;
+ }
+
+ CreateButtons(g, boxInfo); //title buttons
+ }
+ }
+ #endregion
+
+ #region Private Methods
+ private bool SetDoubleBuffered(Form frm)
+ {
+ bool retVal = false;
+ if (SystemInformation.TerminalServerSession)
+ {
+ SetLastError = new Exception("## WARN ##, Flicking may occur, because your in a terminal session.");
+ return retVal;
+ }
+
+ if (frm != null)
+ {
+ try
+ {
+ PropertyInfo aProp =
+ typeof(Control).GetProperty("DoubleBuffered",
+ BindingFlags.NonPublic | BindingFlags.Instance);
+
+ aProp.SetValue(frm, true, null);
+ retVal = true;
+ }
+ catch (Exception ex)
+ {
+ SetLastError = ex;
+ }
+ }
+ else
+ SetLastError = new Exception("## WARN ##, Missing Form object.");
+
+ return retVal;
+ }
+ private void CreateButtons(Graphics g, BoxInfo boxInfo)
+ {
+ int buttonPadding = 2;
+ Rectangle titleRect = boxInfo.Rectangle;
+ Rectangle btnRect = boxInfo.Rectangle;
+ BoxInfo newBtnSetup;
+
+ btnRect.Height = titleRect.Height - (TitleOptions.Padding.Top + TitleOptions.Padding.Bottom) - (boxInfo.BorderSize * 2);
+ btnRect.Width = btnRect.Height;
+
+ float f = ((float)TitleOptions.RoundedRadius) * 0.5F;
+ int extra = (int)Math.Floor(f);
+
+ if (TitleOptions.Icon != null)
+ {
+ btnRect.X = TitleOptions.Padding.Left + TitleOptions.BorderSize;
+ btnRect.Y = TitleOptions.Padding.Top + TitleOptions.BorderSize;
+
+ if ((TitleOptions.RoundedCorners & SWF_ARC_CORNERS.TopLeft) > 0)
+ btnRect.X += extra;
+
+ newBtnSetup = new BoxInfo()
+ {
+ Rectangle = btnRect,
+ BackgroundImageLayout = SWF_BG_IMG_LAYOUT.Normal,
+ BorderSize = TitleOptions.Close.BorderSize,
+ BorderColor = TitleOptions.Close.BorderColor,
+ RoundedCorners = TitleOptions.Close.RoundedCorners,
+ RoundedRadius = TitleOptions.Close.RoundedRadius,
+ BackgroundImage = TitleOptions.Icon,
+ };
+ //newBtnSetup.Rectangle = new Rectangle(new Point(30, 0), new Size(200, 200));
+
+ Global.CreateBox(g, newBtnSetup);
+ }
+
+ btnRect.X = titleRect.Width - btnRect.Width - TitleOptions.Padding.Right - TitleOptions.BorderSize;
+ btnRect.Y = boxInfo.Rectangle.Y + TitleOptions.Padding.Top + TitleOptions.BorderSize;
+
+ if ((TitleOptions.RoundedCorners & SWF_ARC_CORNERS.TopRight) > 0)
+ btnRect.X -= extra;
+
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Close) > 0)
+ {
+ newBtnSetup = new BoxInfo()
+ {
+ BackColor = TitleOptions.Close.BackColor,
+ ForeColor = TitleOptions.Close.TextSetup.Color,
+ BorderSize = TitleOptions.Close.BorderSize,
+ BorderColor = TitleOptions.Close.BorderColor,
+ Font = TitleOptions.Close.TextSetup.Font,
+ Padding = TitleOptions.Close.Padding,
+ HAlign = TitleOptions.Close.TextSetup.HorizonalAlign,
+ VAlign = TitleOptions.Close.TextSetup.VerticalAlign,
+ Rectangle = btnRect,
+ Text = TitleOptions.Close.TextSetup.Text,
+ RoundedCorners = TitleOptions.Close.RoundedCorners,
+ RoundedRadius = TitleOptions.Close.RoundedRadius
+ };
+
+ this.BtnCloseRec = newBtnSetup.Rectangle;
+ Global.CreateBox(g, newBtnSetup);
+ btnRect.X -= (btnRect.Width + buttonPadding + boxInfo.BorderSize);
+ newBtnSetup.Rectangle = btnRect;
+ }
+ else
+ this.BtnCloseRec = new Rectangle();
+
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Maximize_Normal) > 0)
+ {
+ if (TitleOptions.Parent.WindowState == FormWindowState.Maximized)
+ {
+ newBtnSetup = new BoxInfo()
+ {
+ BackColor = TitleOptions.Maximize.BackColor,
+ ForeColor = TitleOptions.Maximize.TextSetup.Color,
+ BorderSize = TitleOptions.Maximize.BorderSize,
+ BorderColor = TitleOptions.Maximize.BorderColor,
+ Font = TitleOptions.Maximize.TextSetup.Font,
+ Padding = TitleOptions.Maximize.Padding,
+ HAlign = TitleOptions.Maximize.TextSetup.HorizonalAlign,
+ VAlign = TitleOptions.Maximize.TextSetup.VerticalAlign,
+ Rectangle = btnRect,
+ Text = TitleOptions.Maximize.TextSetup.Text,
+ RoundedCorners = TitleOptions.Maximize.RoundedCorners,
+ RoundedRadius = TitleOptions.Maximize.RoundedRadius
+ };
+ }
+ else
+ {
+ newBtnSetup = new BoxInfo()
+ {
+ BackColor = TitleOptions.Normal.BackColor,
+ ForeColor = TitleOptions.Normal.TextSetup.Color,
+ BorderSize = TitleOptions.Normal.BorderSize,
+ BorderColor = TitleOptions.Normal.BorderColor,
+ Font = TitleOptions.Normal.TextSetup.Font,
+ Padding = TitleOptions.Normal.Padding,
+ HAlign = TitleOptions.Normal.TextSetup.HorizonalAlign,
+ VAlign = TitleOptions.Normal.TextSetup.VerticalAlign,
+ Rectangle = btnRect,
+ Text = TitleOptions.Normal.TextSetup.Text,
+ RoundedCorners = TitleOptions.Normal.RoundedCorners,
+ RoundedRadius = TitleOptions.Normal.RoundedRadius
+ };
+ }
+
+ this.BtnMaxRec = newBtnSetup.Rectangle;
+ Global.CreateBox(g, newBtnSetup);
+ btnRect.X -= (btnRect.Width + buttonPadding + boxInfo.BorderSize);
+ newBtnSetup.Rectangle = btnRect;
+ }
+ else
+ this.BtnMaxRec = new Rectangle();
+
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Minimize) > 0)
+ {
+ newBtnSetup = new BoxInfo()
+ {
+ BackColor = TitleOptions.Minimized.BackColor,
+ ForeColor = TitleOptions.Minimized.TextSetup.Color,
+ BorderSize = TitleOptions.Minimized.BorderSize,
+ BorderColor = TitleOptions.Minimized.BorderColor,
+ Font = TitleOptions.Minimized.TextSetup.Font,
+ Padding = TitleOptions.Minimized.Padding,
+ HAlign = TitleOptions.Minimized.TextSetup.HorizonalAlign,
+ VAlign = TitleOptions.Minimized.TextSetup.VerticalAlign,
+ Rectangle = btnRect,
+ Text = TitleOptions.Minimized.TextSetup.Text,
+ RoundedCorners = TitleOptions.Minimized.RoundedCorners,
+ RoundedRadius = TitleOptions.Minimized.RoundedRadius
+ };
+
+ this.BtnMinRec = newBtnSetup.Rectangle;
+ Global.CreateBox(g, newBtnSetup);
+ btnRect.X -= (btnRect.Width + buttonPadding + boxInfo.BorderSize);
+ newBtnSetup.Rectangle = btnRect;
+ }
+ else
+ this.BtnMinRec = new Rectangle();
+ }
+ private void SetupOptions()
+ {
+ TitleOptions.Parent.MouseMove += Form_MouseMove;
+ TitleOptions.Parent.MouseUp += Form_MouseUp;
+ TitleOptions.Parent.MouseDown += Form_MouseDown;
+ TitleOptions.Parent.Paint += Form_Paint;
+ TitleOptions.Parent.Resize += Form_Resize;
+ }
+ #endregion
+ }
+}
diff --git a/SwitchWinForms/Helper/BoxMethods.cs b/SwitchWinForms/Helper/BoxMethods.cs
new file mode 100644
index 0000000..16e06e3
--- /dev/null
+++ b/SwitchWinForms/Helper/BoxMethods.cs
@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Security.Permissions;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ public abstract class BoxMethods
+ {
+ private static SWFTitlebarOptions _titleOptions = null;
+
+ const int cursorFormEdge = 5;
+ const int WM_NCHITTEST = 0x0084;
+
+ private SWF_RESIZEABLE _resizeable = SWF_RESIZEABLE.None;
+
+
+ #region Internal Properties
+ internal static Dictionary ZIndex { get; } = new Dictionary();
+ internal static int LatestZIndex { get; set; } = 0;
+ internal Rectangle BtnCloseRec { get; set; } = new Rectangle();
+ internal Rectangle BtnMinRec { get; set; } = new Rectangle();
+ internal Rectangle BtnMaxRec { get; set; } = new Rectangle();
+ internal Point StartPoint { get; set; } = new Point(0, 0); // also for the moving
+ internal bool Drag { get; set; } = false; // determine if we should be moving the form
+ internal Exception SetLastError { get; set; }
+ #endregion
+
+ #region Public Methods
+ [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+ public bool WndProc(ref Message m)
+ {
+ bool retVal = false;
+
+ if (m.Msg == WM_NCHITTEST && IsFormResizeable())
+ {
+ int x = (int)(m.LParam.ToInt64() & 0xFFFF);
+ int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
+ Point pt = SWFTitlebar.TitleOptions.Parent.PointToClient(new Point(x, y));
+ Size clientSize = SWFTitlebar.TitleOptions.Parent.ClientSize;
+
+ if (Global.IsInBounds(SWFTitlebar.TitleOptions.Parent, pt, this.BtnCloseRec, Cursors.Hand) ||
+ Global.IsInBounds(SWFTitlebar.TitleOptions.Parent, pt, this.BtnMinRec, Cursors.Hand) ||
+ Global.IsInBounds(SWFTitlebar.TitleOptions.Parent, pt, this.BtnMaxRec, Cursors.Hand))
+ {
+ retVal = false;
+ }
+ else if (pt.X <= cursorFormEdge && pt.Y >= clientSize.Height - cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWFTitlebar.TitleOptions.Parent.IsMirrored ? SWF_HITTEST.HT_BOTTOMRIGHT : SWF_HITTEST.HT_BOTTOMLEFT);
+ retVal = true;
+ }
+ else if (pt.X >= clientSize.Width - cursorFormEdge && pt.Y >= clientSize.Height - cursorFormEdge && clientSize.Width >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWFTitlebar.TitleOptions.Parent.IsMirrored ? SWF_HITTEST.HT_BOTTOMLEFT : SWF_HITTEST.HT_BOTTOMRIGHT);
+ retVal = true;
+ }
+ else if (pt.X <= cursorFormEdge && pt.Y <= cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWFTitlebar.TitleOptions.Parent.IsMirrored ? SWF_HITTEST.HT_TOPRIGHT : SWF_HITTEST.HT_TOPLEFT);
+ retVal = true;
+ }
+ else if (pt.X >= clientSize.Width - cursorFormEdge && pt.Y <= cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWFTitlebar.TitleOptions.Parent.IsMirrored ? SWF_HITTEST.HT_TOPLEFT : SWF_HITTEST.HT_TOPRIGHT);
+ retVal = true;
+ }
+ else if (pt.Y <= cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWF_HITTEST.HT_TOP);
+ retVal = true;
+ }
+ else if (pt.Y >= clientSize.Height - cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWF_HITTEST.HT_BOTTOM);
+ retVal = true;
+ }
+ else if (pt.X <= cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWF_HITTEST.HT_LEFT);
+ retVal = true;
+ }
+ else if (pt.X >= clientSize.Width - cursorFormEdge && clientSize.Height >= cursorFormEdge)
+ {
+ m.Result = (IntPtr)(SWF_HITTEST.HT_RIGHT);
+ retVal = true;
+ }
+ else
+ {
+ //SWFTitlebar.TitleOptions.Parent.Cursor = Cursors.Default;
+ retVal = false;
+ }
+ }
+
+ return retVal;
+ }
+ public static SWFTitlebarOptions TitleOptions
+ {
+ get { return _titleOptions; }
+ set
+ {
+ _titleOptions = value;
+ if (TitleOptions.Parent != null && !string.IsNullOrWhiteSpace(TitleOptions.TextSetup?.Text))
+ TitleOptions.Parent.Text = TitleOptions.TextSetup.Text;
+ }
+ }
+ public Exception LastError { get { return SetLastError; } }
+ #endregion
+
+ #region Private/Internal Methods
+ internal bool GetZIndex(ref SWFBoxingOptions options, out int idx)
+ {
+ bool retVal = false;
+
+ lock (ZIndex)
+ {
+ if (ZIndex.TryGetValue(options.Name, out SWFBoxingOptions foundOpt))
+ {
+ idx = foundOpt.ZIndex;
+ retVal = true;
+ }
+ else
+ {
+ idx = ++LatestZIndex;
+ options.ZIndex = idx;
+ ZIndex.Add(options.Name, options);
+ }
+ }
+
+ return retVal;
+ }
+ internal bool ImOnTop(SWFBoxingOptions options)
+ {
+ bool retVal = true;
+
+ foreach (SWFBoxingOptions bopt in ZIndex.Values)
+ {
+ if (options.Name == bopt.Name)
+ continue;
+
+ if (bopt.ZIndex > options.ZIndex)
+ {
+ if (options.Rectangle.Contains(bopt.Rectangle))
+ {
+ retVal = false;
+ break;
+ }
+ }
+ }
+
+ return retVal;
+ }
+ private bool IsFormResizeable()
+ {
+ if (this._resizeable == SWF_RESIZEABLE.None)
+ {
+ if ((TitleOptions.ButtonsEnabled & SWF_TITLE_BUTTON.Maximize_Normal) > 0)
+ this._resizeable = SWF_RESIZEABLE.Yes;
+ else
+ this._resizeable = SWF_RESIZEABLE.No;
+ }
+
+ return this._resizeable == SWF_RESIZEABLE.Yes;
+ }
+ internal Cursor GetCursorByType(Form frm, Cursor defaultCursor, out bool cursorChanged)
+ {
+ Cursor retVal = frm.Cursor;
+ cursorChanged = false;
+
+ if (retVal != defaultCursor)
+ {
+ cursorChanged = true;
+ retVal = defaultCursor;
+ }
+ return retVal;
+ }
+ #endregion
+ }
+}
diff --git a/SwitchWinForms/Models/BoxInfo.cs b/SwitchWinForms/Models/BoxInfo.cs
new file mode 100644
index 0000000..096f204
--- /dev/null
+++ b/SwitchWinForms/Models/BoxInfo.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+//test
+namespace SwitchWinForms
+{
+ internal class BoxInfo
+ {
+ public int BorderSize { get; set; }
+ public Padding Padding { get; set; }
+ public Rectangle Rectangle { get; set; }
+ public SWF_BOX_TYPE Type { get; set; }
+ public int TextCursor { get; set; }
+ public string Text { get; set; }
+ public Image Icon { get; set; }
+ public Font Font { get; set; }
+ public StringAlignment VAlign { get; set; }
+ public StringAlignment HAlign { get; set; }
+ public Color BackColor { get; set; }
+ public Color BorderColor { get; set; }
+ public Color ForeColor { get; set; }
+ public Image BackgroundImage { get; set; } = null;
+ public List ReplaceImageColor { get; set; } = new List() { };
+ public ShadowingSetup Shadowing { get; set; } = new ShadowingSetup();
+ public SWF_BG_IMG_LAYOUT BackgroundImageLayout { get; set; } = SWF_BG_IMG_LAYOUT.Stretch;
+ public SWF_ARC_CORNERS RoundedCorners { get; set; } = SWF_ARC_CORNERS.None;
+ public int RoundedRadius { get; set; } = 0;
+ public bool Empty { get { return (this == new BoxInfo()); } }
+
+ internal bool ButtonClicked { get; set; } = false;
+ internal bool InputStart { get; set; } = false;
+ internal Image BackgroundImageOrg { get; set; } = null;
+ internal bool BackgroundImageModified { get; set; } = false;
+ ///
+ /// Deprecated Method.
+ ///
+ ///
+ [Obsolete("IsTextEmpty() is deprecated, please use 'Empty' property instead.")]
+ public bool IsTextEmpty()
+ {
+ return Empty;
+ }
+ }
+}
diff --git a/SwitchWinForms/Models/ReplaceColor.cs b/SwitchWinForms/Models/ReplaceColor.cs
new file mode 100644
index 0000000..bd0686b
--- /dev/null
+++ b/SwitchWinForms/Models/ReplaceColor.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Drawing;
+
+namespace SwitchWinForms
+{
+ public class ReplaceColor
+ {
+ private int _defaultImageColorTolerance = 10;
+ public ReplaceColor() { }
+ public ReplaceColor(Color delete, Color add, int clrTol = 100)
+ {
+ Delete = delete;
+ Add = add;
+ ImageColorTolerance = clrTol;
+ }
+ public Color Delete { get; set; } = Color.Empty;
+ public Color Add { get; set; } = Color.Empty;
+ public int ImageColorTolerance
+ {
+ get => this._defaultImageColorTolerance;
+ set
+ {
+ if (value > 100 || value < 0)
+ throw new Exception("Invalid image color tolerance.\nValid range: 0 - 100");
+
+ this._defaultImageColorTolerance = value;
+ }
+ }
+ public bool Empty { get { return this == new ReplaceColor(); } }
+ }
+}
diff --git a/SwitchWinForms/Models/SWFBoxingOptions.cs b/SwitchWinForms/Models/SWFBoxingOptions.cs
new file mode 100644
index 0000000..338e7d5
--- /dev/null
+++ b/SwitchWinForms/Models/SWFBoxingOptions.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ public class SWFBoxingOptions : TextUtil
+ {
+ private SWF_BOX_TYPE _type = SWF_BOX_TYPE.Frame;
+ private int _titleBarHeight = -1;
+ ///
+ /// To access the box it's easier with a name.
+ ///
+ public string Name { get; set; } = string.Empty;
+ ///
+ /// Required to be setup, as different types of objects work differently based on type.
+ ///
+ public SWF_BOX_TYPE Type
+ {
+ get { return _type; }
+ set {
+ _type = value;
+ if (_type != SWF_BOX_TYPE.FormBody)
+ _titleBarHeight = -1;
+ else if (_titleBarHeight == -1)
+ _titleBarHeight = 30; //default
+ }
+ }
+ ///
+ /// On mouse over or click, cursor changes.
+ ///
+ public SWFCursors Cursors { get; set; } = new SWFCursors();
+ ///
+ /// Parent allows zindex.
+ ///
+ public Form Parent { get; set; } = null;
+ ///
+ /// Select corners to round off. Default None.
+ ///
+ public SWF_ARC_CORNERS RoundedCorners { get; set; } = SWF_ARC_CORNERS.None;
+ ///
+ /// Arc of the corners. 0 = Square.
+ ///
+ public int RoundedRadius { get; set; } = 0;
+ ///
+ /// Pixle size of the border for all 4 sides.
+ ///
+ public int BorderSize { get; set; } = 2;
+ ///
+ /// Padding for each size. Example: new Padding(5,2,2,2)
+ ///
+ public Padding Padding { get; set; } = new Padding(0);
+ ///
+ /// Get or Set the Location of the box.
+ ///
+ public Point Location { get; set; } = new Point(0, 0);
+ ///
+ /// Get or Set the Bounderies of the box.
+ ///
+ public Size Size { get; set; } = new Size(0, 0);
+ ///
+ /// Get or Set the Location and Bounderies of the box.
+ ///
+ public Rectangle Rectangle
+ {
+ get { return new Rectangle(Location, Size); }
+ set
+ {
+ Location = value == null ? Point.Empty : value.Location;
+ Size = value == null ? Size.Empty : value.Size;
+ }
+ }
+ ///
+ /// If there is a custom titlebar and if this this box type is
+ /// a SWF_BOX_TYPE.FormBody, auto-sizing requires to know how tall the titlebar is.
+ /// This setting will be ignored if this object type is not a SWF_BOX_TYPE.FormBody.
+ ///
+ public int TitleBarHeight
+ {
+ get { return _titleBarHeight; }
+ set
+ {
+ _titleBarHeight = value;
+ }
+ }
+ ///
+ /// Text location, value, font, etc..
+ ///
+ public TextOptions TextSetup { get; set; } = new TextOptions();
+ ///
+ /// Back ground color
+ ///
+ public Color BackColor { get; set; } = SystemColors.Control;
+ ///
+ /// Border color, if exists.
+ ///
+ public Color BorderColor { get; set; } = SystemColors.ActiveCaption;
+ ///
+ /// Setup shadowing color, opacity and depth
+ ///
+ public ShadowingSetup Shadowing { get; set; } = new ShadowingSetup();
+ ///
+ /// If setup as a button, if has a shadow, when clicked, should button look like it's clicked on move down and mouse up
+ ///
+ public bool IsAnimatedButton { get; set; } = false;
+ ///
+ /// Internal tracking for mouse up and down, if animation on.
+ ///
+ internal bool ButtonClicked { get; set; } = false;
+ ///
+ /// Since everyting is painted on a form, mouse over icons and clicks need to ver reviewd based on zindex
+ ///
+ internal int ZIndex { get; set; } = 0;
+ }
+}
diff --git a/SwitchWinForms/Models/SWFCursors.cs b/SwitchWinForms/Models/SWFCursors.cs
new file mode 100644
index 0000000..2ed54b0
--- /dev/null
+++ b/SwitchWinForms/Models/SWFCursors.cs
@@ -0,0 +1,23 @@
+using System.Windows.Forms;
+
+/* CursorConverter cConverter = new CursorConverter();
+ Cursor hand = (Cursor)cConverter.ConvertFromString("Hand");
+ string hhh = this.BoxingOptions.Parent.Cursor.cu.ToString();
+ string iii =Cursor.Current.ToString();
+*/
+namespace SwitchWinForms
+{
+ public class SWFCursors
+ {
+ internal Cursor OnMove { get; set; } = Cursors.Default;
+ internal Cursor OnClick { get; set; } = Cursors.Default;
+ public SWFCursors(Cursor onMove = null, Cursor onClick = null)
+ {
+ if (onMove != null)
+ this.OnMove = onMove;
+
+ if (onClick != null)
+ this.OnClick = onClick;
+ }
+ }
+}
diff --git a/SwitchWinForms/Models/SWFMessageEventArgs.cs b/SwitchWinForms/Models/SWFMessageEventArgs.cs
new file mode 100644
index 0000000..bda0207
--- /dev/null
+++ b/SwitchWinForms/Models/SWFMessageEventArgs.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace SwitchWinForms
+{
+ public class SWFMessageEventArgs : EventArgs
+ {
+ private Exception _exception = null;
+ private string _message = string.Empty;
+
+ public SWFMessageEventArgs(Exception exception)
+ {
+ this._exception = exception;
+ this._message = exception.Message;
+ }
+
+ public SWFMessageEventArgs(string message) =>
+ this._message = message;
+
+ public Exception Exception { get { return this._exception; } }
+ public string Message { get { return this._message; } }
+ public bool Success { get { return this._exception == null; } }
+ }
+}
diff --git a/SwitchWinForms/Models/SWFTitlebarOptions.cs b/SwitchWinForms/Models/SWFTitlebarOptions.cs
new file mode 100644
index 0000000..f3bd006
--- /dev/null
+++ b/SwitchWinForms/Models/SWFTitlebarOptions.cs
@@ -0,0 +1,266 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ public class SWFTitlebarOptions : TextUtil
+ {
+ private int _borderSize = 2;
+ ///
+ /// Name of Titlebar Option
+ ///
+ public string Name { get; set; } = string.Empty;
+ ///
+ /// Parent Form
+ ///
+ internal Form GetSetParent { get; set; }
+ ///
+ /// titlebar is always location 0,0
+ ///
+ internal Point Location { get; set; } = new Point(0, 0);
+ ///
+ /// Size is updated by paint.
+ ///
+ internal Size Size { get; set; } = new Size(0, 0);
+ public Image Icon { get; set; }
+ ///
+ /// The primary form.
+ ///
+ public Form Parent { get { return GetSetParent; } }
+ ///
+ /// Get Location and Size of titlebar.
+ ///
+ public Rectangle Rectangle { get { return new Rectangle(this.Location, this.Size); } }
+ ///
+ /// Border size.
+ /// Valid alues (0-5).
+ /// Default: 2
+ ///
+ public int BorderSize
+ {
+ get { return _borderSize; }
+ set
+ {
+ if (value < 0 || value > 5)
+ throw new Exception("BorderSize must be between 0-5");
+
+ _borderSize = value;
+ }
+ }
+ ///
+ /// Rounding corners specified.
+ ///
+ ///
+ /// Default: None
+ ///
+ public SWF_ARC_CORNERS RoundedCorners { get; set; } = SWF_ARC_CORNERS.None;
+ ///
+ /// Radius of the arc for the rounded corners.
+ /// Will be ignored if RoundedCorners is set to None.
+ /// Default: 0
+ ///
+ public int RoundedRadius { get; set; } = 0;
+ ///
+ /// All text and buttons will be adjusted based on padding.
+ /// Usage: Padding(Left, Top, Right, Bottom)
+ /// Default: 0
+ ///
+ public Padding Padding { get; set; } = new Padding(0);
+ ///
+ /// Height of titlebar.
+ /// Default: 30
+ ///
+ public int Height { get; set; } = 30;
+ ///
+ /// Enable the Minimize, Maximum/Normal, and Close buttons for titlebar.
+ /// Usage: SWF_TITLE_BUTTON.Minimize | SWF_TITLE_BUTTON.Close
+ /// Default: SWF_TITLE_BUTTON.All
+ ///
+ public SWF_TITLE_BUTTON ButtonsEnabled { get; set; } = SWF_TITLE_BUTTON.All;
+ ///
+ /// Setup or use defaults for Minimized button.
+ ///
+ ///
+ /// Default:
+ /// BackColor = SystemColors.Window,
+ /// BorderColor = SystemColors.WindowFrame,
+ /// TextSetup = new TextOptions()
+ /// {
+ /// Color = SystemColors.WindowText,
+ /// Text = SWFUnicodeChars.MIN,
+ /// Font = Global.DefaultButtonFont,
+ /// HorizonalAlign = StringAlignment.Center,
+ /// VerticalAlign = StringAlignment.Center,
+ /// }
+ ///
+ public ButtonsState Minimized { get; set; } = new ButtonsState()
+ {
+ BackColor = SystemColors.Window,
+ BorderColor = SystemColors.WindowFrame,
+ TextSetup = new TextOptions()
+ {
+ Color = SystemColors.WindowText,
+ Text = SWFUnicodeChars.MIN,
+ Font = Global.DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ };
+ ///
+ /// Setup or use defaults for Maximize button.
+ ///
+ ///
+ /// Default:
+ /// BackColor = SystemColors.Window,
+ /// BorderColor = SystemColors.WindowFrame,
+ /// TextSetup = new TextOptions()
+ /// {
+ /// Color = SystemColors.WindowText,
+ /// Text = SWFUnicodeChars.MAX,
+ /// Font = Global.DefaultButtonFont,
+ /// HorizonalAlign = StringAlignment.Center,
+ /// VerticalAlign = StringAlignment.Center,
+ /// }
+ ///
+ public ButtonsState Maximize { get; set; } = new ButtonsState()
+ {
+ BackColor = SystemColors.Window,
+ BorderColor = SystemColors.WindowFrame,
+ TextSetup = new TextOptions()
+ {
+ Color = SystemColors.WindowText,
+ Text = SWFUnicodeChars.MAX,
+ Font = Global.DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ };
+ ///
+ /// Setup or use defaults for Normal button.
+ ///
+ ///
+ /// Default:
+ /// BackColor = SystemColors.Window,
+ /// BorderColor = SystemColors.WindowFrame,
+ /// TextSetup = new TextOptions()
+ /// {
+ /// Color = SystemColors.WindowText,
+ /// Text = SWFUnicodeChars.NORM,
+ /// Font = Global.DefaultButtonFont,
+ /// HorizonalAlign = StringAlignment.Center,
+ /// VerticalAlign = StringAlignment.Center,
+ /// }
+ ///
+ public ButtonsState Normal { get; set; } = new ButtonsState()
+ {
+ BackColor = SystemColors.Window,
+ BorderColor = SystemColors.WindowFrame,
+ TextSetup = new TextOptions()
+ {
+ Color = SystemColors.WindowText,
+ Text = SWFUnicodeChars.NORM,
+ Font = Global.DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ };
+ ///
+ /// Setup or use defaults for Close button.
+ ///
+ ///
+ /// Default:
+ /// BackColor = SystemColors.Window,
+ /// BorderColor = SystemColors.WindowFrame,
+ /// TextSetup = new TextOptions()
+ /// {
+ /// Color = SystemColors.WindowText,
+ /// Text = Global.GetUnicode(SWF_UNICODE_BUTTONS.CLOSE),
+ /// Font = Global.DefaultButtonFont,
+ /// HorizonalAlign = StringAlignment.Center,
+ /// VerticalAlign = StringAlignment.Center,
+ /// }
+ ///
+ public ButtonsState Close { get; set; } = new ButtonsState()
+ {
+ BackColor = SystemColors.Window,
+ BorderColor = SystemColors.WindowFrame,
+ TextSetup = new TextOptions()
+ {
+ Color = SystemColors.WindowText,
+ Text = SWFUnicodeChars.CLOSE,
+ Font = Global.DefaultButtonFont,
+ HorizonalAlign = StringAlignment.Center,
+ VerticalAlign = StringAlignment.Center,
+ }
+ };
+ ///
+ /// Titlebar caption information
+ ///
+ public TextOptions TextSetup { get; set; } = new TextOptions();
+ ///
+ /// Titlebar background color.
+ /// Default: SystemColors.GradientActiveCaption
+ ///
+ public Color BackColor { get; set; } = SystemColors.GradientActiveCaption;
+ ///
+ /// Titlebar border color.
+ /// Default: SystemColors.ActiveBorder
+ ///
+ public Color BorderColor { get; set; } = SystemColors.ActiveBorder;
+ ///
+ /// All button setup shown on the title bar. This includes, Minimum, Normal/Maximum, Close buttons.
+ ///
+ public class ButtonsState : TextUtil
+ {
+ ///
+ /// Border size around buttons.
+ /// Default: 1
+ ///
+ public int BorderSize { get; set; } = 1;
+ ///
+ /// Seperations between buttons.
+ /// Default: 2
+ ///
+ public int MarginRight { get; set; } = 2;
+ ///
+ /// Buttons border color
+ /// Default: SystemColors.ActiveBorder
+ ///
+ public Color BorderColor { get; set; } = SystemColors.ActiveBorder;
+ ///
+ /// Button Background Color
+ /// Default: SystemColors.ActiveCaption
+ ///
+ public Color BackColor { get; set; } = SystemColors.ActiveCaption;
+ ///
+ /// Button's text configuration
+ ///
+ public TextOptions TextSetup { get; set; } = new TextOptions();
+ ///
+ /// Button's padding
+ /// Default: 0
+ ///
+ public Padding Padding { get; set; } = new Padding(0);
+ ///
+ /// Which corners to be rounded for this button.
+ /// Default: None
+ ///
+ public SWF_ARC_CORNERS RoundedCorners { get; set; } = SWF_ARC_CORNERS.None;
+ ///
+ /// Radius of the arc for each corner.
+ /// Default: 0
+ /// Suggest: 2-10
+ ///
+ public int RoundedRadius { get; set; } = 0;
+ ///
+ /// Is default ButtonsState class without any settings.
+ ///
+ public bool Empty { get { return this == new ButtonsState(); } }
+ }
+ ///
+ /// Is default SWFTitlebarOptions class without any settings.
+ ///
+ public bool Empty { get { return this == new SWFTitlebarOptions(); } }
+ }
+}
diff --git a/SwitchWinForms/Models/SWFUnicodeChars.cs b/SwitchWinForms/Models/SWFUnicodeChars.cs
new file mode 100644
index 0000000..fda3a11
--- /dev/null
+++ b/SwitchWinForms/Models/SWFUnicodeChars.cs
@@ -0,0 +1,80 @@
+using System.Globalization;
+
+namespace SwitchWinForms
+{
+ ///
+ /// Unicode for special characters.
+ ///
+ public class SWFUnicodeChars
+ {
+ private const int min = 10134;
+ private const int max = 11026;
+ private const int norm = 11027;
+ private const int close = 10062; //10060-X;
+ private const int txtCursor = 10626; //10070-❖ 10626-⦂
+ private int ucode = 0;
+ ///
+ /// You can pass any unicode number and use
+ /// .ToString() to get the local string value.
+ ///
+ ///
+ public SWFUnicodeChars(int ucode) =>
+ this.ucode = ucode;
+ ///
+ /// Internal method to convert unicode to current culture string value.
+ ///
+ ///
+ ///
+ private static string MakeString(int unicode)
+ {
+ return ((char)unicode)
+ .ToString(new CultureInfo(CultureInfo.CurrentCulture.Name));
+ }
+ ///
+ /// Returns the default value for Minimum button text.
+ ///
+ public static string MIN
+ {
+ get { return MakeString(min); }
+ }
+ ///
+ /// Returns the default value for Text Cursor text.
+ ///
+ public static string TXT_CURSOR
+ {
+ get { return MakeString(txtCursor); }
+ }
+ ///
+ /// Returns the default value for Maximum button text.
+ ///
+ public static string MAX
+ {
+ get { return MakeString(max); }
+ }
+ ///
+ /// Returns the default value for Normal button text.
+ ///
+ public static string NORM
+ {
+ get { return MakeString(norm); }
+ }
+ ///
+ /// Returns the default value for Close button text.
+ ///
+ public static string CLOSE
+ {
+ get { return MakeString(close); }
+ }
+ ///
+ /// Converts the unicode value passed in to the curent culture string value.
+ ///
+ public override string ToString()
+ {
+ return MakeString(this.ucode);
+ }
+ ///
+ /// Has class been called.
+ ///
+ public bool Empty { get { return this.ucode == 0; } }
+ }
+}
diff --git a/SwitchWinForms/Models/ShadowingSetup.cs b/SwitchWinForms/Models/ShadowingSetup.cs
new file mode 100644
index 0000000..0c58ec1
--- /dev/null
+++ b/SwitchWinForms/Models/ShadowingSetup.cs
@@ -0,0 +1,14 @@
+
+using System.Drawing;
+
+namespace SwitchWinForms
+{
+ public class ShadowingSetup
+ {
+ public Color Color { get; set; } = Color.Black;
+ public SWF_TRANSPARENT_PERCENTAGE Visibilty { get; set; } = SWF_TRANSPARENT_PERCENTAGE.Empty;
+ public int Depth { get; set; } = 5;
+ internal int getVisibilty { get { return (int)Visibilty; } }
+ public bool Empty { get { return this == new ShadowingSetup(); } }
+ }
+}
diff --git a/SwitchWinForms/Models/TextUtil.cs b/SwitchWinForms/Models/TextUtil.cs
new file mode 100644
index 0000000..8da2330
--- /dev/null
+++ b/SwitchWinForms/Models/TextUtil.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ public abstract class TextUtil
+ {
+ public class TextOptions
+ {
+ internal int TextCursor { get; set; } = 0;
+ public string Text { get; set; } = string.Empty;
+ ///
+ /// Only used for SWF_BOX_TYPE.TextBox
+ ///
+ public string ValidInputExpression { get; set; } = null;
+ public Image BackgroundImage { get; set; } = null;
+ public SWF_BG_IMG_LAYOUT BackgroundImageLayout { get; set; } = SWF_BG_IMG_LAYOUT.Stretch;
+ public List ReplaceImageColor { get; set; } = new List() { };
+ public Font Font { get; set; } = Global.DefaultFont;
+ public Color Color { get; set; } = Global.DefaultFontColor;
+ public StringAlignment VerticalAlign { get; set; } = StringAlignment.Near;
+ public StringAlignment HorizonalAlign { get; set; } = StringAlignment.Near;
+ public bool Empty { get { return this == new TextOptions(); } }
+ ///
+ /// Deprecated Method
+ ///
+ ///
+ [Obsolete("IsEmpty() is deprecated, please use 'Empty' property instead.")]
+ public bool IsEmpty() {
+ return Empty;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SwitchWinForms/Properties/AssemblyInfo.cs b/SwitchWinForms/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..fe7aa53
--- /dev/null
+++ b/SwitchWinForms/Properties/AssemblyInfo.cs
@@ -0,0 +1,37 @@
+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("SwitchWinForms")]
+[assembly: AssemblyDescription("Create new forms with flare or use it for certain components.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("chizl.com")]
+[assembly: AssemblyProduct("SwitchWinForms")]
+[assembly: AssemblyCopyright("copyright (c) chizl.com 2023")]
+[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("7c49620c-5f61-4a4e-a6ca-166b18e4daa6")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("2.1.0.0")]
+[assembly: AssemblyFileVersion("2.1.0.317")]
+[assembly: AssemblyInformationalVersion("2.1.0.0")]
\ No newline at end of file
diff --git a/SwitchWinForms/Static/Constants.cs b/SwitchWinForms/Static/Constants.cs
new file mode 100644
index 0000000..24bf991
--- /dev/null
+++ b/SwitchWinForms/Static/Constants.cs
@@ -0,0 +1,97 @@
+namespace SwitchWinForms
+{
+ public enum SWF_BG_IMG_LAYOUT
+ {
+ Normal,
+ Center,
+ Stretch,
+ Tile
+ }
+ public enum SWF_BOX_TYPE
+ {
+ Empty,
+ Titlebar,
+ FormBody,
+ Button,
+ Frame,
+ Label,
+ TextBox
+ }
+ public enum SWF_ARC_CORNERS
+ {
+ None = 0,
+ TopLeft = 1,
+ TopRight = 2,
+ BottomLeft = 4,
+ BottomRight = 8,
+ Left = TopLeft | BottomLeft,
+ Right = TopRight | BottomRight,
+ Top = TopLeft | TopRight,
+ Bottom = BottomLeft | BottomRight,
+ All = TopLeft | TopRight | BottomLeft | BottomRight,
+ }
+ public enum SWF_TRANSPARENT_PERCENTAGE
+ {
+ Empty = 0,
+ Five = 13,
+ Ten = 26,
+ Fifteen = 38,
+ Twenty = 51,
+ TwentyFive = 64,
+ Thirty = 77,
+ ThirtyFive = 89,
+ Forty = 102,
+ FortyFive = 115,
+ Fifty = 127,
+ FiftyFive = 140,
+ Sixty = 153,
+ SixtyFive = 166,
+ Seventy = 179,
+ SeventyFive = 191,
+ Eighty = 204,
+ EightyFive = 217,
+ Ninty = 230,
+ NintyFive = 242,
+ Hundered = 255
+ }
+ public enum SWF_TITLE_BUTTON
+ {
+ Minimize = 1,
+ Maximize_Normal = 2,
+ Close = 4,
+ All = Minimize | Maximize_Normal | Close
+ }
+ internal enum SWF_RESIZEABLE
+ {
+ None = 0,
+ Yes = 1,
+ No = 2
+ }
+ internal enum SWF_HITTEST
+ {
+ HT_ERROR = -2,
+ HT_TRANSPARENT = -1,
+ HT_NOWHERE = 0,
+ HT_CLIENT = 1,
+ HT_CAPTION = 2,
+ HT_SYSMENU = 3,
+ HT_GROWBOX = 4,
+ HT_MENU = 5,
+ HT_HSCROLL = 6,
+ HT_VSCROLL = 7,
+ HT_MINBUTTON = 8,
+ HT_MAXBUTTON = 9,
+ HT_LEFT = 10,
+ HT_RIGHT = 11,
+ HT_TOP = 12,
+ HT_TOPLEFT = 13,
+ HT_TOPRIGHT = 14,
+ HT_BOTTOM = 15,
+ HT_BOTTOMLEFT = 16,
+ HT_BOTTOMRIGHT = 17,
+ HT_BORDER = 18,
+ HT_OBJECT = 19,
+ HT_CLOSE = 20,
+ HT_HELP = 21
+ }
+}
\ No newline at end of file
diff --git a/SwitchWinForms/Static/Global.cs b/SwitchWinForms/Static/Global.cs
new file mode 100644
index 0000000..aac1890
--- /dev/null
+++ b/SwitchWinForms/Static/Global.cs
@@ -0,0 +1,487 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace SwitchWinForms
+{
+ internal class Global
+ {
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ extern static bool DestroyIcon(IntPtr handle);
+
+ private const string DefaultTextFont = "Courier New";
+ internal static List IgnoreKeys { get; } = new List() { Keys.Right, Keys.Left, Keys.Home, Keys.End,
+ Keys.Enter, Keys.Return, Keys.Back, Keys.Delete,
+ Keys.Escape, Keys.Shift, Keys.ShiftKey, Keys.Capital,
+ Keys.Alt, Keys.Control, Keys.ControlKey,
+ Keys.CapsLock, Keys.Snapshot, Keys.Print, Keys.PrintScreen,
+ Keys.Menu, Keys.Apps, Keys.Up, Keys.Down, Keys.PageDown,
+ Keys.PageUp, Keys.VolumeDown,
+ Keys.VolumeUp, Keys.VolumeMute };
+ internal static Dictionary ConvertKey { get; } = new Dictionary()
+ {
+ { Keys.Enter, '\n' },
+ { Keys.Tab, '\t' },
+ { Keys.OemPeriod, '.' },
+ { Keys.Decimal, '.' },
+ { Keys.NumPad1, '1' },
+ { Keys.NumPad2, '2' },
+ { Keys.NumPad3, '3' },
+ { Keys.NumPad4, '4' },
+ { Keys.NumPad5, '5' },
+ { Keys.NumPad6, '6' },
+ { Keys.NumPad7, '7' },
+ { Keys.NumPad8, '8' },
+ { Keys.NumPad9, '9' },
+ { Keys.NumPad0, '0' },
+ { Keys.D1, '1' },
+ { Keys.D2, '2' },
+ { Keys.D3, '3' },
+ { Keys.D4, '4' },
+ { Keys.D5, '5' },
+ { Keys.D6, '6' },
+ { Keys.D7, '7' },
+ { Keys.D8, '8' },
+ { Keys.D9, '9' },
+ { Keys.D0, '0' },
+ };
+ internal static Font DefaultFont { get; } = new Font("Verdana", 12, FontStyle.Regular, GraphicsUnit.Pixel);
+ internal static Font DefaultButtonFont { get; } = new Font("Verdana", 12, FontStyle.Regular, GraphicsUnit.Pixel);
+ internal static Color DefaultFontColor { get; } = Color.Black;
+ internal static bool IsInBounds(Form frm, Point pt, Rectangle rect, Cursor cursorType = null)
+ {
+ bool retVal = false;
+
+ if (pt.X >= rect.Left &&
+ pt.Y >= rect.Top &&
+ pt.X <= rect.Left + rect.Width &&
+ pt.Y <= rect.Top + rect.Height)
+ {
+ if (frm != null && cursorType != null)
+ frm.Cursor = cursorType;
+
+ retVal = true;
+ }
+
+ return retVal;
+ }
+ internal static bool MouseIsClose(Point pt, Rectangle rect)
+ {
+ int count = 0;
+ int closeBy = 2;
+ bool[] hasBool = new bool[4];
+
+ hasBool[0] = pt.X < rect.X && (rect.X - pt.X <= closeBy) ? true : false;
+ hasBool[1] = pt.Y < rect.Y && (rect.Y - pt.Y <= closeBy) ? true : false;
+ hasBool[2] = pt.X > (rect.X + rect.Width) && (pt.X - (rect.X + rect.Width) <= closeBy) ? true : false;
+ hasBool[3] = pt.Y > (rect.Y + rect.Height) && (pt.Y - (rect.Y + rect.Height) <= closeBy) ? true : false;
+
+ for(int i= 0; i < 4; i++)
+ {
+ if (hasBool[i])
+ count++;
+ }
+
+ return count >= 1;
+ }
+ internal static BoxInfo CreateBox(Graphics g, BoxInfo boxInfo)
+ {
+ int buffer = 1;
+ Size maxSize = boxInfo.Rectangle.Size;
+ Rectangle innerBoxRect = boxInfo.Rectangle;
+
+ if (innerBoxRect.Width < 1 || innerBoxRect.Height < 1)
+ return boxInfo;
+
+ //create the shadow first.
+ if (boxInfo.Shadowing != null &&
+ boxInfo.Shadowing.Visibilty != SWF_TRANSPARENT_PERCENTAGE.Empty &&
+ !boxInfo.ButtonClicked)
+ {
+ Color shaColor = Color.FromArgb(
+ boxInfo.Shadowing.getVisibilty,
+ boxInfo.Shadowing.Color.R,
+ boxInfo.Shadowing.Color.G,
+ boxInfo.Shadowing.Color.B);
+
+ Brush shadowBrush = new SolidBrush(shaColor);
+
+ Rectangle shadowBox = new Rectangle(
+ boxInfo.Rectangle.X + boxInfo.Shadowing.Depth,
+ boxInfo.Rectangle.Y + boxInfo.Shadowing.Depth,
+ boxInfo.Rectangle.Width,
+ boxInfo.Rectangle.Height);
+
+ FillRoundedRectangle(g, shadowBrush, boxInfo, shadowBox, true);
+ }
+
+ //&& !boxInfo.BackgroundImageModified
+ if (boxInfo.BackgroundImage != null )
+ {
+ Image newImg = boxInfo.BackgroundImage;
+ if (boxInfo.ReplaceImageColor.Count > 0)
+ {
+ //we dont want to call MakeTransparent each roll, this
+ //will cause jumping excuted mutliple times.
+ foreach (ReplaceColor rc in boxInfo.ReplaceImageColor)
+ newImg = MakeTransparent(newImg, rc, rc.ImageColorTolerance);
+
+ boxInfo.ReplaceImageColor = new List();
+ //This makes it perminate until next restart.
+
+ boxInfo.BackgroundImage = newImg;
+ boxInfo.BackgroundImageModified = true;
+ }
+
+ if (boxInfo.BackgroundImageLayout != SWF_BG_IMG_LAYOUT.Tile &&
+ (boxInfo.BackgroundImage.Width > boxInfo.Rectangle.Width ||
+ boxInfo.BackgroundImage.Height > boxInfo.Rectangle.Height))
+ {
+ newImg = ResizeBitmap(new Bitmap(newImg), boxInfo.Rectangle.Size);
+ boxInfo.BackgroundImage = newImg;
+ boxInfo.BackgroundImageModified = true;
+ }
+ }
+
+ //create the background.
+ SolidBrush bgColor = new SolidBrush(boxInfo.BackColor);
+ FillRoundedRectangle(g, bgColor, boxInfo, boxInfo.Rectangle, false);
+
+ //if border, then draw border ontop of background.
+ if (boxInfo.BorderSize > 0)
+ {
+ for (int i = 0; i < boxInfo.BorderSize; i++)
+ {
+ Rectangle borderRect = new Rectangle()
+ {
+ Location = new Point(boxInfo.Rectangle.Location.X + i, boxInfo.Rectangle.Location.Y + i),
+ Size = new Size((maxSize.Width - (i * 2)) - buffer, (maxSize.Height - (i * 2)) - buffer)
+ };
+
+ //create the border
+ Pen titlePen = new Pen(boxInfo.BorderColor, boxInfo.BorderSize);
+ DrawRoundedRectangle(g, titlePen, boxInfo, borderRect);
+
+ innerBoxRect = borderRect;
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(boxInfo.Text))
+ {
+ StringFormat stringFormat = new StringFormat()
+ {
+ Alignment = boxInfo.HAlign,
+ LineAlignment = boxInfo.VAlign
+ };
+
+ innerBoxRect = new Rectangle(innerBoxRect.Left + boxInfo.Padding.Left,
+ innerBoxRect.Top + boxInfo.Padding.Top,
+ innerBoxRect.Width - boxInfo.Padding.Right,
+ innerBoxRect.Height - boxInfo.Padding.Bottom);
+
+ if (boxInfo.Type == SWF_BOX_TYPE.Titlebar && boxInfo.Icon != null)
+ innerBoxRect.Location = new Point((innerBoxRect.X * 2) + innerBoxRect.Height + (boxInfo.Padding.Left * 2), innerBoxRect.Y);
+ else if (boxInfo.Type == SWF_BOX_TYPE.Titlebar)
+ innerBoxRect.Location = new Point((innerBoxRect.X * 2) + (boxInfo.Padding.Left * 2), innerBoxRect.Y);
+
+ Font ft = boxInfo.Font;
+ if (boxInfo.Type == SWF_BOX_TYPE.TextBox && boxInfo.InputStart)
+ {
+ //We have to change the font to "Courier New", since I"m overlaying so I can add the * at the cursor spot.
+ //An asterisk can be a differnt size than a letter for example if not using a squared font letter.
+ ft = new Font(DefaultTextFont, boxInfo.Font.Size, boxInfo.Font.Style, GraphicsUnit.Pixel);
+ int cursor = boxInfo.TextCursor;
+ string text;
+
+ if (cursor > 0)
+ text = boxInfo.Text.Substring(0, cursor) + "*";
+ else
+ text = "*";
+
+ g.DrawString(text, ft, new SolidBrush(Color.Gray), innerBoxRect, stringFormat);
+ }
+
+ g.DrawString(boxInfo.Text, ft, new SolidBrush(boxInfo.ForeColor), innerBoxRect, stringFormat);
+ }
+
+ return boxInfo;
+ }
+ internal static bool IsValidGraphic(Graphics g)
+ {
+ bool retVal = true;
+
+ try
+ {
+ if (!g.IsClipEmpty)
+ retVal = false;
+ }
+ catch
+ {
+ retVal = false;
+ }
+
+ return retVal;
+ }
+ internal static Image GetImage(string path)
+ {
+ if (!File.Exists(path))
+ throw new IOException($"File not found.\n${path}");
+
+ Image retVal;
+ FileInfo fi = new FileInfo(path);
+ try
+ {
+ switch (fi.Extension.ToLower())
+ {
+ case ".exe":
+ case ".ico":
+ retVal = (Image)GetEXEImage(path);
+ break;
+ default:
+ retVal = Image.FromFile(path);
+ break;
+ }
+ }
+ catch
+ {
+ throw new IOException("Invalid filetype.");
+ }
+
+ return retVal;
+ }
+ internal static Icon GetIcon(string path)
+ {
+ if (!File.Exists(path))
+ throw new IOException($"File not found.\n${path}");
+
+ FileInfo fi = new FileInfo(path);
+ Icon retVal;
+ try
+ {
+ switch (fi.Extension.ToLower())
+ {
+ case ".exe":
+ case ".ico":
+ retVal = (Icon)GetEXEImage(path);
+ break;
+ default:
+ Bitmap bmp = (Bitmap)Image.FromFile(path);
+ if (bmp.Width > 128 || bmp.Height > 128) //max icon size: 128x128 .ico
+ bmp = ResizeBitmap(bmp, new Size(128, 128));
+ IntPtr Hicon = bmp.GetHicon();
+ retVal = (Icon)Icon.FromHandle(Hicon).Clone();
+ //Required cleanup or creates memory leak.
+ DestroyIcon(Hicon);
+ break;
+ }
+ }
+ catch
+ {
+ throw new IOException("Invalid filetype.");
+ }
+
+ return retVal;
+ }
+ private static Bitmap ResizeBitmap(Bitmap img, Size sz)
+ {
+ float width = sz.Width;
+ float height = sz.Height;
+ var brush = new SolidBrush(Color.Transparent);
+ float scale = Math.Min(width / ((float)img.Width), height / ((float)img.Height));
+ var bmp = new Bitmap(sz.Width, sz.Height);
+ var graph = Graphics.FromImage(bmp);
+ var scaleWidth = (int)(img.Width * scale);
+ var scaleHeight = (int)(img.Height * scale);
+ RectangleF rec = new RectangleF(((int)width - scaleWidth) / 2, ((int)height - scaleHeight) / 2, scaleWidth, scaleHeight);
+ graph.FillRectangle(brush, rec);
+ graph.DrawImage(img, rec);
+
+ return bmp;
+ }
+ internal static void DrawRoundedRectangle(Graphics graphics, Pen pen, BoxInfo boxInfo, Rectangle bounds)
+ {
+ if (graphics == null)
+ throw new ArgumentNullException("graphics");
+ if (pen == null)
+ throw new ArgumentNullException("pen");
+
+ using (GraphicsPath path = RoundedRect(bounds, boxInfo))
+ {
+ graphics.DrawPath(pen, path);
+ }
+ }
+ internal static void FillRoundedRectangle(Graphics graphics, Brush brush, BoxInfo boxInfo, Rectangle bounds, bool isShadow = false)
+ {
+ if (graphics == null)
+ throw new ArgumentNullException("graphics");
+ if (brush == null)
+ throw new ArgumentNullException("brush");
+
+ using (GraphicsPath path = RoundedRect(bounds, boxInfo))
+ {
+ graphics.FillPath(brush, path);
+ if (boxInfo.BackgroundImage != null && !isShadow)
+ {
+ if (boxInfo.BackgroundImageLayout == SWF_BG_IMG_LAYOUT.Normal)
+ graphics.DrawImage(boxInfo.BackgroundImage, bounds.Location);
+ //if (boxInfo.BackgroundImageLayout == SWF_BG_IMG_LAYOUT.Tile)
+ else
+ {
+ Brush gbrush = new TextureBrush(boxInfo.BackgroundImage);
+ graphics.FillPath(gbrush, path);
+ }
+ /*else if (boxInfo.BackgroundImageLayout == SWF_BG_IMG_LAYOUT.Stretch)
+ {
+ graphics.DrawImage(boxInfo.BackgroundImage, bounds.Location);
+ }
+ else if (boxInfo.BackgroundImageLayout == SWF_BG_IMG_LAYOUT.Center)
+ {
+ graphics.DrawImage(boxInfo.BackgroundImage, bounds.Location);
+ }*/
+ }
+ }
+ }
+ internal static GraphicsPath PointsToGraphicsPath(List points)
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(points.ToArray());
+ return gp;
+ }
+ internal static List GraphicsPathToPoints(GraphicsPath gp)
+ {
+ return gp.PathPoints.ToList();
+ }
+ internal static bool DeleteFile(string path)
+ {
+ bool retVal = true;
+
+ try
+ {
+ if (File.Exists(path))
+ File.Delete(path);
+ }
+ catch
+ {
+ retVal = false;
+ }
+
+ return retVal;
+ }
+ private static GraphicsPath RoundedRect(Rectangle bounds, BoxInfo boxInfo)
+ {
+ int radiusTopLeft = 0;
+ int radiusTopRight = 0;
+ int radiusBottomRight = 0;
+ int radiusBottomLeft = 0;
+
+ if ((boxInfo.RoundedCorners & SWF_ARC_CORNERS.TopLeft) > 0)
+ radiusTopLeft = boxInfo.RoundedRadius;
+ if ((boxInfo.RoundedCorners & SWF_ARC_CORNERS.TopRight) > 0)
+ radiusTopRight = boxInfo.RoundedRadius;
+ if ((boxInfo.RoundedCorners & SWF_ARC_CORNERS.BottomRight) > 0)
+ radiusBottomRight = boxInfo.RoundedRadius;
+ if ((boxInfo.RoundedCorners & SWF_ARC_CORNERS.BottomLeft) > 0)
+ radiusBottomLeft = boxInfo.RoundedRadius;
+
+ var size = new Size(radiusTopLeft << 1, radiusTopLeft << 1);
+ var arc = new Rectangle(bounds.Location, size);
+ var path = new GraphicsPath();
+
+ // top left arc
+ if (radiusTopLeft == 0)
+ path.AddLine(arc.Location, arc.Location);
+ else
+ path.AddArc(arc, 180, 90);
+
+ // top right arc
+ if (radiusTopRight != radiusTopLeft)
+ {
+ size = new Size(radiusTopRight << 1, radiusTopRight << 1);
+ arc.Size = size;
+ }
+
+ arc.X = bounds.Right - size.Width;
+ if (radiusTopRight == 0)
+ path.AddLine(arc.Location, arc.Location);
+ else
+ path.AddArc(arc, 270, 90);
+
+ // bottom right arc
+ if (radiusTopRight != radiusBottomRight)
+ {
+ size = new Size(radiusBottomRight << 1, radiusBottomRight << 1);
+ arc.X = bounds.Right - size.Width;
+ arc.Size = size;
+ }
+
+ arc.Y = bounds.Bottom - size.Height;
+ if (radiusBottomRight == 0)
+ path.AddLine(arc.Location, arc.Location);
+ else
+ path.AddArc(arc, 0, 90);
+
+ // bottom left arc
+ if (radiusBottomRight != radiusBottomLeft)
+ {
+ arc.Size = new Size(radiusBottomLeft << 1, radiusBottomLeft << 1);
+ arc.Y = bounds.Bottom - arc.Height;
+ }
+
+ arc.X = bounds.Left;
+ if (radiusBottomLeft == 0)
+ path.AddLine(arc.Location, arc.Location);
+ else
+ path.AddArc(arc, 90, 90);
+
+ path.CloseFigure();
+ return path;
+ }
+ private static object GetEXEImage(string path)
+ {
+ object retVal;
+ string typeofName = typeof(T).Name.ToLower();
+ try
+ {
+ Icon IEIcon = Icon.ExtractAssociatedIcon(path);
+ if (typeofName == "icon")
+ retVal = (object)IEIcon;
+ else
+ retVal = IEIcon.ToBitmap();
+ }
+ catch
+ {
+ retVal = null;
+ }
+
+ return retVal;
+ }
+ private static Image MakeTransparent(Image image, ReplaceColor color, int tolerance)
+ {
+ return MakeTransparent(new Bitmap(image), color, tolerance);
+ }
+ private static Bitmap MakeTransparent(Bitmap bitmap, ReplaceColor color, int tolerance)
+ {
+ Bitmap transparentImage = new Bitmap(bitmap);
+
+ for (int i = transparentImage.Size.Width - 1; i >= 0; i--)
+ {
+ for (int j = transparentImage.Size.Height - 1; j >= 0; j--)
+ {
+ var currentColor = transparentImage.GetPixel(i, j);
+ if (Math.Abs(color.Delete.R - currentColor.R) < tolerance &&
+ Math.Abs(color.Delete.G - currentColor.G) < tolerance &&
+ Math.Abs(color.Delete.B - currentColor.B) < tolerance)
+ transparentImage.SetPixel(i, j, color.Add);
+ }
+ }
+
+ //transparentImage.MakeTransparent(color.Delete);
+ return transparentImage;
+ }
+ }
+}
diff --git a/SwitchWinForms/SwitchWinForms.csproj b/SwitchWinForms/SwitchWinForms.csproj
new file mode 100644
index 0000000..ba6a0c2
--- /dev/null
+++ b/SwitchWinForms/SwitchWinForms.csproj
@@ -0,0 +1,68 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {7C49620C-5F61-4A4E-A6CA-166B18E4DAA6}
+ Library
+ Properties
+ SwitchWinForms
+ SwitchWinForms
+ v4.7.2
+ 512
+ true
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\Code\~VBS\setVersion.vbs "$(ProjectDir)"
+
+
\ No newline at end of file