Degeim Skrevet 13. juni 2009 Del Skrevet 13. juni 2009 (endret) 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 13. juni 2009 av Degeim Lenke til kommentar
aC Skrevet 16. juni 2009 Del Skrevet 16. juni 2009 (endret) 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 16. juni 2009 av aC Lenke til kommentar
GeirGrusom Skrevet 16. juni 2009 Del Skrevet 16. juni 2009 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 Lenke til kommentar
Degeim Skrevet 16. juni 2009 Forfatter Del Skrevet 16. juni 2009 Ja, konstantene fikser jeg. Skal forsøke senere i dag. Mange takk! Lenke til kommentar
Largie Skrevet 16. juni 2009 Del Skrevet 16. juni 2009 (endret) 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 16. juni 2009 av Largie Lenke til kommentar
Degeim Skrevet 16. juni 2009 Forfatter Del Skrevet 16. juni 2009 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
Kris Skrevet 16. juni 2009 Del Skrevet 16. juni 2009 Kan jeg få se hvordan den ble? Har lett etter noe lignende selv. Lenke til kommentar
Degeim Skrevet 16. juni 2009 Forfatter Del Skrevet 16. juni 2009 Ja, naturligvis. Er på en annen maskin nå, men kan poste den i morgen. Lenke til kommentar
Degeim Skrevet 17. juni 2009 Forfatter Del Skrevet 17. juni 2009 (endret) 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 17. juni 2009 av Degeim Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå