Lock keyboard and mouse or prevent user leaving window in C #

5

I'm developing a lan-house style locking screen where the user does not leave the screen without the permission of the server, I wonder if it has a way to prevent the user from using the keyboard and > mouse or it leaves the Form open (example ALT + TAB ), , but it only works with Administrator privileges, and for me it is not possible to open the application in this mode.

Obs : I have already been able to block the screen closing via ALT + F4 , and I have already been able to prevent the user from opening the tasks.

Thanks for the help.

    
asked by anonymous 24.02.2015 / 22:51

1 answer

7

You can use the BlockInput , you will block the use of the keyboard and mouse .

using System.Runtime.InteropServices;

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern void BlockInput([In, MarshalAs(UnmanagedType.Bool)]bool fBlockIt);

private void button1_Click(object sender, EventArgs e){
    BlockInput(true); 
}

Example taken from CodeProject .

But to use it, you must have privileges (from Windows Vista), create a manifest file and change the element requestedExecutionLevel to:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

When you run the program, the UAC window will appear to confirm the execution of the program with privileges.

Example of a manifest file:

<?xml version="1.0" encoding="utf-8" ?> 
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 
    xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
    xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <assemblyIdentity version="1.0.0.0" name="MyApplication" />
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                 <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
</asmv1:assembly>

Alternative

An alternative is to use Hooks to intercept the events of the mouse and keyboard and manipulate the operation of these.

The articles below explain the use of Hooks in C #.

Below are examples of how to undo the operation of the mouse and keyboard.

Mouse

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

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }
        // Importa as funções que serão usadas
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        [DllImport("user32.dll")]
        static extern IntPtr CallNextHookEx(IntPtr idHook, int code, int wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        private delegate IntPtr LowLevelMouseProc(int code, IntPtr wParam, IntPtr lParam);

        private enum MouseMessages{
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_MOUSEMOVE = 0x0200,
            WM_MOUSEWHEEL = 0x020A,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205
        }

        const int WH_MOUSE_LL = 14; // Tipo de hook que será usado

        private LowLevelMouseProc hook = hookProc;
        private static IntPtr hhook = IntPtr.Zero;

        public void SetHook(){
            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_MOUSE_LL, hook, hInstance, 0); // Instala o hook para a interceptação dos eventos do mouse
        }

        public static void UnHook(){
            UnhookWindowsHookEx(hhook); // Remove o hook instalado
        }

        public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam){
            // Se a mensagem recebida for > 0 e o clique do mouse for do botão esquerdo ou direito
            if (code >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam || MouseMessages.WM_RBUTTONDOWN == (MouseMessages)wParam)
            {
                return (IntPtr)1; // Inibe o clique
            }
            else
                return CallNextHookEx(hhook, code, (int)wParam, lParam); // Passa para o próximo evento
        }

        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e){
            UnHook(); // Ao fechar o form desintalamos o hook
        }

        private void Form1_Load(object sender, EventArgs e){
            SetHook(); // Ao iniciar instala o hook 
        }
    }
}

In the example above, the callback LowLevelMouseProc ", the system calls this function each time a new mouse-related event is to be released in

  • , when intercepted, we return a result different than expected.

    Keyboard

    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
            }
            // Importa as funções que serão usadas
            [DllImport("user32.dll")]
            static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);
    
            [DllImport("user32.dll")]
            static extern bool UnhookWindowsHookEx(IntPtr hInstance);
    
            [DllImport("user32.dll")]
            static extern IntPtr CallNextHookEx(IntPtr idHook, int code, int wParam, IntPtr lParam);
    
            [DllImport("kernel32.dll")]
            static extern IntPtr LoadLibrary(string lpFileName);
    
            private delegate IntPtr LowLevelKeyboardProc(int code, IntPtr wParam, IntPtr lParam);
    
            const int WH_KEYBOARD_LL = 13; // Tipo de hook que será usado
            const int WM_KEYDOWN = 0x100;  // Messagem usada para quando uma tecla for pressionada
    
            private LowLevelKeyboardProc hook = hookProc;
            private static IntPtr hhook = IntPtr.Zero;
    
            public void SetHook(){
                IntPtr hInstance = LoadLibrary("User32");
                hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hook, hInstance, 0); // Instala o hook para o teclado
            }
    
            public static void UnHook(){
                UnhookWindowsHookEx(hhook);
            }
    
            public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam){
                if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN){ // Quando uma tecla for pressionada
                    return (IntPtr)1; // Inibe o funcionamento
                }
                else
                    return CallNextHookEx(hhook, code, (int)wParam, lParam); // Passa para o próximo evento
            }
    
            private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                UnHook(); // Ao fechar o form desintala o hook
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                SetHook(); // Ao iniciar instala o hook
            }
        }
    }
    

    The above example is not valid for combinations of special system keys as < kbd> CTRL + Alt + DEL . Here the callback is used LowLevelKeyboardProc , it is called every time a new a new keyboard input event is about to be placed in the message queue , when intercepting it we can know which key is being typed, return another return key, or cancel it.

    It is important to always uninstall the hook after use with the UnhookWindowsHookEx .

        
  • 24.02.2015 / 23:04