設置:
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);
}
}
完整實例:點擊打開鏈接