C# NumLock Resume Fix 常駐程式

  • 461
  • 0
  • C#
  • 2017-04-08

因為新買的 Win10 筆電在睡眠恢復後,NumLock 會被關掉,所以寫了這個程式。

-------------------------------------------------

NumLock Resume Fix 下載 https://drive.google.com/open?id=0B-FwFpetKuXjTjBRSWJsSndtUWM

GitHub Link https://github.com/sbeat313/Winform/tree/master/NumLock

-------------------------------------------------

主要的設計方向

A - 1.判斷電腦從睡眠模式恢復。

A - 2.開啟 NumLock。

次要的設計方向

B - 1.開機啟動。

B - 2.程式常駐。

-------------------------------------------------

A - 1 判斷電腦從睡眠模式恢復。

使用的是 PowerModeChangedEventHandler (MSDN)

使用後會回傳三種模式,而我們選擇 " Resume " 來使用。

成員名稱 描述
Resume

作業系統即將從暫停狀態恢復。

StatusChange

由作業系統引發電源模式狀態通知事件。 這可能表示弱式或電池充電中、 AC 電源與電池或另一個系統的狀態變更之間轉換的電源供應器。

Suspend

作業系統即將暫停。

-------------------------------------------------

A - 2.開啟 NumLock。

開啟 NumLock則是調用 Win32.dll的 keybd_event function(MSDN) 方式達成

[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;

keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_KEYUP, 0);

-------------------------------------------------

P.s 若需要判斷 NumLock 目前狀態可使用 IsKeyLocked(MSDN)。

寫成如下:

if (!Control.IsKeyLocked(Keys.NumLock) == true)
{
   keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_EXTENDEDKEY, 0);
   keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_KEYUP, 0);
}

-------------------------------------------------

B - 1 開機啟動

透過在註冊表添加機碼的方式達成,使用 RegistryKey (MSDN)。

對此台電腦所有帳戶生效 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
對目前帳戶生效 "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"

我通常需要記錄少筆的程式設定值會使用 Registry 來儲存,多筆則寫成 *.ini 檔。

寫入值的方法 Registry.SetValue(String , Object , RegistryValueKind)。
讀取值的方法 Registry.GetValue(String , Object )。

-------------------------------------------------

B - 2 程式常駐

常駐:

1.程式收到右下角成為一個小圖示。

 - 使用工具箱的 NotifyIcon 可以達成,可以設定顯示的 Text 通常為程式名。 

 - 可以搭配工具箱的 ContextMenuStrip 使用,以達成小圖示右鍵功能表。

2.程式 " 不會 " 在工作列 Taskbar 出現。

 - this.ShowInTaskbar = false;

 

正常:

1.程式恢復到一般尺寸。

 - this.WindowState = FormWindowState.Minimized;

2.程式 " 會 " 在工作列 Taskbar 出現。

 - this.ShowInTaskbar = true;

-------------------------------------------------

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace NumLock
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
        const int KEYEVENTF_EXTENDEDKEY = 0x1;
        const int KEYEVENTF_KEYUP = 0x2;

        public Form1()
        {
            InitializeComponent();

            Registry.SetValue(@"HKEY_Current_User\Control Panel\Keyboard", "InitialKeyboardIndicators", "2");

            if (!Control.IsKeyLocked(Keys.NumLock) == true)
            {
                keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_EXTENDEDKEY, 0);
                keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_KEYUP, 0);
            }
        }

        RegistryKey regitsryKeyStartUp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

        #region 主程式

        #region 視窗載入
        private void Form1_Load(object sender, EventArgs e)
        {
            isFormHide();

            var isStartUp = (regitsryKeyStartUp.GetValue("NumLock Resume Fix") == null) ? chkBoxStartUp.Checked = false : chkBoxStartUp.Checked = true;

            SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEventsPowerModeChanged);
        }
        #endregion

        #region 判斷從睡眠模式回復並按下NumLock
        private void SystemEventsPowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
            if (e.Mode.ToString() == "Resume")
            {
                keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_EXTENDEDKEY, 0);
                keybd_event((byte)Keys.NumLock, 0, KEYEVENTF_KEYUP, 0);
            }
        }
        #endregion

        #endregion

        #region 人性化功能

        #region 判斷是否隱藏視窗
        private void isFormHide()
        {
            string registryPath = @"HKEY_CURRENT_USER\SOFTWARE\ChongHou";

            if (Registry.GetValue(registryPath, "Hide", "false") == null)
            {
                Registry.SetValue(registryPath, "Hide", "false");
            }
            else if (Registry.GetValue(registryPath, "Hide", "false").ToString() == "True")
            {
                this.WindowState = FormWindowState.Minimized;
                this.ShowInTaskbar = false;
                chkBoxHideMode.Checked = true;
            }
        }
        #endregion

        #region 設定是否開啟常駐模式
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            bool formHide;
            var checkFormHide = (chkBoxHideMode.Checked == true) ? formHide = true : formHide = false;
            Registry.SetValue(@"HKEY_CURRENT_USER\SOFTWARE\ChongHou", "Hide", formHide);
        }
        #endregion

        #region 解除常駐模式恢復正常視窗
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
        }
        #endregion

        #region 設定是否開機啟動
        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if(chkBoxStartUp.Checked == true)
            {
                regitsryKeyStartUp.SetValue("NumLock Resume Fix", Application.ExecutablePath);
            }
            else
            {
                regitsryKeyStartUp.DeleteValue("NumLock Resume Fix", false);
            }
        }
        #endregion

        #endregion
    }
}

 

本頁面為一點點累積學習寫程式之路。

許多資訊不是正確、或只是自己看的懂得。

如果不小心點進來誤導了您,還真的不好意思。