diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e0dfc29 --- /dev/null +++ b/.gitignore @@ -0,0 +1,227 @@ +# The following command works for downloading when using Git for Windows: +# curl -LOf http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore +# +# Download this file using PowerShell v3 under Windows with the following comand: +# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore +# +# or wget: +# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ +# build folder is nowadays used for build scripts and should not be ignored +#build/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings +modulesbin/ +tempbin/ + +# EPiServer Site file (VPP) +AppData/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# vim +*.txt~ +*.swp +*.swo + +# Temp files when opening LibreOffice on ubuntu +.~lock.* + +# svn +.svn + +# CVS - Source Control +**/CVS/ + +# Remainings from resolving conflicts in Source Control +*.orig + +# SQL Server files +**/App_Data/*.mdf +**/App_Data/*.ldf +**/App_Data/*.sdf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# OS generated files # +Icon? + +# Mac desktop service store files +.DS_Store + +# SASS Compiler cache +.sass-cache + +# Visual Studio 2014 CTP +**/*.sln.ide + +# Visual Studio temp something +.vs/ + +# dotnet stuff +project.lock.json + +# VS 2015+ +*.vc.vc.opendb +*.vc.db + +# Rider +.idea/ + +# Visual Studio Code +.vscode/ + +# Output folder used by Webpack or other FE stuff +**/node_modules/* +**/wwwroot/* + +# SpecFlow specific +*.feature.cs +*.feature.xlsx.* +*.Specs_*.html + +# UWP Projects +AppPackages/ + +##### +# End of core ignore list, below put you custom 'per project' settings (patterns or path) +##### + diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..e0dfc29 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,227 @@ +# The following command works for downloading when using Git for Windows: +# curl -LOf http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore +# +# Download this file using PowerShell v3 under Windows with the following comand: +# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore +# +# or wget: +# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ +# build folder is nowadays used for build scripts and should not be ignored +#build/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings +modulesbin/ +tempbin/ + +# EPiServer Site file (VPP) +AppData/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# vim +*.txt~ +*.swp +*.swo + +# Temp files when opening LibreOffice on ubuntu +.~lock.* + +# svn +.svn + +# CVS - Source Control +**/CVS/ + +# Remainings from resolving conflicts in Source Control +*.orig + +# SQL Server files +**/App_Data/*.mdf +**/App_Data/*.ldf +**/App_Data/*.sdf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# OS generated files # +Icon? + +# Mac desktop service store files +.DS_Store + +# SASS Compiler cache +.sass-cache + +# Visual Studio 2014 CTP +**/*.sln.ide + +# Visual Studio temp something +.vs/ + +# dotnet stuff +project.lock.json + +# VS 2015+ +*.vc.vc.opendb +*.vc.db + +# Rider +.idea/ + +# Visual Studio Code +.vscode/ + +# Output folder used by Webpack or other FE stuff +**/node_modules/* +**/wwwroot/* + +# SpecFlow specific +*.feature.cs +*.feature.xlsx.* +*.Specs_*.html + +# UWP Projects +AppPackages/ + +##### +# End of core ignore list, below put you custom 'per project' settings (patterns or path) +##### + diff --git a/src/App.config b/src/App.config new file mode 100755 index 0000000..5754728 --- /dev/null +++ b/src/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Form1.Designer.cs b/src/Form1.Designer.cs new file mode 100755 index 0000000..7786925 --- /dev/null +++ b/src/Form1.Designer.cs @@ -0,0 +1,139 @@ +namespace WidgetEmbed +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 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.textBox1 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.SaveEmbedsCheckbox = new System.Windows.Forms.CheckBox(); + this.SaveButton = new System.Windows.Forms.Button(); + this.BoundsDetectionCheckbox = new System.Windows.Forms.CheckBox(); + this.CheckBoundsButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.BackColor = System.Drawing.SystemColors.Menu; + this.textBox1.Location = new System.Drawing.Point(197, 112); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(362, 143); + this.textBox1.TabIndex = 1; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(591, 166); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(84, 44); + this.button1.TabIndex = 2; + this.button1.Text = "Create Embed"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(565, 112); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(129, 21); + this.comboBox1.TabIndex = 3; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // SaveEmbedsCheckbox + // + this.SaveEmbedsCheckbox.AutoSize = true; + this.SaveEmbedsCheckbox.Location = new System.Drawing.Point(1, 23); + this.SaveEmbedsCheckbox.Name = "SaveEmbedsCheckbox"; + this.SaveEmbedsCheckbox.Size = new System.Drawing.Size(138, 17); + this.SaveEmbedsCheckbox.TabIndex = 4; + this.SaveEmbedsCheckbox.Text = "Save Embeds On Close"; + this.SaveEmbedsCheckbox.UseVisualStyleBackColor = true; + // + // SaveButton + // + this.SaveButton.Location = new System.Drawing.Point(708, 1); + this.SaveButton.Name = "SaveButton"; + this.SaveButton.Size = new System.Drawing.Size(91, 26); + this.SaveButton.TabIndex = 5; + this.SaveButton.Text = "Save Now"; + this.SaveButton.UseVisualStyleBackColor = true; + this.SaveButton.Click += new System.EventHandler(this.button2_Click); + // + // BoundsDetectionCheckbox + // + this.BoundsDetectionCheckbox.AutoSize = true; + this.BoundsDetectionCheckbox.Location = new System.Drawing.Point(1, 1); + this.BoundsDetectionCheckbox.Name = "BoundsDetectionCheckbox"; + this.BoundsDetectionCheckbox.Size = new System.Drawing.Size(138, 17); + this.BoundsDetectionCheckbox.TabIndex = 6; + this.BoundsDetectionCheckbox.Text = "Check Bounds On Start"; + this.BoundsDetectionCheckbox.UseVisualStyleBackColor = true; + // + // CheckBoundsButton + // + this.CheckBoundsButton.Location = new System.Drawing.Point(708, 33); + this.CheckBoundsButton.Name = "CheckBoundsButton"; + this.CheckBoundsButton.Size = new System.Drawing.Size(91, 26); + this.CheckBoundsButton.TabIndex = 7; + this.CheckBoundsButton.Text = "Check Bounds"; + this.CheckBoundsButton.UseVisualStyleBackColor = true; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.ButtonHighlight; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.CheckBoundsButton); + this.Controls.Add(this.BoundsDetectionCheckbox); + this.Controls.Add(this.SaveButton); + this.Controls.Add(this.SaveEmbedsCheckbox); + this.Controls.Add(this.comboBox1); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "Form1"; + this.Text = "WidgetEmbed"; + this.Load += new System.EventHandler(this.Form1_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.CheckBox SaveEmbedsCheckbox; + private System.Windows.Forms.Button SaveButton; + private System.Windows.Forms.CheckBox BoundsDetectionCheckbox; + private System.Windows.Forms.Button CheckBoundsButton; + } +} + diff --git a/src/Form1.cs b/src/Form1.cs new file mode 100755 index 0000000..0db9f9e --- /dev/null +++ b/src/Form1.cs @@ -0,0 +1,497 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml.Serialization; + +namespace WidgetEmbed +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + + public static List WidgetWindows = new List(); + public static List Widgets = new List(); + public static bool BeginningShutdown = false; + + string directoryLocation = Environment.ExpandEnvironmentVariables(@"%Public%\Documents\WidgetEmbed\"); + string widgetFileName = "SavedWidgets.wgt"; + + bool widgetsVisible = true; + bool isAnimatingWidgets; + bool isAnimatingForm; + bool formVisible = true; + + + public ContextMenuStrip contextMenu1 = new ContextMenuStrip(); + public ToolStripMenuItem MenuItem1 = new ToolStripMenuItem("HideWidgets"); + public ToolStripMenuItem MenuItem2 = new ToolStripMenuItem("HideAddWidgetsMenu"); + public ToolStripMenuItem MenuItem3 = new ToolStripMenuItem("CloseApplication"); + NotifyIcon ni = new NotifyIcon(); + + public static bool ScreenBoundsDetection = true; + + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_QUERYENDSESSION || m.Msg == WM_ENDSESSION) + { + BeginningShutdown = true; + ShuttingDown(); + } + base.WndProc(ref m); + + } + + private void Form1_Load(object sender, EventArgs e) + { + SystemEvents.SessionEnding += (s, eargs) => + { + ShuttingDown(); + eargs.Cancel = true; + }; + + InputBox.Instance = new InputBox(); + + this.MaximizeBox = false; + this.MinimizeBox = false; + + this.Visible = false; + this.Opacity = 0; + + this.Location = new Point((Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height) / 2); + + + button1.Enabled = false; + + comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; + comboBox1.Items.Add("Website URL"); + comboBox1.Items.Add("HTML Embed Widget"); + + ni.Visible = true; + ni.Icon = SystemIcons.Application; + ni.Text = "WidgetEmbed (Visible)"; + ni.ContextMenuStrip = contextMenu1; + + contextMenu1.Items.Add(MenuItem1); + contextMenu1.Items.Add(MenuItem2); + contextMenu1.Items.Add(MenuItem3); + + MenuItem1.Text = "Hide Widgets"; + MenuItem2.Text = "Hide Add Widgets Menu"; + MenuItem3.Text = "Exit Application"; + + MenuItem1.Image = SystemIcons.Application.ToBitmap(); + MenuItem2.Image = SystemIcons.Question.ToBitmap(); + MenuItem3.Image = SystemIcons.Error.ToBitmap(); + + MenuItem1.Click += (s, eargs) => + { + ChangeWidgetVisibility(); + }; + + MenuItem2.Click += (s, eargs) => + { + if (isAnimatingForm) + return; + + formVisible = (this.Opacity == 1 ? true : false); + + MenuItem2.Text = (formVisible ? "Show" : "Hide") + " Add Widgets Menu"; + + Fade(this, (formVisible ? "FadeOut" : "FadeIn"), 10); + }; + + MenuItem3.Click += (s, eargs) => + { + TryClose(); + }; + + this.FormClosing += (s, fcea) => + { + if (!BeginningShutdown) + { + fcea.Cancel = TryClose(); + } + else + { + ShuttingDown(); + fcea.Cancel = true; + } + }; + + ni.MouseDoubleClick += (s, mea) => + { + ChangeWidgetVisibility(); + }; + + CheckBoundsButton.Click += (s, eargs) => + { + CheckBounds(); + }; + + + //Serialiation + if (!Directory.Exists(directoryLocation)) + { + Directory.CreateDirectory(directoryLocation); + } + + if (!File.Exists(directoryLocation + widgetFileName)) + { + File.Create(directoryLocation + widgetFileName).Close(); + } + else if (new FileInfo(directoryLocation + widgetFileName).Length == 0) + { + //file exists, but is empty! + } + else + { + LoadWidgets(); + } + + this.Visible = true; + this.Opacity = 1; + } + + const int WM_QUERYENDSESSION = 0x0011; + const int WM_ENDSESSION = 0x0016; + + + public void ShuttingDown() + { + if (SaveEmbedsCheckbox.Checked) + { + SaveWidgets(); + } + + for (int i = 0; i < WidgetWindows.Count; i++) + { + WidgetWindows[i].Close(); + } + + + Environment.Exit(0); + } + + + + + public bool TryClose() + { + + DialogResult dr = MessageBox.Show(new Form { TopMost = true }, "Are you sure you want to exit?", "Program Exiting Prompt", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + if (dr == DialogResult.Yes) + { + if (SaveEmbedsCheckbox.Checked) + SaveWidgets(); + + + ni.Visible = false; + ni.Icon = null; + + Environment.Exit(0); + } + return true; + } + + public void CheckBounds() + { + for (int i = 0; i < WidgetWindows.Count; i++) + { + if (!IsOnScreen(WidgetWindows[i])) + if (MessageBox.Show(new Form { TopMost = true }, "Widget: \"" + Widgets[i].WidgetTitle + "\" was not detected within the safe bounds area.\nWould you like to relocate it to the center of the main screen?", "Safe Bounds Detection", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + WidgetWindows[i].Location = new Point((Screen.PrimaryScreen.WorkingArea.Width - WidgetWindows[i].Size.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - WidgetWindows[i].Size.Height) / 2); + } + } + + MessageBox.Show(new Form { TopMost = true }, "Bound Check Complete!", "Safe Bounds Detection", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + public void ChangeWidgetVisibility() + { + if (isAnimatingWidgets) + return; + + widgetsVisible = !widgetsVisible; + + ni.Text = "WidgetEmbed " + (widgetsVisible ? "(Visible)" : "(Hidden)"); + MenuItem1.Text = (widgetsVisible ? "Hide" : "Show") + " Widgets"; + + if (widgetsVisible) + { + for (int i = 0; i < WidgetWindows.Count; i++) + { + Fade(WidgetWindows[i], "FadeIn", 10); + + } + } + else + { + for (int i = 0; i < WidgetWindows.Count; i++) + { + //WidgetWindows[i].Enabled = false; + Fade(WidgetWindows[i], "FadeOut", 10); + + } + } + } + + SerializedWidgetData sd; + + + + + + public static bool IsOnScreen(Form form) + { + Screen[] screens = Screen.AllScreens; + foreach (Screen screen in screens) + { + Rectangle formRectangle = new Rectangle(form.Left, form.Top, 60, 60); + + if (screen.WorkingArea.Contains(formRectangle)) + { + return true; + } + } + + return false; + } + + + + + + + private async void Fade(Form o, string FadeType, int interval = 80) + { + bool AnimatingForm = (o == this); + + if (AnimatingForm) + isAnimatingForm = true; + else + isAnimatingWidgets = true; + + if (FadeType == "FadeIn") + { + if (AnimatingForm) + { + + this.ShowInTaskbar = true; + this.Visible = true; + } + + //Object is not fully invisible. Fade it in + while (o.Opacity < 1.0) + { + await Task.Delay(interval); + o.Opacity += 0.05; + } + o.Opacity = 1; //make fully visible + + if (AnimatingForm) + isAnimatingForm = false; + else + isAnimatingWidgets = false; + } + else if (FadeType == "FadeOut") + { + //Object is fully visible. Fade it out + while (o.Opacity > 0.0) + { + await Task.Delay(interval); + o.Opacity -= 0.05; + } + o.Opacity = 0; //make fully invisible + + if (AnimatingForm) + { + isAnimatingForm = false; + { + this.ShowInTaskbar = false; + this.Visible = false; + } + } + else + isAnimatingWidgets = false; + } + } + + + public async void SaveWidgets() + { + if (sd == null) + sd = new SerializedWidgetData(); + + sd.SaveOnClose = SaveEmbedsCheckbox.Checked; + sd.PrimaryScreenDetection = BoundsDetectionCheckbox.Checked; + + if (isAnimatingForm) + { + double check1 = this.Opacity; + await Task.Delay(1000); + double check2 = this.Opacity; + + sd.WidgetMenuShown = check1 < check2 ? true : false; + } + else + { + sd.WidgetMenuShown = this.Opacity == 1 ? true : false; + } + + sd.Widgets = Widgets; + + SerializeXml(sd, directoryLocation + widgetFileName); + } + + public void LoadWidgets() + { + sd = DeserializeXml(directoryLocation + widgetFileName); + + if (sd == null) + return; + + SaveEmbedsCheckbox.Checked = sd.SaveOnClose; + BoundsDetectionCheckbox.Checked = sd.PrimaryScreenDetection; + + if (sd.WidgetMenuShown) + { + this.Visible = true; + this.Opacity = 1; + } + else + { + this.Opacity = 0; + this.ShowInTaskbar = false; + formVisible = false; + MenuItem2.Text = "Show Add Widgets Menu"; + } + + + for (int i = 0; i < sd.Widgets.Count; i++) + { + Form f2 = new Form2(sd.Widgets[i].WidgetWebData, sd.Widgets[i].WidgetLoadType, sd.Widgets[i].WidgetWindowSize, sd.Widgets[i].WidgetLocation, sd.Widgets[i].WidgetZoomScale, sd.Widgets[i].WidgetTitle); + f2.Show(); + + SetWindowPos(f2.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); + } + + if (BoundsDetectionCheckbox.Checked) + { + this.Shown += (s, eargs) => + { + CheckBounds(); + }; + + } + } + + public T SerializeXml(T objToSerialize, string outputFile) + { + try + { + + XmlSerializer s = new XmlSerializer(typeof(SerializedWidgetData)); + + using (TextWriter tw = new StreamWriter(outputFile)) + { + s.Serialize(tw, objToSerialize); + tw.Close(); + } + + } + catch (Exception ex) + { + MessageBox.Show(new Form { TopMost = true }, "Error while saving data!\nError:" + ex.Message, "Error Has Occurred", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + return default(T); + } + + public T DeserializeXml(string inputFile) + { + try + { + + XmlSerializer s = new XmlSerializer(typeof(T)); + T deserializedObject = default(T); + + using (TextReader tr = new StreamReader(inputFile)) + { + deserializedObject = (T)s.Deserialize(tr); + tr.Close(); + } + + return deserializedObject; + } + catch (Exception ex) + { + MessageBox.Show(new Form { TopMost = true }, "Save file corrupted!\nGenerating New File\nError:" + ex.Message, "Error Has Occured", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + return default(T); + } + + + + private void button1_Click(object sender, EventArgs e) + { + Form2 f2 = new Form2(textBox1.Text, (Form2.LoadType)comboBox1.SelectedIndex); + f2.Show(); + + SetWindowPos(f2.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); + + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + if (comboBox1.SelectedIndex > -1) + button1.Enabled = true; + } + + private void button2_Click(object sender, EventArgs e) + { + SaveWidgets(); + } + + public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + public const UInt32 SWP_NOSIZE = 0x0001; + public const UInt32 SWP_NOMOVE = 0x0002; + public const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE; + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); + const int SW_MAXIMIZE = 3; + const int SW_MINIMIZE = 6; + const int SW_SHOW = 5; + const int SW_HIDE = 0; + const int SW_SHOWNORMAL = 1; + const int SW_RESTORE = 9; + } + + + + public class SerializedWidgetData + { + public List Widgets = new List(); + public bool SaveOnClose; + public bool WidgetMenuShown; + public bool PrimaryScreenDetection; + } +} diff --git a/src/Form1.resx b/src/Form1.resx new file mode 100755 index 0000000..29dcb1b --- /dev/null +++ b/src/Form1.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/src/Form2.Designer.cs b/src/Form2.Designer.cs new file mode 100755 index 0000000..604889d --- /dev/null +++ b/src/Form2.Designer.cs @@ -0,0 +1,143 @@ +namespace WidgetEmbed +{ + + partial class Form2 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 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.Exit = new System.Windows.Forms.Button(); + this.Reload = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.ZoomOut = new System.Windows.Forms.Button(); + this.ZoomIn = new System.Windows.Forms.Button(); + this.WindowTitle = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // Exit + // + this.Exit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Exit.ForeColor = System.Drawing.Color.White; + this.Exit.Location = new System.Drawing.Point(780, 0); + this.Exit.Name = "Exit"; + this.Exit.Size = new System.Drawing.Size(25, 25); + this.Exit.TabIndex = 1; + this.Exit.TabStop = false; + this.Exit.Text = "X"; + this.Exit.UseVisualStyleBackColor = true; + this.Exit.Click += new System.EventHandler(this.Exit_Click); + // + // Reload + // + this.Reload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Reload.ForeColor = System.Drawing.Color.White; + this.Reload.Location = new System.Drawing.Point(756, 0); + this.Reload.Name = "Reload"; + this.Reload.Size = new System.Drawing.Size(25, 25); + this.Reload.TabIndex = 2; + this.Reload.TabStop = false; + this.Reload.Text = "↻"; + this.Reload.UseVisualStyleBackColor = true; + this.Reload.Click += new System.EventHandler(this.Reload_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = System.Drawing.SystemColors.ActiveCaption; + this.panel1.Location = new System.Drawing.Point(12, 29); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(782, 473); + this.panel1.TabIndex = 3; + // + // ZoomOut + // + this.ZoomOut.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.ZoomOut.ForeColor = System.Drawing.Color.White; + this.ZoomOut.Location = new System.Drawing.Point(708, 0); + this.ZoomOut.Name = "ZoomOut"; + this.ZoomOut.Size = new System.Drawing.Size(25, 25); + this.ZoomOut.TabIndex = 5; + this.ZoomOut.TabStop = false; + this.ZoomOut.Text = "-"; + this.ZoomOut.UseVisualStyleBackColor = true; + this.ZoomOut.Click += new System.EventHandler(this.ZoomOut_Click); + // + // ZoomIn + // + this.ZoomIn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.ZoomIn.ForeColor = System.Drawing.Color.White; + this.ZoomIn.Location = new System.Drawing.Point(732, 0); + this.ZoomIn.Name = "ZoomIn"; + this.ZoomIn.Size = new System.Drawing.Size(25, 25); + this.ZoomIn.TabIndex = 4; + this.ZoomIn.TabStop = false; + this.ZoomIn.Text = "+"; + this.ZoomIn.UseVisualStyleBackColor = true; + this.ZoomIn.Click += new System.EventHandler(this.ZoomIn_Click); + // + // WindowTitle + // + this.WindowTitle.AutoSize = true; + this.WindowTitle.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.WindowTitle.ForeColor = System.Drawing.Color.White; + this.WindowTitle.Location = new System.Drawing.Point(12, 6); + this.WindowTitle.Name = "WindowTitle"; + this.WindowTitle.Size = new System.Drawing.Size(94, 19); + this.WindowTitle.TabIndex = 6; + this.WindowTitle.Text = "Default title"; + this.WindowTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // Form2 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.ControlText; + this.ClientSize = new System.Drawing.Size(806, 514); + this.Controls.Add(this.ZoomOut); + this.Controls.Add(this.ZoomIn); + this.Controls.Add(this.panel1); + this.Controls.Add(this.Reload); + this.Controls.Add(this.Exit); + this.Controls.Add(this.WindowTitle); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "Form2"; + this.Load += new System.EventHandler(this.Form2_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Button Exit; + private System.Windows.Forms.Button Reload; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button ZoomOut; + private System.Windows.Forms.Button ZoomIn; + private System.Windows.Forms.Label WindowTitle; + } +} \ No newline at end of file diff --git a/src/Form2.cs b/src/Form2.cs new file mode 100755 index 0000000..d1229fc --- /dev/null +++ b/src/Form2.cs @@ -0,0 +1,842 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using CefSharp; +using CefSharp.Handler; +using CefSharp.WinForms; +using Microsoft.VisualBasic; + +namespace WidgetEmbed +{ + public partial class Form2 : Form + { + ReSize resize = new ReSize(); + + //public static Form2 f2Instance; + + public ChromiumWebBrowser browser; + + string defaultTitle = "Title (Middle Click)"; + public Form2(string websiteData, LoadType loadType) + { + //f2Instance = this; + + widget.WidgetWebData = websiteData; + widget.WidgetLoadType = loadType; + + InitializeComponent(); + //this.SetStyle(ControlStyles.ResizeRedraw, true); + InitBrowser(); + //CefSharpSettings.SubprocessExitIfParentProcessClosed = true; //look into this + + this.Load += (s, eargs) => + { + widget.WidgetLocation = new Point((Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height) / 2); + + SetWidgetTitle(defaultTitle); + }; + + + //this.HandleCreated += (s, eargs) => { widget.Title = defaultTitle; }; + + + + + //this.FormBorderStyle = FormBorderStyle.None; // no borders + //this.DoubleBuffered = true; + //this.SetStyle(ControlStyles.ResizeRedraw, true); // this is to avoid visual artifacts + } + + public Form2(string websiteData, LoadType loadType, Size widgetSize, Point widgetLocation, double zoomScale, string widgetTitle) + { + //f2Instance = this; + + widget.WidgetWebData = websiteData; + widget.WidgetLoadType = loadType; + widget.WidgetWindowSize = widgetSize; + widget.WidgetLocation = widgetLocation; + widget.WidgetZoomScale = zoomScale; + + InitializeComponent(); + InitBrowser(); + + SetWidgetTitle(widgetTitle); + + //this.HandleCreated += (s, eargs) => + //{ + + // if (!(widgetTitle.Length == 0)) + // widget.Title = widgetTitle; + // else + // widget.Title = defaultTitle; + //}; + + + + } + + public enum LoadType + { + WebsiteURL, + HTMLEmbed + } + + + public static bool cefInit = false; + public static bool ignoreLinkLoadingStateChanged; + + public Widget widget = new Widget(); + + bool waitingToSetZoom = true; + + public void InitBrowser() + { + if (!cefInit) + { + Cef.Initialize(new CefSettings()); + cefInit = true; + } + + browser = new ChromiumWebBrowser(); + browser.RequestHandler = new BrowserRequestHandler(); + browser.LifeSpanHandler = new BrowserLifeSpanHandler(); + + + browser.IsBrowserInitializedChanged += (s, e) => + { + if (!browser.IsBrowserInitialized) + return; + + + if (widget.WidgetLoadType == LoadType.HTMLEmbed) + browser.LoadHtml(widget.WidgetWebData, false); + else if (widget.WidgetLoadType == LoadType.WebsiteURL) + browser.Load(widget.WidgetWebData); + + //this.WindowState = FormWindowState.Normal; + //this.StartPosition = FormStartPosition.Manual; + //if (!(widget.WidgetLocation == default)) //(interferes at 0,0 + + //if (Form1.ScreenBoundsDetection) + //{ + // if (!((widget.WidgetLocation.X < 0 || widget.WidgetLocation.Y < 0) /*|| (widget.WidgetLocation.X > Form1.PrimaryScreen.Bounds.X - 25 || widget.WidgetLocation.Y > Form1.PrimaryScreen.Bounds.Y - 25)*/)) + // this.Invoke(new Action(() => this.Location = widget.WidgetLocation)); + // else + // { + // widget.WidgetLocation.X = widget.WidgetLocation.X < 0 ? 0 : widget.WidgetLocation.X; + // widget.WidgetLocation.Y = widget.WidgetLocation.Y < 0 ? 0 : widget.WidgetLocation.Y; + // this.Invoke(new Action(() => this.Location = widget.WidgetLocation)); + // } + //} + + this.Invoke(new Action(() => this.Location = widget.WidgetLocation)); + + if (!(widget.WidgetWindowSize == default)) + this.Invoke(new Action(() => this.Size = widget.WidgetWindowSize)); + + + this.Move += (sender, eargs) => + { + //MessageBox.Show("LOCATION CHANGED"); + widget.WidgetLocation = this.Location; + }; + + this.SizeChanged += (sender, eargs) => + { + //MessageBox.Show("SIZE CHANGED"); + widget.WidgetWindowSize = this.Size; + }; + + if (!(widget.WidgetZoomScale == 0)) + browser.LoadingStateChanged += (sender, eargs) => + { + //MessageBox.Show("IS LOADED"); + if (!eargs.IsLoading) + if (waitingToSetZoom) + { + browser.SetZoomLevel(widget.WidgetZoomScale); + waitingToSetZoom = false; + } + }; + }; + + + + + #region garbage + //browser.Load(Embed); + //browser.LoadingStateChanged += async (s, e) => + //{ + // //MessageBox.Show("Loading State Changed is current disabled for development purposes. (by dev)"); + // //MessageBox.Show("MAINFRAME URL: " + e.Browser.MainFrame.Url); + + + // //e.Browser.StopLoad + + // if (!e.IsLoading) + // { + // if (ignoreLinkLoadingStateChanged) + // { + // ignoreLinkLoadingStateChanged = false; + // return; + // } + + // string script = "(function() { var body = document.body, html = document.documentElement; return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();"; + // await Task.Delay(5000); + + // var taskResult = browser.EvaluateScriptAsync(script); + + + // //Task t = new Task(() => browser.EvaluateScriptAsync(script)); + // //t.ContinueWith((task) => + // //{ + // // //MessageBox.Show("asdf"); + // // if (!task.IsFaulted) + // // { + // // var response = task as Task; + // // var result = response.Result; + + // // if (result.Success && response.Result != null) + // // { + // // taskResult = response.Result.ToString(); + // // } + // // } + // //}); + // //var height = t as Task; + // //MessageBox.Show(height.Result.Result.ToString()); + // MessageBox.Show((dynamic)taskResult.Result.Message); //finish this tomorrow. trying to get height so then i can get width and make the sizes be predefined! (use:https://stackoverflow.com/questions/60435891/how-to-get-html-document-height-using-cefsharp) + // } + //}; + + //browser.Click += (s, e) => + //{ + + //}; + + #endregion + + this.panel1.Controls.Add(browser); + browser.Dock = DockStyle.Fill; + + this.ShowInTaskbar = false; + //browser.Dock = DockStyle.Fill; + } + + public async void UpdateTitle() + { + string Title = await InputBox.Instance.Show("Enter new widget title:", "Rename Widget", widget.WidgetTitle == defaultTitle ? "" : widget.WidgetTitle, 32); //Interaction.InputBox("Enter new widget title:\n(16 characters max)", "Rename Widget"); + + if (Title == widget.WidgetTitle) + return; + + if (Title.Length == 0) + MessageBox.Show(new Form { TopMost = true }, "Title rename has been cancelled", "Rename Cancelled", MessageBoxButtons.OK, MessageBoxIcon.Information); + //else if (Title.Length > 32) + // MessageBox.Show(new Form { TopMost = true }, "Title is too long!", "Title Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + { + SetWidgetTitle(Title); + + MessageBox.Show(new Form { TopMost = true }, "Title has been renamed to: \"" + Title + "\"", "Rename Successful", MessageBoxButtons.OK, MessageBoxIcon.Information); + + return; + } + + //UpdateTitle(); + } + + public void SetWidgetTitle(string Title) + { + widget.WidgetTitle = Title; + WindowTitle.Text = Title; + } + + + #region WndProc stuff + private const int cGrip = 16; // Grip size + private const int cCaption = 32; // Caption bar height; + private const int WM_NCLBUTTONDBLCLK = 0x00A3; //double click on a title bar a.k.a. non-client area of the form + + int Mx; + int My; + int Sw; + int Sh; + + bool mov; + + void SizerMouseDown(object sender, MouseEventArgs e) + { + mov = true; + My = MousePosition.Y; + Mx = MousePosition.X; + Sw = Width; + Sh = Height; + } + + void SizerMouseMove(object sender, MouseEventArgs e) + { + if (mov == true) + { + Width = MousePosition.X - Mx + Sw; + Height = MousePosition.Y - My + Sh; + } + } + + void SizerMouseUp(object sender, MouseEventArgs e) + { + mov = false; + } + + public override Size MinimumSize + { + get + { + return base.MinimumSize; + } + set + { + base.MinimumSize = new Size(179, 51); + } + } + + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + // turn on WS_EX_TOOLWINDOW style bit + cp.ExStyle |= 0x80; + return cp; + } + } + + protected override void WndProc(ref Message m) + { + //if (m.Msg == 0x84) + //{ // Trap WM_NCHITTEST + // Point pos = new Point(m.LParam.ToInt32()); + // pos = this.PointToClient(pos); + // if (pos.Y < cCaption) + // { + // m.Result = (IntPtr)2; // HTCAPTION + // return; + // } + // if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip) + // { + // m.Result = (IntPtr)17; // HTBOTTOMRIGHT + // return; + // } + //} + + int x = (int)(m.LParam.ToInt64() & 0xFFFF); //get x mouse position + int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16); //get y mouse position you can gave (x,y) it from "MouseEventArgs" too + Point pt = PointToClient(new Point(x, y)); + + if (m.Msg == 0x84) + { + switch (resize.getMosuePosition(pt, this)) + { + case "l": m.Result = (IntPtr)10; return; // the Mouse on Left Form + case "r": m.Result = (IntPtr)11; return; // the Mouse on Right Form + case "a": m.Result = (IntPtr)12; return; + case "la": m.Result = (IntPtr)13; return; + case "ra": m.Result = (IntPtr)14; return; + case "u": m.Result = (IntPtr)15; return; + case "lu": m.Result = (IntPtr)16; return; + case "ru": m.Result = (IntPtr)17; return; // the Mouse on Right_Under Form + case "": m.Result = pt.Y < 32 /*mouse on title Bar*/ ? (IntPtr)2 : (IntPtr)1; return; + + } + } + else if (m.Msg == WM_NCLBUTTONDBLCLK) + { + m.Result = IntPtr.Zero; + return; + } + + base.WndProc(ref m); + } + #endregion + + public const int WM_NCLBUTTONDOWN = 0xA1; + public const int HT_CAPTION = 0x2; + + [DllImport("user32.dll")] + public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); + [DllImport("user32.dll")] + public static extern bool ReleaseCapture(); + + private void button1_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + ReleaseCapture(); + SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); + } + } + + + + private void Browser_Click(object sender, EventArgs e) + { + throw new NotImplementedException(); + } + + public void SetDefaultButtonDesign(Button b) + { + b.BackColor = Color.Black; + b.FlatStyle = FlatStyle.Flat; + b.FlatAppearance.BorderColor = Color.White; + b.FlatAppearance.BorderSize = 1; + + b.GotFocus += (s, e) => + { + this.Focus(); + }; + } + + + private void Form2_Load(object sender, EventArgs e) + { + + Form1.WidgetWindows.Add(this); + Form1.Widgets.Add(widget); + + foreach (var btn in this.Controls.OfType