Gå til innhold

C#: Deaktivere Windows-knappen på tastaturet


Anbefalte innlegg

Hoi

 

Jeg må sørge for at brukeren av programmet mitt ikke kan bruker Windows-knappen (han må ikke kunne trykke Windows-Tab i Vista og få opp oppgaveskifteren).

 

Etter en del søking har jeg funnet følgende kode, men sliter med å få det til å fungere i C#:

 

LRESULT CALLBACK WinKeyHook(int code,WPARAM wparam,LPARAM lparam)
	{
		auto PKBDLLHOOKSTRUCT key=(PKBDLLHOOKSTRUCT)lparam;

		switch(wparam)
		{
			case(WM_KEYDOWN):
			case(WM_SYSKEYDOWN):
				if((key->vkCode==VK_LWIN)||(key->vkCode==VK_RWIN))
					return TRUE;

			case(WM_KEYUP):
			case(WM_SYSKEYUP):
				if((key->vkCode==VK_LWIN)||(key->vkCode==VK_RWIN))
					return TRUE;
		}

		return CallNextHookEx(0,code,wparam,lparam);
	}

	INT WINAPI WinMain (HINSTANCE inst,HINSTANCE prev,LPSTR cmdl,INT show)
	{
		HHOOK hook;

		hook=SetWindowsHookEx(WH_KEYBOARD_LL,WinKeyHook,inst,0);

		if(!hook)
		{
			MessageBox(NULL,TEXT("Could not create hook"),TEXT("Hook-Error"),MB_ICONERROR);
			return 0;
		}
	}

 

Jeg vet veldig lite om behandling av APIer, så er det noen som har alternative forslag til deaktivering av windows-knappen, eller kan hjelpe meg å få det der til å fungere i C#?

 

Mvh,

Degeim

Endret av Degeim
Lenke til kommentar
Videoannonse
Annonse

det er C ikke C#, men det var du kanskje klar over. får kompilert med

 

cl main.c /link user32.lib

 

PS. når det kommer til å gjøre det om til c# så er nok kanskje GeirGrusom behjelpelig med dette (da han er særlig glad i vise frem alle de fine sidene med c#)

Endret av aC
Lenke til kommentar

Tror han er ute etter P/Invokes og slikt, altså få oversatt C til C#.

 

Det er litt mye til at jeg gidder å kikke opp alt sammen, men her er en kjapp cheat sheet for datatypene i det minste:

 

HHOOK = IntPtr
LRESULT = int
WPARAM = IntPtr
LPARAM = IntPtr
INT = int

public delegate int WinKeyHookDelegate(int code, IntPtr wParam, IntPtr lParam);

[DllImport("User32")]
public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("User32")]
public static extern IntPtr SetWindowsHookEx(int idHook, WindowKeyHookDelegate lpfn, IntPtr hMod, int dwThreadId);

public enum HookFlags
{
 LLKHF_EXTENDED = 0,
 LLKHF_INJECTED = 4,
 LLKHF_ALTDOWN = 5
 LLKHF_UP = 6
}

public struct KBDLLHOOKSTRUCT 
{
int vkCode;
int scanCode;
HookFlags flags;
int time;
IntPtr dwExtraInfo;
}

 

Det tar lang tid å sjekke opp verdiene til konstanter, så det kan du nesten gjøre selv :p

Lenke til kommentar

Du trenger en standard keyboard hook som mange andre har lagd før deg :)

http://www.codeproject.com/KB/system/globa...eyboardlib.aspx

http://www.codeproject.com/KB/system/CSLLKeyboard.aspx

http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx

http://www.codeproject.com/KB/cs/globalhook.aspx

 

Sparer mye tid på og implementere allerede ferdig løsninger ;)

 

Edit: Merk at man KAN beskytte seg mot global hooks, derfor er det ikke garantert at det virker på alle maskiner (bla paranoide virusprogrammer har dette). Men hvis du skal lage en kiosk sak eller lignende der du har kontroll på alle ledd så er det ingen problem...

Endret av Largie
Lenke til kommentar

Mange takk for alle svar!

 

Det viste seg at en keyboard hook var akkurat det jeg trengte, så jeg fikk takket være eksemplene til Largie satt sammen en minimalistisk en som kun blokkerer Windows-tasten (og Ctrl+Esc) og Alt-Tab.

Lenke til kommentar

Jeg puttet også inn støtte for å blokkere andre taster (constructoren med "BlockList" som parameter).

 

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;

public class KeyboardHook : IDisposable
{

	//Internal parameters
	private bool PassAllKeysToNextApp = false;
	private bool AllowAltTab = false;
	private bool AllowWindowsKey = false;

	//Keyboard API constants
	private const int WH_KEYBOARD_LL = 13;
	private const int WM_KEYUP = 0x0101;
	private const int WM_SYSKEYUP = 0x0105;

	//Modifier key constants
	private const int VK_SHIFT = 0x10;
	private const int VK_CONTROL = 0x11;
	private const int VK_MENU = 0x12;
	private const int VK_CAPITAL = 0x14;

	//Variables used in the call to SetWindowsHookEx
	private HookHandlerDelegate proc;
	private IntPtr hookID = IntPtr.Zero;
	internal delegate IntPtr HookHandlerDelegate(
		int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);

	//List that contains all keys to be blocked
	private List<int> BlockKeys;

	/// <summary>
	/// Event triggered when a keystroke is intercepted by the 
	/// low-level hook.
	/// </summary>
	public event KeyboardHookEventHandler KeyIntercepted;

	// Structure returned by the hook whenever a key is pressed
	internal struct KBDLLHOOKSTRUCT
	{
		public int vkCode;
		int scanCode;
		public int flags;
		int time;
		int dwExtraInfo;
	}

	#region Constructors
	/// <summary>
	/// Sets up a keyboard hook to trap all keystrokes without 
	/// passing any to other applications.
	/// </summary>
	public KeyboardHook()
	{
		proc = new HookHandlerDelegate(HookCallback);
		using (Process curProcess = Process.GetCurrentProcess())
		using (ProcessModule curModule = curProcess.MainModule)
		{
			hookID = NativeMethods.SetWindowsHookEx(WH_KEYBOARD_LL, proc,
				NativeMethods.GetModuleHandle(curModule.ModuleName), 0);
		}
	}

	public KeyboardHook(List<int> blockList)
		: this()
	{
		BlockKeys = blockList;
	}

	#endregion

	#region Hook Callback Method
	/// <summary>
	/// Processes the key event captured by the hook.
	/// </summary>
	private IntPtr HookCallback(
		int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
	{
		bool AllowKey = PassAllKeysToNextApp;

		if (BlockKeys != null)
			if (BlockKeys.Contains(lParam.vkCode))
				return (System.IntPtr)1;

		if (!AllowWindowsKey)
			if (IsWindowsKey(ref lParam))
				return (System.IntPtr)1;

		// Alt+Tab
		if (!AllowAltTab)
			if ((lParam.flags == 32) && (lParam.vkCode == 9))
				return (System.IntPtr)1;

		//Filter wParam for KeyUp events only
		if (nCode >= 0)
		{
			if (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)
			{

				// Check for key combinations that are allowed to 
				// get through to Windows
				//
				// Ctrl+Esc or Windows key
				if (AllowWindowsKey)
					if (IsWindowsKey(ref lParam))
						AllowKey = true;

				// Alt+Tab
				if ((lParam.flags == 32) && (lParam.vkCode == 9))
					AllowKey = true;

				OnKeyIntercepted(new KeyboardHookEventArgs(lParam.vkCode, AllowKey));
			}

			//If this key is being suppressed, return a dummy value
			if (AllowKey == false)
				return (System.IntPtr)1;
		}
		//Pass key to next application
		return NativeMethods.CallNextHookEx(hookID, nCode, wParam, ref lParam);

	}

	private bool IsWindowsKey(ref KBDLLHOOKSTRUCT lParam)
	{
		switch (lParam.flags)
		{
			//Ctrl+Esc
			case 0:
				if (lParam.vkCode == 27)
					return true;
				break;

			//Windows keys
			case 1:
				if ((lParam.vkCode == 91) || (lParam.vkCode == 92))
					return true;
				break;
		}

		return false;
	}
	#endregion

	#region Event Handling
	/// <summary>
	/// Raises the KeyIntercepted event.
	/// </summary>
	/// <param name="e">An instance of KeyboardHookEventArgs</param>
	public void OnKeyIntercepted(KeyboardHookEventArgs e)
	{
		if (KeyIntercepted != null)
			KeyIntercepted(e);
	}

	/// <summary>
	/// Delegate for KeyboardHook event handling.
	/// </summary>
	/// <param name="e">An instance of InterceptKeysEventArgs.</param>
	public delegate void KeyboardHookEventHandler(KeyboardHookEventArgs e);

	/// <summary>
	/// Event arguments for the KeyboardHook class's KeyIntercepted event.
	/// </summary>
	public class KeyboardHookEventArgs : System.EventArgs
	{

		private string keyName;
		private int keyCode;
		private bool passThrough;

		/// <summary>
		/// The name of the key that was pressed.
		/// </summary>
		public string KeyName
		{
			get { return keyName; }
		}

		/// <summary>
		/// The virtual key code of the key that was pressed.
		/// </summary>
		public int KeyCode
		{
			get { return keyCode; }
		}

		/// <summary>
		/// True if this key combination was passed to other applications,
		/// false if it was trapped.
		/// </summary>
		public bool PassThrough
		{
			get { return passThrough; }
		}

		public KeyboardHookEventArgs(int evtKeyCode, bool evtPassThrough)
		{
			keyName = ((Keys)evtKeyCode).ToString();
			keyCode = evtKeyCode;
			passThrough = evtPassThrough;
		}

	}

	#endregion

	#region IDisposable Members
	/// <summary>
	/// Releases the keyboard hook.
	/// </summary>
	public void Dispose()
	{
		NativeMethods.UnhookWindowsHookEx(hookID);
	}
	#endregion

	#region Native methods

	[ComVisibleAttribute(false),
	 System.Security.SuppressUnmanagedCodeSecurity()]
	internal class NativeMethods
	{
		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr GetModuleHandle(string lpModuleName);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr SetWindowsHookEx(int idHook,
			HookHandlerDelegate lpfn, IntPtr hMod, uint dwThreadId);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool UnhookWindowsHookEx(IntPtr hhk);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
			IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);

		[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
		public static extern short GetKeyState(int keyCode);

	}


	#endregion
}

 

Klassen er stort sett basert på dette: http://www.codeproject.com/KB/system/CSLLKeyboard.aspx

 

Jeg har bare fjernet noe av det jeg ikke trengte, og lagt inn litt jeg måtte ha med.

Endret av Degeim
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...