设置:

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);
        }
    }
完整实例: 点击打开链接
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐