Skip to content

Instantly share code, notes, and snippets.

@neilbalch
Last active February 25, 2018 19:24
Show Gist options
  • Save neilbalch/0c0d957fa09139a6c10a7d8c0aa6d7db to your computer and use it in GitHub Desktop.
Save neilbalch/0c0d957fa09139a6c10a7d8c0aa6d7db to your computer and use it in GitHub Desktop.
KeyboardLocks Toast Message Version
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;
namespace KeyboardLocksIndicator {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
KeyboardLockIndicator lockIndicator = new KeyboardLockIndicator();
lockIndicator.StartLockIndicator();
/*// Form PictureBox Test (DELETE)
Form form = new Form();
form.Text = "Image Viewer";
PictureBox pictureBox = new PictureBox();
Bitmap myBitmap = new Bitmap("images.jpg");
pictureBox.Image = (Image)myBitmap;
pictureBox.Dock = DockStyle.Fill;
form.Controls.Add(pictureBox);
Application.Run(form);
*/
}
class KeyboardLockIndicator {
// Create tray icon and make it visible
NotifyIcon lockIcon;
// Create detecterWorker thread
Thread detecterWorker;
public void StartLockIndicator() {
// Create lockIcon tray icon and make it visible
lockIcon = new NotifyIcon {
Icon = new Icon("icon.ico"),
Visible = true
};
// Create Menu Items and add them to a context meny on the tray icon
MenuItem quit = new MenuItem("Quit / Exit");
MenuItem name = new MenuItem("Displays an overlay when any keyboard lock state changes.");
ContextMenu contextMenu = new ContextMenu();
contextMenu.MenuItems.Add(quit);
contextMenu.MenuItems.Add(name);
lockIcon.ContextMenu = contextMenu;
// Make Quit button close application
quit.Click += Quit_Click;
// Start the detecterWorker thread
detecterWorker = new Thread(new ThreadStart(KeyboardLockDetecter));
detecterWorker.Start();
}
#region Quit Button Handler
private void Quit_Click(object sender, EventArgs e) {
// Get rid of the tray icon
lockIcon.Dispose();
// Kill the Ping Sender thread
detecterWorker.Abort();
// Exit Apllication
Environment.Exit(1);
}
#endregion
#region KeyboardLockDetecter
class LockState {
// Is the numlock key on?
public bool Num;
// Is the capslock key on?
public bool Caps;
// Is the scroll lock key on?
public bool Scroll;
}
public void KeyboardLockDetecter() {
try {
// Store the old keyboard lock state
LockState prevState = new LockState() {
Num = Control.IsKeyLocked(Keys.NumLock),
Caps = Control.IsKeyLocked(Keys.CapsLock),
Scroll = Control.IsKeyLocked(Keys.Scroll)
};
while (true) {
// Store the new keyboard lock state
LockState newState = new LockState() {
Num = Control.IsKeyLocked(Keys.NumLock),
Caps = Control.IsKeyLocked(Keys.CapsLock),
Scroll = Control.IsKeyLocked(Keys.Scroll)
};
// Create a new icon for the tooltip message
ToolTipIcon icon = new ToolTipIcon();
//TODO(Neil): Handle simultaneous presses better, i.e. queue the balloon tips
//TODO(Neil): Make the image display work! i.e. figure out how to show translucent clickthrough-able bitmaps
if (newState.Num != prevState.Num) {
// Show Proper image
lockIcon.ShowBalloonTip(0 /*Depreciated Parameter*/, "Num Lock Event", newState.Num ? "On" : "Off", icon);
} else if (newState.Caps != prevState.Caps) {
// Show Proper image
lockIcon.ShowBalloonTip(0 /*Depreciated Parameter*/, "Caps Lock Event", newState.Caps ? "On" : "Off", icon);
} else if (newState.Scroll != prevState.Scroll) {
// Show Proper image
lockIcon.ShowBalloonTip(0 /*Depreciated Parameter*/, "Scroll Lock Event", newState.Scroll ? "On" : "Off", icon);
}
// Set the previous lock state to the new one in prep for the next iteration
prevState = newState;
// Sleep for 500ms
Thread.Sleep(500);
}
} catch (ThreadAbortException) {
// No need to do anything, just catch the ThreadAbortException.
}
}
#endregion
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment