前端时间,老大一天到晚脖子痛,说是老了,不能比我们年轻人了...
其实我脖子也痛好吗!!!
就有做个软件的想法,于是产生了这个东西——StandUp。
一个非常简陋的小东西,不过也有值得学习的地方,是基于 WPF 的。
<Window x:Class="StandUp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StandUp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label x:Name="labPointer" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<Label x:Name="labRestPointer" Content="Label" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top"/>
<Label x:Name="labInfo" Content="请休息五分钟后再回来!" Margin="255,0,205,42" Foreground="White" FontWeight="Bold" VerticalAlignment="Bottom" Height="60" Width="500" BorderBrush="White" FontSize="24" RenderTransformOrigin="0.5,0.5">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform X="100"/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace StandUp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private DispatcherTimer timer;
private DispatcherTimer restTimer;
private const long timeToWork = 300;//(5分钟)
private const long timeToStandUp = 3600;//(1小时)
//private const long timeToWork = 300;//(1分钟)
//private const long timeToStandUp = 30;//(5分钟)
private long timeSpan = 0;
private long momentTs = 0;
private NotifyIcon notifyIcon;
#region 禁用全局快捷键
public static bool IsEnableHook;
private struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hHook);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(IntPtr path);
private IntPtr hHook;
LowLevelKeyboardProcDelegate hookProc; // prevent gc
const int WH_KEYBOARD_LL = 13;
public enum Ekey
{
VK_LBUTTON = 0x01,// Left mouse button
VK_RBUTTON = 0x02,// Right mouse button
VK_CANCEL = 0x03,// Control-break processing
VK_MBUTTON = 0x04,// Middle mouse button (three-button mouse)
VK_XBUTTON1 = 0x05,// X1 mouse button
VK_XBUTTON2 = 0x06,// X2 mouse button
VK_BACK = 0x08,// BACKSPACE key
VK_TAB = 0x09,// TAB key
VK_CLEAR = 0x0C,// CLEAR key
VK_RETURN = 0x0D,// ENTER key
VK_SHIFT = 0x10,// SHIFT key
VK_CONTROL = 0x11,// CTRL key
VK_MENU = 0x12,// ALT key
VK_PAUSE = 0x13,// PAUSE key
VK_CAPITAL = 0x14,// CAPS LOCK key
VK_KANA = 0x15,// IME Kana mode
VK_HANGUEL = 0x15,// IME Hanguel mode (maintained for compatibility; use VK_HANGUL)
VK_HANGUL = 0x15,// IME Hangul mode
VK_JUNJA = 0x17,// IME Junja mode
VK_FINAL = 0x18,// IME final mode
VK_HANJA = 0x19,// IME Hanja mode
VK_KANJI = 0x19,// IME Kanji mode
VK_ESCAPE = 0x1B,// ESC key
VK_CONVERT = 0x1C,// IME convert
VK_NONCONVERT = 0x1D,// IME nonconvert
VK_ACCEPT = 0x1E,// IME accept
VK_MODECHANGE = 0x1F,// IME mode change request
VK_SPACE = 0x20,// SPACEBAR
VK_PRIOR = 0x21,// PAGE UP key
VK_NEXT = 0x22,// PAGE DOWN key
VK_END = 0x23,// END key
VK_HOME = 0x24,// HOME key
VK_LEFT = 0x25,// LEFT ARROW key
VK_UP = 0x26,// UP ARROW key
VK_RIGHT = 0x27,// RIGHT ARROW key
VK_DOWN = 0x28,// DOWN ARROW key
VK_SELECT = 0x29,// SELECT key
VK_PRINT = 0x2A,// PRINT key
VK_EXECUTE = 0x2B,// EXECUTE key
VK_SNAPSHOT = 0x2C,// PRINT SCREEN key
VK_INSERT = 0x2D,// INS key
VK_DELETE = 0x2E,// DEL key
VK_HELP = 0x2F,// HELP key
N0 = 0x30,// 0 key
N1 = 0x31,// 1 key
N2 = 0x32,// 2 key
N3 = 0x33,// 3 key
N4 = 0x34,// 4 key
N5 = 0x35,// 5 key
N6 = 0x36,// 6 key
N7 = 0x37,// 7 key
N8 = 0x38,// 8 key
N9 = 0x39,// 9 key
A = 0x41,// A key
B = 0x42,// B key
C = 0x43,// C key
D = 0x44,// D key
E = 0x45,// E key
F = 0x46,// F key
G = 0x47,// G key
H = 0x48,// H key
I = 0x49,// I key
J = 0x4A,// J key
K = 0x4B,// K key
L = 0x4C,// L key
M = 0x4D,// M key
N = 0x4E,// N key
O = 0x4F,// O key
P = 0x50,// P key
Q = 0x51,// Q key
R = 0x52,// R key
S = 0x53,// S key
T = 0x54,// T key
U = 0x55,// U key
V = 0x56,// V key
W = 0x57,// W key
X = 0x58,// X key
Y = 0x59,// Y key
Z = 0x5A,// Z key
VK_LWIN = 0x5B,// Left Windows key (Natural keyboard)
VK_RWIN = 0x5C,// Right Windows key (Natural keyboard)
VK_APPS = 0x5D,// Applications key (Natural keyboard)
VK_SLEEP = 0x5F,// Computer Sleep key
VK_NUMPAD0 = 0x60,// Numeric keypad 0 key
VK_NUMPAD1 = 0x61,// Numeric keypad 1 key
VK_NUMPAD2 = 0x62,// Numeric keypad 2 key
VK_NUMPAD3 = 0x63,// Numeric keypad 3 key
VK_NUMPAD4 = 0x64,// Numeric keypad 4 key
VK_NUMPAD5 = 0x65,// Numeric keypad 5 key
VK_NUMPAD6 = 0x66,// Numeric keypad 6 key
VK_NUMPAD7 = 0x67,// Numeric keypad 7 key
VK_NUMPAD8 = 0x68,// Numeric keypad 8 key
VK_NUMPAD9 = 0x69,// Numeric keypad 9 key
VK_MULTIPLY = 0x6A,// Multiply key
VK_ADD = 0x6B,// Add key
VK_SEPARATOR = 0x6C,// Separator key
VK_SUBTRACT = 0x6D,// Subtract key
VK_DECIMAL = 0x6E,// Decimal key
VK_DIVIDE = 0x6F,// Divide key
VK_F1 = 0x70,// F1 key
VK_F2 = 0x71,// F2 key
VK_F3 = 0x72,// F3 key
VK_F4 = 0x73,// F4 key
VK_F5 = 0x74,// F5 key
VK_F6 = 0x75,// F6 key
VK_F7 = 0x76,// F7 key
VK_F8 = 0x77,// F8 key
VK_F9 = 0x78,// F9 key
VK_F10 = 0x79,// F10 key
VK_F11 = 0x7A,// F11 key
VK_F12 = 0x7B,// F12 key
VK_NUMLOCK = 0x90,// NUM LOCK key
VK_SCROLL = 0x91,// SCROLL LOCK key
VK_LSHIFT = 0xA0,// Left SHIFT key
VK_RSHIFT = 0xA1,// Right SHIFT key
VK_LCONTROL = 0xA2,// Left CONTROL key
VK_RCONTROL = 0xA3,// Right CONTROL key
VK_LMENU = 0xA4,// Left MENU key
VK_RMENU = 0xA5,// Right MENU key
VK_BROWSER_BACK = 0xA6,// Browser Back key
VK_BROWSER_FORWARD = 0xA7,// Browser Forward key
VK_BROWSER_REFRESH = 0xA8,// Browser Refresh key
VK_BROWSER_STOP = 0xA9,// Browser Stop key
VK_BROWSER_SEARCH = 0xAA,// Browser Search key
VK_BROWSER_FAVORITES = 0xAB,// Browser Favorites key
VK_BROWSER_HOME = 0xAC,// Browser Start and Home key
VK_VOLUME_MUTE = 0xAD,// Volume Mute key
VK_VOLUME_DOWN = 0xAE,// Volume Down key
VK_VOLUME_UP = 0xAF,// Volume Up key
VK_MEDIA_NEXT_TRACK = 0xB0,// Next Track key
VK_MEDIA_PREV_TRACK = 0xB1,// Previous Track key
VK_MEDIA_STOP = 0xB2,// Stop Media key
VK_MEDIA_PLAY_PAUSE = 0xB3,// Play/Pause Media key
VK_LAUNCH_MAIL = 0xB4,// Start Mail key
VK_LAUNCH_MEDIA_SELECT = 0xB5,// Select Media key
VK_LAUNCH_APP1 = 0xB6,// Start Application 1 key
VK_LAUNCH_APP2 = 0xB7,// Start Application 2 key
VK_OEM_1 = 0xBA,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_PLUS = 0xBB,// For any country/region, the '+' key
VK_OEM_COMMA = 0xBC,// For any country/region, the ',' key
VK_OEM_MINUS = 0xBD,// For any country/region, the '-' key
VK_OEM_PERIOD = 0xBE,// For any country/region, the '.' key
VK_OEM_2 = 0xBF,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_3 = 0xC0,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_4 = 0xDB,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_5 = 0xDC,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_6 = 0xDD,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_7 = 0xDE,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_8 = 0xDF,// Used for miscellaneous characters; it can vary by keyboard.
VK_OEM_102 = 0xE2,// Either the angle bracket key or the backslash key on the RT 102-key keyboard
VK_PROCESSKEY = 0XE5,// IME PROCESS key
VK_PACKET = 0xE7,// Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key
VK_ATTN = 0xF6,// Attn key
VK_CRSEL = 0xF7,// CrSel key
VK_EXSEL = 0xF8,// ExSel key
VK_EREOF = 0xF9,// Erase EOF key
VK_PLAY = 0xFA,// Play key
VK_ZOOM = 0xFB,// Zoom key
VK_NONAME = 0xFC,// Reserved
VK_PA1 = 0xFD,// PA1 key
VK_OEM_CLEAR = 0xFE,// Clear key
}
//protected override void OnExit(ExitEventArgs e)
//{
// UnhookWindowsHookEx(hHook); // release keyboard hook
// base.OnExit(e);
//}
private static int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
{
if (nCode >= 0)
switch (wParam)
{
case 256: // WM_KEYDOWN
case 257: // WM_KEYUP
case 260: // WM_SYSKEYDOWN
case 261: // M_SYSKEYUP
if (
(lParam.vkCode == (int)Ekey.VK_SPACE && lParam.flags == 32) || // Alt+ space
(lParam.vkCode == (int)Ekey.VK_TAB && lParam.flags == 32) || // Alt+Tab
(lParam.vkCode == (int)Ekey.VK_ESCAPE && lParam.flags == 32) || // Alt+Esc
(lParam.vkCode == (int)Ekey.VK_F4 && lParam.flags == 32) || // Alt+F4
(lParam.vkCode == (int)Ekey.VK_ESCAPE && lParam.flags == 0) || // Ctrl+Esc
(lParam.vkCode == 0x5b && lParam.flags == 1) || // Left Windows Key
(lParam.vkCode == 0x5c && lParam.flags == 1)) // Right Windows Key
{
return 1;
}
break;
}
return CallNextHookEx(0, nCode, wParam, ref lParam);
}
#endregion
public MainWindow()
{
InitializeComponent();
// hook keyboard
IntPtr hModule = GetModuleHandle(IntPtr.Zero);
hookProc = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hModule, 0);
if (hHook == IntPtr.Zero)
System.Windows.Forms.MessageBox.Show("不能设置快捷键:" + Marshal.GetLastWin32Error());
else
IsEnableHook = true;
ImageBrush b = new ImageBrush();
b.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/bg.jpg", UriKind.RelativeOrAbsolute));
//b.ImageSource = new BitmapImage(new Uri("pack://application:,,,../../bg.jpg", UriKind.RelativeOrAbsolute));
b.Stretch = Stretch.Fill;
this.Background = b;
#region 图标显示在托盘
this.notifyIcon = new NotifyIcon();
this.notifyIcon.BalloonTipText = "Stand Up | ";
this.notifyIcon.ShowBalloonTip(2000);
this.notifyIcon.Text = "Stand Up | ";
this.notifyIcon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath);
this.notifyIcon.Visible = true;
string startUpStr = GetRegRunState("StandUp") ? "取消自启动" : "自启动";
System.Windows.Forms.MenuItem startUp = new System.Windows.Forms.MenuItem(startUpStr);
startUp.Click += new EventHandler((o, e) =>
{
if (startUp.Text.Equals("自启动"))
{
if (RegRun("StandUp", true))
startUp.Text = "取消自启动";
}
else
{
if (RegRun("StandUp", false))
startUp.Text = "自启动";
}
});
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("打开");
open.Click += new EventHandler(Show);
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("退出");
exit.Click += new EventHandler(Close);
//关联托盘控件
System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { startUp, open, exit };
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler((o, e) =>
{
if (e.Button == MouseButtons.Left) this.Show(o, e);
});
#endregion
ShowInTaskbar = false;
WindowState = WindowState.Maximized;
WindowStyle = WindowStyle.None;
labInfo.Content = "";
Loaded += new RoutedEventHandler(RestTimeLoaded);
Loaded += new RoutedEventHandler(TimerLoaded);
}
/// <summary>
/// 工作计时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void TimerLoaded(object sender, RoutedEventArgs e)
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += new EventHandler(TimerArrive);
timer.Start();
}
/// <summary>
/// 休息计时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void RestTimeLoaded(object sender, RoutedEventArgs e)
{
restTimer = new DispatcherTimer();
restTimer.Interval = TimeSpan.FromSeconds(1);
restTimer.Tick += new EventHandler(RestTimerArrive);
}
/// <summary>
/// 工作期间执行的时间
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TimerArrive(object sender, EventArgs e)
{
if (IsEnableHook)
{
if (UnhookWindowsHookEx(hHook))
IsEnableHook = false;
else
IsEnableHook = true;
}
if (this.Visibility != Visibility.Hidden)
{
ShowInTaskbar = false;
momentTs++;
if (momentTs >= 5)
this.Hide();
}
string notiInfo = GetTime(true);
this.notifyIcon.BalloonTipText = this.notifyIcon.Text = "Stand Up | " + notiInfo;
labInfo.Content = notiInfo;
timeSpan++;
if (timeSpan == timeToStandUp)
{
timeSpan = 0;
timer.Stop();
restTimer.Start();
}
}
private string GetTime(bool getTimeToStandUp)
{
string result = string.Empty;
if (getTimeToStandUp)
{
long ts = timeToStandUp - timeSpan;
string clockStr = string.Format("{0} 小时 {1} 分钟 {2} 秒", ts / 3600, (ts % 3600) / 60, (ts % 3600) % 60);
result = string.Format("您还可以工作:{0}", clockStr);
}
else
{
long ts = timeToWork - timeSpan;
string clockStr = string.Format("{0} 分钟 {1} 秒", ts / 60, ts % 60);
result = string.Format("您还可以休息:{0}", clockStr);
}
return result;
}
/// <summary>
/// 休息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RestTimerArrive(object sender, EventArgs e)
{
if (!IsEnableHook)
{
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, GetModuleHandle(IntPtr.Zero), 0);
if (hHook == IntPtr.Zero)
{
IsEnableHook = false;
System.Windows.Forms.MessageBox.Show("不能设置快捷键:" + Marshal.GetLastWin32Error());
}
else
IsEnableHook = true;
}
momentTs = 0;
if (this.Visibility != Visibility.Visible)
this.Show();
labInfo.Content = GetTime(false);
timeSpan++;
if (timeSpan == timeToWork)
{
timeSpan = 0;
restTimer.Stop();
timer.Start();
}
}
private void Show(object sender, EventArgs e)
{
momentTs = 0;
this.Visibility = System.Windows.Visibility.Visible;
this.ShowInTaskbar = true;
this.Activate();
}
private void Hide(object sender, EventArgs e)
{
this.ShowInTaskbar = false;
this.Visibility = System.Windows.Visibility.Hidden;
}
private void Close(object sender, EventArgs e)
{
bool result = UnhookWindowsHookEx(hHook);
System.Windows.Application.Current.Shutdown();
}
/// <summary>
/// 自启动
/// </summary>
/// <param name="appName"></param>
/// <param name="f"></param>
bool RegRun(string appName, bool f)
{
RegistryKey HKCU = Registry.CurrentUser;
RegistryKey Run = HKCU.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
bool b = false;
foreach (string i in Run.GetValueNames())
{
if (i == appName)
{
b = true;
break;
}
}
try
{
if (f)
Run.SetValue(appName, System.Windows.Forms.Application.ExecutablePath);
else
Run.DeleteValue(appName);
}
catch
{
return false;
}
HKCU.Close();
return true;
}
/// <summary>
/// 获取当前是否开机启动
/// </summary>
/// <param name="appName"></param>
/// <returns></returns>
bool GetRegRunState(string appName)
{
bool result = false;
RegistryKey HKCU = Registry.CurrentUser;
RegistryKey Run = HKCU.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
try
{
if (Run.GetValue(appName) != null)
result = true;
}
catch
{
return result; ;
}
HKCU.Close();
return result;
}
}
}
虽然是找资料东平西凑做出来的,不过也算是灵活应变嘛!嘿嘿!
对了,这里面加入了开机自启和休息时间屏蔽快捷键的功能.
不过屏蔽快捷键的功能做的不是特别好,ctrl + alt + del 可以打开任务管理器...这个不知道怎么解决...