我想做一个程序,需要控制电脑的键盘和鼠标,锁住键盘和鼠标使得用户操作锁住键盘和鼠标时无效,我想用 hook做一个全局钩子,但是同时我还要通过keyboardevent和mouseevent来模拟鼠标键盘操作,怎么样才能不屏蔽我自己的鼠标键盘操作?

解决方案 »

  1.   

    在CodeProject上看到过一个别人写的全局Hook...不知道有没有用.
      

  2.   

    RickTroy(崔驰坤 Richard Troy-Rex,RickTroy)大哥,你回来看看,怎么没人回答呢!
      

  3.   

    1
      ①使用未公开API:BlockInput,
      ②然后再屏蔽Ctrl   +   Alt   +   Del等键,就是重写一个gra.dll。   
    2
    可以用鼠标和键盘的过滤驱动. 偶有DDK改天下去看看,赫赫:)
      

  4.   

    终于找到了这篇,希望对你有所帮助:
    感谢您使用微软产品。您可以响应form的MouseMove事件,然后在该事件的处理函数中对鼠标位置进行判断、控制:
    private void InitializeComponent()
    {
    ...
    this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
    ...
    }private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    System.Drawing.Point pt = this.PointToClient(Cursor.Position);
    if (pt.X > 200)
    {
    Cursor.Position = new System.Drawing.Point(200,pt.Y);
    }
    if (pt.Y >200)
    {
    Cursor.Position = new System.Drawing.Point(pt.X,200);
    }
    }
    希望能对您有所帮助!======================
    - 微软全球技术中心本贴子仅供19b的用户作为参考信息使用。其内容不具备任何法律保障。您需要考虑到并承担使用此信息可能带来的风险。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
    为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
    ======================
      

  5.   

    ClipCursor()把鼠标限制在一个区域内
      

  6.   

    下面是一段VB6代码
    Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)
    Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As LongConst WM_MOUSELAST = &H209
    Const WM_MOUSEFIRST = &H200
    Public Const WM_KEYLAST = &H108
    Public Const WM_KEYFIRST = &H100
    Public Const WH_JOURNALRECORD = 0
    Public Const WH_JOURNALPLAYBACK = 1Type EVENTMSG
            message As Long
            paramL As Long
            paramH As Long
            time As Long
            hwnd As Long
    End TypePublic hNxtHook As Long   ' 钩子过程的句柄
    Public msg As EVENTMSGSub EnableHook()'锁住键盘和鼠标
       hNxtHook = SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf HookProc, App.hInstance, 0)
    End SubSub FreeHook()'释放键盘和鼠标
        UnhookWindowsHookEx hNxtHook
    End SubFunction HookProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        HookProc = CallNextHookEx(hNxtHook, code, wParam, lParam)
    End Function
      

  7.   

    下面是模拟鼠标
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPrivate Const MK_CONTROL = &H8  ' 键盘Ctrl键
    Private Const MK_LBUTTON = &H1  ' 鼠标左键
    Private Const MK_MBUTTON = &H10 ' 鼠标中键
    Private Const MK_RBUTTON = &H2  ' 鼠标右键Private Const WM_MBUTTONDOWN = &H207   ' 鼠标中键按下
    Private Const WM_MBUTTONUP = &H208     ' 鼠标中键抬起
    Private Const WM_LBUTTONDOWN = &H201   ' 鼠标左键按下
    Private Const WM_LBUTTONUP = &H202     ' 鼠标左键抬起
    Private Const WM_LBUTTONDBLCLK = &H203 ' 鼠标左键双击
    Private Const WM_MOUSEMOVE = &H200     ' 鼠标移动
    Private Const WM_RBUTTONDBLCLK = &H206 ' 鼠标右键双击
    Private Const WM_RBUTTONDOWN = &H204   ' 鼠标右键按下
    Private Const WM_RBUTTONUP = &H205     ' 鼠标右键抬起
    Private Const HWND_BROADCAST = &HFFFF& ' 用来对所有的窗口传送消息Private Type POINTAPI
            X As Long
            Y As Long
    End Type' 根据lParam 参数取得对应的X,Y坐标
    Private Function GetPointXY(ByVal lParam As Long) As POINTAPI
        GetPointXY.X = lParam And &HFFFF
        GetPointXY.Y = (lParam And &HFFFF0000) / (2 ^ 16)
    End Function' 将位置坐标转换为 Twips单位
    Private Function XY2Twips(ByRef pos As POINTAPI)
        pos.X = pos.X * Screen.TwipsPerPixelX
        pos.Y = pos.Y * Screen.TwipsPerPixelY
    End Function' 移动光标
    Private Sub MoveCursor(ByVal X As Integer, ByVal Y As Integer)
        SetCursorPos X, Y
        Me.Caption = "X:" & X & ",Y:" & Y
    End Sub' 延时
    Public Sub Pause(HowLong As Long)
        Dim tick As Long
        
        tick = GetTickCount()
        Do
          DoEvents
        Loop Until tick + HowLong < GetTickCount
    End Sub'  移动光标
    Private Sub MouseMove()
        Dim X As Long, Y As Long
        Dim pos As POINTAPI
        Dim demopos As POINTAPI
        
        ' 演示按钮区域的左上角
        demopos.X = (TestCmd.Left + TestCmd.Width / 2 + Me.Left) / Screen.TwipsPerPixelX
        demopos.Y = (TestCmd.Top + TestCmd.Height / 2 + Me.Top + 300) / Screen.TwipsPerPixelY
        
        ' 得到当前光标位置
        GetCursorPos pos
        
        ' 循环,将光标移动到 demopos 位置
        For X = pos.X To demopos.X Step -1
            Pause 4
            MoveCursor X, pos.Y
        Next
        For Y = pos.Y To demopos.Y Step -1
            Pause 10
            MoveCursor demopos.X, Y
        Next
    End Sub'  单击演示按钮开始演示
    Private Sub DemoCmd_Click()
        Dim lParam As Long
        Dim pos As POINTAPI
        Dim i As Integer
        Dim h As Long
        
        '  移动光标
        Call MouseMove
        
        '  得到当前光标位置
        GetCursorPos pos
        lParam = CLng(pos.X) + CLng(pos.Y) * (2 ^ 16)
        h = TestCmd.hwnd
        '  传递鼠标按下操作
        Call PostMessage(h, WM_LBUTTONDOWN, MK_LBUTTON, lParam)
        lblTip.Caption = "光标按下"
        DoEvents
        '  延时
        Pause 1000
        '  传递鼠标抬起操作
        Call PostMessage(Me.TestCmd.hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam)
        Me.lblTip.Caption = "光标抬起"
    End Sub
     
    Private Sub TestCmd_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
        MsgBox "HELLO"
    End Sub
      

  8.   

    模拟鼠标键盘都不是问题,问题是,当我用hook把键盘和鼠标消息过滤后,不是也把自己模拟鼠标键盘的消息也过滤掉了???
      

  9.   

    限制鼠标在一个范围也可以做到,但是我不能限制鼠标在一个范围,因为我模拟鼠标键盘时要超出此范围,如果限制范围,那我模拟的鼠标键盘不也不能超出这个范围。还有就是要考虑键盘呢???
    键盘怎么控制啊??怎么过滤掉用户输入的键盘信息?
    我的想法是用钩子hook。现在基本想通了,不过还没实现,^_^!
      

  10.   

    hook 的办法不可靠,
    尽管现在好多人 ,好多软件,都用这个hook方法来解决问题,就像网管软件。
    除了在增加键盘的驱动写一个filter外,
    就是使用BlockInput(true)/ BlockInput(false)进行锁住键盘鼠标。
    如果在要对alt+ctl+del控制,就要重写gra.dll了。
      

  11.   

    上面的gra.dll写错了,是msgina.dll
    =======================
    交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。在WinLogon初始化时,就向系统注册截获CTRL+ALT+DEL消息,所以其他程序就无法得到CTRL+ALT+DEL的消息。
    WinLogon会和GINA DLL进行交互,缺省是MSGINA.DLL(在System32目录下)。微软同时也为我们提供的接口,自己
    可以编GINA DLL来代替MSGINA.DLL。
      

  12.   

    不知道这个对楼主有没有帮助,这个可以截获键盘,鼠标的
    如果截获后,把该事件不扔出去,就算锁了吧这是以前看到的,c#全局钩子
    内容太长,分2段
    using System;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Threading;
    using System.Windows.Forms;
    namespace GlobalHookDemo  
    {

    /// <summary>
    /// This class allows you to tap keyboard and mouse and / or to detect their activity even when an 
    /// application runes in background or does not have any user interface at all. This class raises 
    /// common .NET events with KeyEventArgs and MouseEventArgs so you can easily retrive any information you need.
    /// </summary>
    /// <res>
    ///  created by - Georgi
    ///  created on - 22.05.2004 13:08:01
    /// </res>
    public class UserActivityHook : object 
    {

    /// <summary>
    /// Default constructor - starts hooks automatically
    /// </summary>
    public UserActivityHook() 
    {
    Start();
    }

    ~UserActivityHook() 

    Stop();
    }  //public event MouseEventHandler OnMouseActivity;
    public event KeyEventHandler KeyDown;
    public event KeyPressEventHandler KeyPress;
    public event KeyEventHandler KeyUp;
    //public event EventHandler MainForm_MinimumSizeChanged; public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); // static int hMouseHook = 0; //Declare mouse hook handle as int.
    static int hKeyboardHook = 0; //Declare keyboard hook handle as int. //values from Winuser.h in Microsoft SDK.
    // public const int WH_MOUSE_LL  = 14; //mouse hook constant
    public const int WH_KEYBOARD_LL = 13; //keyboard hook constant // HookProc MouseHookProcedure; //Declare MouseHookProcedure as HookProc type.
    HookProc KeyboardHookProcedure; //Declare KeyboardHookProcedure as HookProc type.
    //Declare wrapper managed POINT class.
    // [StructLayout(LayoutKind.Sequential)]
    // public class POINT 
    // {
    // public int x;
    // public int y;
    // } //Declare wrapper managed MouseHookStruct class.
    // [StructLayout(LayoutKind.Sequential)]
    // public class MouseHookStruct 
    // {
    // public POINT pt;
    // public int hwnd;
    // public int wHitTestCode;
    // public int dwExtraInfo;
    // } //Declare wrapper managed KeyboardHookStruct class.
    [StructLayout(LayoutKind.Sequential)]
    public class KeyboardHookStruct
    {
    public int vkCode; //Specifies a virtual-key code. The code must be a value in the range 1 to 254. 
    public int scanCode; // Specifies a hardware scan code for the key. 
    public int flags;  // Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
    public int time; // Specifies the time stamp for this message.
    public int dwExtraInfo; // Specifies extra information associated with the message. 
    }
    //Import for SetWindowsHookEx function.
    //Use this function to install a hook.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, 
    IntPtr hInstance, int threadId); //Import for UnhookWindowsHookEx.
    //Call this function to uninstall the hook.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(int idHook);

    //Import for CallNextHookEx.
    //Use this function to pass the hook information to next hook procedure in chain.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern int CallNextHookEx(int idHook, int nCode, 
    Int32 wParam, IntPtr lParam);   public void Start()
    {
    // install Mouse hook 

    /* if(hMouseHook == 0)
    {
    // Create an instance of HookProc.
    MouseHookProcedure = new HookProc(MouseHookProc); hMouseHook = SetWindowsHookEx( WH_MOUSE_LL,
    MouseHookProcedure, 
    Marshal.GetHINSTANCE(
    Assembly.GetExecutingAssembly().GetModules()[0]),
    0); //If SetWindowsHookEx fails.
    if(hMouseHook == 0 )
    {
    Stop();
    throw new Exception("SetWindowsHookEx failed.");
    }
    }
    */
    // install Keyboard hook 

    if(hKeyboardHook == 0)
    {
    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
    hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,
    KeyboardHookProcedure, 
    Marshal.GetHINSTANCE(
    Assembly.GetExecutingAssembly().GetModules()[0]),
    0); //If SetWindowsHookEx fails.
    if(hKeyboardHook == 0 )
    {
    Stop();
    throw new Exception("SetWindowsHookEx ist failed.");
    }
    }
    }
      

  13.   

    public void Stop()
    {
    // bool retMouse =true;
    bool retKeyboard = true;
    /* if(hMouseHook != 0)
    {
    retMouse = UnhookWindowsHookEx(hMouseHook);
    hMouseHook = 0;

    */
    if(hKeyboardHook != 0)
    {
    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
    hKeyboardHook = 0;


    //If UnhookWindowsHookEx fails.
    // if (!(retMouse && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
    if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");//add
    } private const int WM_MOUSEMOVE = 0x200;
    private const int WM_LBUTTONDOWN = 0x201;
    private const int WM_RBUTTONDOWN = 0x204;
    private const int WM_MBUTTONDOWN = 0x207;
    private const int WM_LBUTTONUP = 0x202;
    private const int WM_RBUTTONUP = 0x205;
    private const int WM_MBUTTONUP = 0x208;
    private const int WM_LBUTTONDBLCLK = 0x203;
    private const int WM_RBUTTONDBLCLK = 0x206;
    private const int WM_MBUTTONDBLCLK = 0x209; /* private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
    {
    // if ok and someone listens to our events
    if ((nCode >= 0) && (OnMouseActivity!=null)) 
    {

    MouseButtons button=MouseButtons.None;
    switch (wParam)
    {
    case WM_LBUTTONDOWN: 
    //case WM_LBUTTONUP: 
    //case WM_LBUTTONDBLCLK: 
    button=MouseButtons.Left; 
    break;
    case WM_RBUTTONDOWN: 
    //case WM_RBUTTONUP: 
    //case WM_RBUTTONDBLCLK: 
    button=MouseButtons.Right; 
    break;
    }
    int clickCount=0;
    if (button!=MouseButtons.None)
    if (wParam==WM_LBUTTONDBLCLK || wParam==WM_RBUTTONDBLCLK) clickCount=2;
    else clickCount=1;

    //Marshall the data from callback.
    MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
    MouseEventArgs e=new MouseEventArgs(
    button, 
    clickCount, 
    MyMouseHookStruct.pt.x, 
    MyMouseHookStruct.pt.y, 
    0 );
    OnMouseActivity(this, e);
    }
    return CallNextHookEx(hMouseHook, nCode, wParam, lParam); 
    }
    */
    //The ToAscii function translates the specified virtual-key code and keyboard state to the corresponding character or characters. The function translates the code using the input language and physical keyboard layout identified by the keyboard layout handle.
    [DllImport("user32")] 
    public static extern int ToAscii(int uVirtKey, //[in] Specifies the virtual-key code to be translated. 
    int uScanCode, // [in] Specifies the hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed). 
    byte[] lpbKeyState, // [in] Pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of one key. If the high-order bit of a byte is set, the key is down (pressed). The low bit, if set, indicates that the key is toggled on. In this function, only the toggle bit of the CAPS LOCK key is relevant. The toggle state of the NUM LOCK and SCROLL LOCK keys is ignored.
    byte[] lpwTransKey, // [out] Pointer to the buffer that receives the translated character or characters. 
    int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.  //The GetKeyboardState function copies the status of the 256 virtual keys to the specified buffer. 
    [DllImport("user32")] 
    public static extern int GetKeyboardState(byte[] pbKeyState); private const int WM_KEYDOWN  = 0x100;
    private const int WM_KEYUP  = 0x101;
    private const int WM_SYSKEYDOWN  = 0x104;
    private const int WM_SYSKEYUP  = 0x105;

    private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
    {
    // it was ok and someone listens to events
    if ((nCode >= 0) && (KeyDown!=null || KeyUp!=null || KeyPress!=null))
    {
    KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
    //raise KeyDown
    if ( KeyDown!=null && ( wParam ==WM_KEYDOWN || wParam==WM_SYSKEYDOWN ))
    {
    Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
    KeyEventArgs e = new KeyEventArgs(keyData);
    KeyDown(this, e);
    }


    // raise KeyPress
     
    if ( KeyPress!=null &&  wParam ==WM_KEYDOWN )
    {
    byte[] keyState = new byte[256];
    GetKeyboardState(keyState); byte[] inBuffer= new byte[2];
    if (ToAscii(MyKeyboardHookStruct.vkCode,
    MyKeyboardHookStruct.scanCode,
    keyState,
    inBuffer,
    MyKeyboardHookStruct.flags)==1) 
    {
    KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
    KeyPress(this, e);
    }
    }


     //raise KeyUp
    if ( KeyUp!=null && ( wParam ==WM_KEYUP || wParam==WM_SYSKEYUP ))
    {
    Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
    KeyEventArgs e = new KeyEventArgs(keyData);
    KeyUp(this, e);
    } }
    return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); 
    }
    }
    }
      

  14.   

    锁住键盘倒是自己就能做,但是锁住键盘后想让自己的程序模拟键盘,而自己程序中的键盘消息不希望被锁住。
    我的想法是设置一个全局变量来判断是否为本应用程序发的消息,如果是就将消息传递下去,否则将消息拦截!
    但是好像不大好使,不知道为什么。
    还有就是我的程序中使用了Thread.Sleep(5000)后就好像锁不住键盘鼠标了!真是奇怪了!!!!

     truelove7283159(大头娃娃) 大哥说的方法能不能详细一点,给点资料 
       
     
      

  15.   

    truelove7283159(大头娃娃) 大哥说的方法真的是很好用啊。
    我用钩子写了一大堆封装,结果以为封装的很好了,但是一旦遇到线程操作就出问题了,还不知道什么原因。
    一用truelove7283159(大头娃娃) 大哥说的方法那真是太好使了,两句话就搞定了!
    ^_^
    哈哈!
    今天真啊真高兴啊!
      

  16.   

    我用钩子锁住了键盘鼠标,但是用到多线程中就锁不住了,不知道是什么原因。
    但是用钩子锁的比用BlockInput锁的死,即使用Ctrl+Del+Alt键也不能解锁,但是Ctrl+Del+Alt键可以解锁BlockInput。这既是BlockInput的缺点也是BlockInput的优点所在!而且BlockInput锁不住我模拟的键盘鼠标消息,真是一步到位!太TM爽了!
      

  17.   

    TO:star0796(star0796) 
    所以跟你说了,Ctrl+Del+Alt键要重写MSGINA.DLL.网上的列子太多。 
    我就不多写了.
    组合在一起,可以起到你要的效果.
    阻止系统的按键输入,但是不阻止自己的系统消息,事件.
    钩子,全局钩子对全局有效.要是你的钩子不是全局的,可能效果有些不好.