掛機鎖製作




設置:

button控件透明:backcolor設置爲transpare,flatStyle設置爲popup。

隱藏標題欄:FormBorderStyle設置爲None。

窗體初始位置:startPosition設置爲屏幕中央

關鍵代碼:

涉及的api及系統配置:

    class API
    {
        public const string itemName = "waitForLock";       //註冊表項名
        public const string valueName = "lockPassowrd";     //鍵名

        [StructLayout(LayoutKind.Sequential)]
        public struct KeyMSG
        {
            public int vkCode;//按鍵  
            public int scanCode;
            public int flags;//標誌是keyDown或keyUp  
            public int time;
            public int dwExtraInfo;
        }

        public delegate int keydownEvent(int nCode, int wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public extern static bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]

        public extern static int FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
         public extern static int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);

        /// 鉤子安裝  
        /// </summary>  
        /// <param name="HookType">表示鉤子類型,它是和鉤子函數類型一一對應的。如,WH_KEYBOARD,WH_MOUSE。</param>  
        /// <param name="methodAddress">鉤子函數入口地址</param>  
        /// <param name="handler">鉤子函數所在的實例的句柄。對於線程鉤子,該參數爲NULL;對於系統鉤子,該參數爲鉤子函數所在的DLL句柄。 (系統鉤子必須在DLL中)</param>  
        /// <param name="dwThread">指定鉤子所監視的線程的線程號。對於全局鉤子,該參數爲NULL。其中,全局鉤子函數必須包含在DLL(動態鏈接庫)中,而線程專用鉤子還可以包含在可執行文件中。</param>  
        /// <returns>所安裝的鉤子句柄</returns>  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int SetWindowsHookEx(int HookType, keydownEvent methodAddress, IntPtr handler, int dwThread);




        /// <summary>  
        ///交給下一個鉤子  
        /// </summary>  
        /// <param name="hhk">鉤子句柄</param>  
        /// <param name="nCode"></param>  
        /// <param name="wParam"></param>  
        /// <param name="lParam"></param>  
        /// <returns></returns>  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]  
        public  static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, Int32 wParam, IntPtr lParam);  
  
  
        /// <summary>  
        /// 釋放鉤子  
        /// </summary>  
        /// <param name="handler">鉤子id</param>  
        /// <returns></returns>  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]  
        public static extern bool UnhookWindowsHookEx(IntPtr handler);  
    }

將註冊表相關操作封裝爲一個類

    class myRegist
    {
        private const string root = "SOFTWARE";     //根目錄

        private RegistryKey reg;                    //註冊表操作對象
        private string FileName;                    //項名
        private List<string> keyNames;              //鍵名集,基於此集合創建鍵值對
        private string defaultValue;                //鍵對應的值的默認值

        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="fn">項名</param>
        /// <param name="kn">想要建立的鍵名集合</param>
        public myRegist(string fn,string[] kn=null)
        {
            FileName = fn;
            defaultValue = "";

            if (kn != null) keyNames = new List<string>(kn);
            else keyNames = new List<string>();
            
            reg = Registry.LocalMachine.OpenSubKey(root,true);
            RegistryKey tmp = reg.OpenSubKey(FileName, true);
            if (tmp != null) reg = tmp;
            else reg = reg.CreateSubKey(FileName);

            foreach(string name in keyNames)
            {
                if (reg.GetValue(name)==null) reg.SetValue(name, defaultValue);
            }
        }
        /// <summary>
        /// 設定指定鍵值
        /// </summary>
        /// <param name="name">鍵</param>
        /// <param name="value">值</param>
        public void setKeyValueByName(string name,string value)
        {
            reg.SetValue(name, value);
        }
        /// <summary>
        /// 取得指定鍵值
        /// </summary>
        /// <param name="name">鍵</param>
        /// <returns>值</returns>
        public object getValueByName(string name)
        {
            return reg.GetValue(name);
        }
    }
解鎖界面部分代碼:
    public partial class myUnlock : Form
    {
        private myRegist mr;
        public myUnlock()
        {
            InitializeComponent();
            mr = new myRegist(API.itemName);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if ((string)mr.getValueByName(API.valueName) == myPassword.Text)
            {
                sccuss();
                this.Close();
            }
            else MessageBox.Show("密碼錯誤");
        }
        /// <summary>
        /// 向form1窗體發送消息以解除掛機鎖
        /// </summary>
        private void sccuss()
        {
            int hwnd = API.FindWindow(null, "Form1");
            API.SendMessage((IntPtr)hwnd, 0x00, 0, 0);
            this.Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
修改掛機鎖界面代碼:
   public partial class updatePassword : Form
    {
        private myRegist mr;
        public updatePassword()
        {
            InitializeComponent();
            mr = new myRegist(API.itemName);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == (string)mr.getValueByName(textBox1.Text) || mr.getValueByName(textBox1.Text)==null)
            {
                mr.setKeyValueByName(API.valueName, textBox2.Text);
                this.Close();
                MessageBox.Show("修改成功");
            }
            else MessageBox.Show("修改失敗,原密碼錯誤");
        }
    }

主界面代碼:

    public partial class Form1 : Form
    {
        private bool isLockOpen;
        private int hand=0;

        private string[] status = {  "關閉" ,"開啓" };
        public Form1()
        {
            InitializeComponent();
            isLockOpen = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private int mykey(int nCode, int wParam, IntPtr lParam)
        {
            bool ret=false;
            if (nCode>=0)
            {
                API.KeyMSG km = (API.KeyMSG)Marshal.PtrToStructure(lParam, typeof(API.KeyMSG));
                KeyEventArgs kEvent = new KeyEventArgs((Keys)km.vkCode);
                if (!(ret=mykeyfunc(this, kEvent)))
                {
                    API.CallNextHookEx((IntPtr)hand, nCode, wParam, lParam);
                }
            }
            return Convert.ToInt32(ret);
        }
        /// <summary>
        /// 篩選鍵盤消息,屏蔽系統熱鍵
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private bool mykeyfunc(object sender, KeyEventArgs e)
        {
            bool flag = true;
            switch(e.KeyData)
            {
                case Keys.Tab:
                case Keys.Menu:
                case Keys.F4:
                case Keys.ControlKey:
                case Keys.LWin:
                case Keys.RWin:
                    break;
                default:
                    flag = false;
                    break;
            }
            return flag;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (isLockOpen)//已開啓,則關閉
            {
                (new myUnlock()).Show();
            }
            else//已關閉,則開啓
            {
                OpenLock();
            }
        }
        private void CloseLock()
        {
            label1.Text = label1.Text.Replace("開啓", "關閉");
            button1.Text = "開啓";
            Cursor.Clip = Screen.AllScreens[0].Bounds;
            isLockOpen = !isLockOpen;
            API.UnhookWindowsHookEx((IntPtr)hand);
        }
        private void OpenLock()
        {
            label1.Text = label1.Text.Replace("關閉", "開啓");
            button1.Text = "關閉";
            this.Cursor = new Cursor(Cursor.Current.Handle);
            Cursor.Position =PointToScreen(new Point(this.button1.Location.X+20 , this.button1.Location.Y+10 ));
            Cursor.Clip = new Rectangle(this.Location, this.Size);
            isLockOpen = !isLockOpen;
            hand = API.SetWindowsHookEx(13, new API.keydownEvent(mykey), IntPtr.Zero, 0);
        }

        private void updatePassword_Click(object sender, EventArgs e)
        {
            (new updatePassword()).Show();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            API.UnhookWindowsHookEx((IntPtr)hand);
        }

        /// <summary>
        /// 接收消息以判斷是否解除掛機鎖
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            if (m.Msg==0x0)
            {
                CloseLock();
            }
            base.WndProc(ref m);
        }
    }
完整實例:點擊打開鏈接
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章