試試這個,
private KeyboardFilter kbFilter;
private void MainForm_Activated(object sender, EventArgs e)
{
kbFilter = new KeyboardFilter(new Keys[]
{
Keys.LWin | Keys.D,
Keys.RWin | Keys.D,
Keys.LWin | Keys.X, // if you need
Keys.RWin | Keys.X, // if you need
Keys.Alt | Keys.F4 // if you need
});
}
private void MainForm_Deactivate(object sender, EventArgs e)
{
kbFilter.Dispose();
}
務必在MainForm_Deactivate
事件使用KeyboardFilter.Dispose()
。
KeyboardFilter
類是從Here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.ComponentModel;
class KeyboardFilter : IDisposable
{
private Keys[] mFilter;
private IntPtr mHook;
private readonly LowLevelKeyboardProc mProc;
public KeyboardFilter(Keys[] keysToFilter)
{
// Install hook
mFilter = keysToFilter;
ProcessModule mod = Process.GetCurrentProcess().MainModule;
mProc = KeyboardProc; // Avoid garbage collector problems
mHook = SetWindowsHookEx(13, mProc, GetModuleHandle(mod.ModuleName), 0);
if (mHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to set hook");
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Release hook
if (mHook != IntPtr.Zero)
{
UnhookWindowsHookEx(mHook);
mHook = IntPtr.Zero;
}
}
}
~KeyboardFilter()
{
Dispose(false);
}
private IntPtr KeyboardProc(int nCode, IntPtr wp, IntPtr lp)
{
// Callback, filter key
if (nCode >= 0)
{
KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
foreach (Keys key in mFilter)
if ((key & Keys.KeyCode) == info.key && CheckModifier(key)) return (IntPtr)1;
}
return CallNextHookEx(mHook, nCode, wp, lp);
}
private static bool CheckModifier(Keys key)
{
// Check if modifier key in required state
if ((key & Keys.Control) == Keys.Control &&
GetAsyncKeyState(Keys.LControlKey) == 0 && GetAsyncKeyState(Keys.RControlKey) == 0) return false;
if ((key & Keys.Shift) == Keys.Shift &&
GetAsyncKeyState(Keys.LShiftKey) == 0 && GetAsyncKeyState(Keys.RShiftKey) == 0) return false;
if ((key & Keys.Alt) == Keys.Alt &&
GetAsyncKeyState(Keys.LMenu) == 0 && GetAsyncKeyState(Keys.RMenu) == 0) return false;
return true;
}
// P/Invoke declarations
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern short GetAsyncKeyState(Keys key);
}
c#wpf
謝謝IDisposable。我嘗試了類似的東西,但我不確定如何在InitialiseComponents();之後調用SendWpfWindowBack方法。你能建議嗎? –
執行此操作:'SendWpfWindowBack(this);'在InitialiseComponents() – ViVi
我仍然可以使用Windows Key + D將它完全減至最小。第一次運行時,它不會直接返回。 (通過Visual Studio顯示)。有任何想法嗎? –