diff --git a/exhibit/Combination.cs b/exhibit/Combination.cs new file mode 100644 index 0000000..69b4889 --- /dev/null +++ b/exhibit/Combination.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Utilities; + +namespace exhibit +{ + class Combination + { + public delegate void EventFunction(List keys); + + private globalKeyboardHook _gkh = new globalKeyboardHook(); + private EventFunction _f; + private List _combinaison; + private List _pressed = new List(); + private bool _event = false; + + public Combination(List combinaison, EventFunction f) + { + _f = f; + _combinaison = combinaison; + foreach (Keys k in _combinaison) + { + _gkh.HookedKeys.Add(k); + _pressed.Add(false); + } + _gkh.KeyDown += new KeyEventHandler(gkh_KeyDown); + _gkh.KeyUp += new KeyEventHandler(gkh_KeyUp); + } + public void Start() + { + _gkh.hook(); + } + public void Stop() + { + _gkh.unhook(); + } + private void gkh_KeyUp(object sender, KeyEventArgs e) + { + e.Handled = true; + _event = false; + _pressed[_combinaison.IndexOf(e.KeyCode)] = false; + } + + private void gkh_KeyDown(object sender, KeyEventArgs e) + { + e.Handled = true; + if (_combinaison.IndexOf(e.KeyCode) == _combinaison.Count - 1) + { + bool before_pressed = true; + for (int i = 0; i < _combinaison.IndexOf(e.KeyCode); i++) + { + if (_pressed[i] == false) + { + before_pressed = false; + } + } + + if (before_pressed == true && _event == false) + { + _f(_combinaison); + _event = true; + } + } + else + { + _pressed[_combinaison.IndexOf(e.KeyCode)] = true; + } + } + } +} diff --git a/exhibit/Form1.Designer.cs b/exhibit/Form1.Designer.cs index 6920a63..f836b8b 100644 --- a/exhibit/Form1.Designer.cs +++ b/exhibit/Form1.Designer.cs @@ -30,33 +30,67 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.panel1 = new System.Windows.Forms.Panel(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.MouseMoveTimer = new System.Windows.Forms.Timer(this.components); + this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.cMS1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.RunStrip = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.Exit = new System.Windows.Forms.ToolStripMenuItem(); + this.textBox2 = new System.Windows.Forms.TextBox(); this.panel1.SuspendLayout(); + this.cMS1.SuspendLayout(); this.SuspendLayout(); // // panel1 // this.panel1.AutoSize = true; this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel1.Controls.Add(this.textBox2); + this.panel1.Controls.Add(this.checkBox1); + this.panel1.Controls.Add(this.linkLabel1); this.panel1.Controls.Add(this.button1); this.panel1.Controls.Add(this.textBox1); this.panel1.Controls.Add(this.label1); this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Location = new System.Drawing.Point(0, 0); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(455, 43); + this.panel1.Size = new System.Drawing.Size(460, 92); this.panel1.TabIndex = 0; // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Location = new System.Drawing.Point(15, 44); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(172, 17); + this.checkBox1.TabIndex = 10; + this.checkBox1.Text = "Show notification of last color?"; + this.checkBox1.UseVisualStyleBackColor = true; + this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.Location = new System.Drawing.Point(12, 69); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(121, 13); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Made by: tech-chieftain"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // // button1 // this.button1.Dock = System.Windows.Forms.DockStyle.Right; this.button1.Font = new System.Drawing.Font("Lucida Fax", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button1.Location = new System.Drawing.Point(310, 0); + this.button1.Location = new System.Drawing.Point(315, 0); this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(145, 43); + this.button1.Size = new System.Drawing.Size(145, 92); this.button1.TabIndex = 2; this.button1.Text = "Exhibit!"; this.button1.UseVisualStyleBackColor = true; @@ -64,13 +98,14 @@ private void InitializeComponent() // // textBox1 // - this.textBox1.Enabled = false; - this.textBox1.Location = new System.Drawing.Point(84, 13); + this.textBox1.Location = new System.Drawing.Point(84, 14); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(180, 20); + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(225, 20); this.textBox1.TabIndex = 1; - this.textBox1.Text = "#Color"; + this.textBox1.Text = "Color name (Hue, Saturation, Value)"; + this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // label1 // @@ -85,19 +120,76 @@ private void InitializeComponent() // this.MouseMoveTimer.Tick += new System.EventHandler(this.MouseMoveTimer_Tick_1); // + // notifyIcon1 + // + this.notifyIcon1.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; + this.notifyIcon1.BalloonTipTitle = "Exhibit"; + this.notifyIcon1.ContextMenuStrip = this.cMS1; + this.notifyIcon1.Text = "Exhibit"; + this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick); + // + // cMS1 + // + this.cMS1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.RunStrip, + this.toolStripSeparator1, + this.Exit}); + this.cMS1.Name = "cMS1"; + this.cMS1.Size = new System.Drawing.Size(184, 54); + // + // RunStrip + // + this.RunStrip.Name = "RunStrip"; + this.RunStrip.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt) + | System.Windows.Forms.Keys.Space))); + this.RunStrip.Size = new System.Drawing.Size(183, 22); + this.RunStrip.Text = "Run"; + this.RunStrip.Click += new System.EventHandler(this.RunStrip_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(180, 6); + // + // Exit + // + this.Exit.Name = "Exit"; + this.Exit.Size = new System.Drawing.Size(183, 22); + this.Exit.Text = "Exit"; + this.Exit.Click += new System.EventHandler(this.Exit_Click); + // + // textBox2 + // + this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox2.Location = new System.Drawing.Point(193, 40); + this.textBox2.Multiline = true; + this.textBox2.Name = "textBox2"; + this.textBox2.ReadOnly = true; + this.textBox2.Size = new System.Drawing.Size(116, 42); + this.textBox2.TabIndex = 11; + this.textBox2.Text = "Press CTRL+Space to stop and keep the last color."; + this.textBox2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // // frmMain // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(455, 43); - this.ControlBox = false; + this.ClientSize = new System.Drawing.Size(460, 92); this.Controls.Add(this.panel1); this.Cursor = System.Windows.Forms.Cursors.Default; + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(476, 131); + this.MinimumSize = new System.Drawing.Size(476, 131); this.Name = "frmMain"; - this.Text = "Form1"; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.Text = "Exhibit"; + this.TopMost = true; this.Load += new System.EventHandler(this.frmMain_Load); + this.Resize += new System.EventHandler(this.frmMain_Resize); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); + this.cMS1.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -110,6 +202,14 @@ private void InitializeComponent() private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Timer MouseMoveTimer; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.NotifyIcon notifyIcon1; + private System.Windows.Forms.ContextMenuStrip cMS1; + private System.Windows.Forms.ToolStripMenuItem RunStrip; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem Exit; + private System.Windows.Forms.TextBox textBox2; } } diff --git a/exhibit/Form1.cs b/exhibit/Form1.cs index 79d4e28..34593a3 100644 --- a/exhibit/Form1.cs +++ b/exhibit/Form1.cs @@ -8,18 +8,34 @@ due to their inability to differntiate certain colors. ----------------------------------------------------------------------------------------- I've used [John Gietzen] answer from this stackoverflow page [https://stackoverflow.com/questions/1483928/how-to-read-the-color-of-a-screen-pixel]. Thanks John! */ + + + + + + using System; using System.Drawing; using System.Windows.Forms; using System.Drawing.Imaging; using System.Runtime.InteropServices; +using Utilities; +using System.Collections.Generic; + namespace exhibit { public partial class frmMain : Form { + private bool showNotification = false; + private List C1 = new List { }; + int count = 0; + private globalKeyboardHook gkh = new globalKeyboardHook(); + private bool mouseMoveTimer = false; - - Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb); + + private Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb); + + private Combination Combinaison; [DllImport("user32.dll")] static extern bool GetCursorPos(ref Point lpPoint); @@ -44,19 +60,31 @@ public Color GetColorAt(Point location) gsrc.ReleaseHdc(); } } - return screenPixel.GetPixel(0, 0); } - + private void frmMain_Load(object sender, EventArgs e) { + List C1 = new List { Keys.LControlKey, Keys.Space }; + Combinaison = new Combination(C1, ConsoleLog); - } + notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; + notifyIcon1.BalloonTipText = "Exhibit is running."; + notifyIcon1.BalloonTipTitle = "Exhibit"; + notifyIcon1.Icon = SystemIcons.Application; - private void button1_Click(object sender, EventArgs e) + notifyIcon1.ShowBalloonTip(1000); + + } + public void ConsoleLog(List keys) { + + Console.WriteLine("Keys are press :" + keys.ToString()); if (!mouseMoveTimer) { + this.Focus(); + this.Show(); + this.WindowState = FormWindowState.Normal; MouseMoveTimer.Start(); mouseMoveTimer = true; } @@ -64,24 +92,33 @@ private void button1_Click(object sender, EventArgs e) { MouseMoveTimer.Stop(); mouseMoveTimer = false; + if (showNotification) + { + notifyIcon1.BalloonTipTitle = "Exhibit"; + notifyIcon1.BalloonTipText = "Last color is: " + textBox1.Text; + notifyIcon1.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; + notifyIcon1.Icon = SystemIcons.Application; + notifyIcon1.ShowBalloonTip(1000); + } } } - private static string HexConverter(Color c) + + private void button1_Click(object sender, EventArgs e) { - return String.Format("{0:X6}", c.ToArgb() & 0x00FFFFFF); - + ConsoleLog(C1); } private void MouseMoveTimer_Tick_1(object sender, EventArgs e) { + Point cursor = new Point(); GetCursorPos(ref cursor); - var c = GetColorAt(cursor); - textBox1.Text = NameOfColorHSV(c); + + } #region RGB /* @@ -96,8 +133,8 @@ private string NameOfColorRGB(Color c) //http://www.workwithcolor.com/orange-brown-color-hue-range-01.htm //The result that will be returned. - string colorName = null; - + string colorName = null; + //Pink-Red if ((c.R <= 255 && c.R >= 101) && (c.G <= 193 && c.G >= 0) && (c.B <= 204 && c.B >= 11)) { @@ -218,21 +255,28 @@ private string NameOfColorHSV(Color c) int max = Math.Max(c.R, Math.Max(c.G, c.B)); int min = Math.Min(c.R, Math.Min(c.G, c.B)); - var Hue = Math.Round(c.GetHue(), 2); + var Hue = Math.Round(c.GetHue()); var Saturation = ((max == 0) ? 0 : 1d - (1d * min / max)) * 100; - Saturation = Math.Round(Saturation, 2); - var Value = Math.Round(((max / 255d) * 100), 2); + Saturation = Math.Round(Saturation); + var Value = Math.Round(((max / 255d) * 100)); //The HSV model distributes colors in a 360(DEGREE) circle where all the colors are distributed //into a 60(DEGREE) slices. Value and saturation determine the brightness and + //Grey + if ((Value >= 8 && Value <= 84) & (Saturation <= 15)) + { + colorName = "Grey (" + Hue + "," + Saturation + "," + Value + ")"; + + } //White - if (Value == 100 && Saturation < 5) + else if (Value >= 85 && Saturation <= 4) { colorName = "White (" + Hue + "," + Saturation + "," + Value + ")"; } - else if (Value == 0 && Saturation < 95) + //White + else if (Value <= 7 && Saturation <= 4) { colorName = "Black (" + Hue + "," + Saturation + "," + Value + ")"; @@ -244,13 +288,13 @@ private string NameOfColorHSV(Color c) } //Pink - else if (Hue >= 331 && Hue <= 345) + else if (Hue >= 329 && Hue <= 345) { colorName = "Pink (" + Hue + "," + Saturation + "," + Value + ")"; } //Magenta-Pink - else if (Hue >= 321 && Hue <= 330) + else if (Hue >= 321 && Hue <= 328) { colorName = "Magenta-Pink (" + Hue + "," + Saturation + "," + Value + ")"; @@ -346,5 +390,58 @@ private string NameOfColorHSV(Color c) } #endregion + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("https://github.com/tech-chieftain"); + + } + + + private void checkBox1_CheckedChanged(object sender, EventArgs e) + { + if (showNotification) + { + showNotification = false; + } + else + { + showNotification = false; + + + } + + } + + private void RunStrip_Click(object sender, EventArgs e) + { + this.Focus(); + + ConsoleLog(C1); + this.Show(); + + } + + private void Exit_Click(object sender, EventArgs e) + { + this.Dispose(); + this.Close(); + + } + + private void frmMain_Resize(object sender, EventArgs e) + { + if (this.WindowState == FormWindowState.Minimized) + { + Hide(); + notifyIcon1.Visible = true; + } + } + + private void notifyIcon1_DoubleClick(object sender, EventArgs e) + { + Show(); + this.WindowState = FormWindowState.Normal; + notifyIcon1.Visible = false; + } } -} +} \ No newline at end of file diff --git a/exhibit/Form1.resx b/exhibit/Form1.resx index 0e0ded0..af13f0d 100644 --- a/exhibit/Form1.resx +++ b/exhibit/Form1.resx @@ -120,4 +120,10 @@ 17, 17 + + 167, 17 + + + 280, 17 + \ No newline at end of file diff --git a/exhibit/exhibit.csproj b/exhibit/exhibit.csproj index 9eac09e..3a0d0d1 100644 --- a/exhibit/exhibit.csproj +++ b/exhibit/exhibit.csproj @@ -44,12 +44,14 @@ + Form Form1.cs + diff --git a/exhibit/globalKeyboardHook.cs b/exhibit/globalKeyboardHook.cs new file mode 100644 index 0000000..364205b --- /dev/null +++ b/exhibit/globalKeyboardHook.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace Utilities { + /// + /// A class that manages a global low level keyboard hook + /// + class globalKeyboardHook { + #region Constant, Structure and Delegate Definitions + /// + /// defines the callback type for the hook + /// + public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam); + + public struct keyboardHookStruct { + public int vkCode; + public int scanCode; + public int flags; + public int time; + public int dwExtraInfo; + } + + const int WH_KEYBOARD_LL = 13; + const int WM_KEYDOWN = 0x100; + const int WM_KEYUP = 0x101; + const int WM_SYSKEYDOWN = 0x104; + const int WM_SYSKEYUP = 0x105; + #endregion + + #region Instance Variables + /// + /// The collections of keys to watch for + /// + public List HookedKeys = new List(); + /// + /// Handle to the hook, need this to unhook and call the next hook + /// + IntPtr hhook = IntPtr.Zero; + #endregion + + #region Events + /// + /// Occurs when one of the hooked keys is pressed + /// + public event KeyEventHandler KeyDown; + /// + /// Occurs when one of the hooked keys is released + /// + public event KeyEventHandler KeyUp; + #endregion + + #region Constructors and Destructors + /// + /// Initializes a new instance of the class and installs the keyboard hook. + /// + public globalKeyboardHook() { + hook(); + } + + /// + /// Releases unmanaged resources and performs other cleanup operations before the + /// is reclaimed by garbage collection and uninstalls the keyboard hook. + /// + ~globalKeyboardHook() { + unhook(); + } + #endregion + + #region Public Methods + /// + /// Installs the global hook + /// + public void hook() { + IntPtr hInstance = LoadLibrary("User32"); + hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0); + } + + /// + /// Uninstalls the global hook + /// + public void unhook() { + UnhookWindowsHookEx(hhook); + } + + /// + /// The callback for the keyboard hook + /// + /// The hook code, if it isn't >= 0, the function shouldn't do anyting + /// The event type + /// The keyhook event information + /// + public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) { + if (code >= 0) { + Keys key = (Keys)lParam.vkCode; + if (HookedKeys.Contains(key)) { + KeyEventArgs kea = new KeyEventArgs(key); + if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) { + KeyDown(this, kea) ; + } else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) { + KeyUp(this, kea); + } + if (kea.Handled) + return 1; + } + } + return CallNextHookEx(hhook, code, wParam, ref lParam); + } + #endregion + + #region DLL imports + /// + /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null + /// + /// The id of the event you want to hook + /// The callback. + /// The handle you want to attach the event to, can be null + /// The thread you want to attach the event to, can be null + /// a handle to the desired hook + [DllImport("user32.dll")] + static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId); + + /// + /// Unhooks the windows hook. + /// + /// The hook handle that was returned from SetWindowsHookEx + /// True if successful, false otherwise + [DllImport("user32.dll")] + static extern bool UnhookWindowsHookEx(IntPtr hInstance); + + /// + /// Calls the next hook. + /// + /// The hook id + /// The hook code + /// The wparam. + /// The lparam. + /// + [DllImport("user32.dll")] + static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam); + + /// + /// Loads the library. + /// + /// Name of the library + /// A handle to the library + [DllImport("kernel32.dll")] + static extern IntPtr LoadLibrary(string lpFileName); + #endregion + } +}