WPF does not register to these messages on the applications MainWindow, but through a hidden windows named “SystemResources…” which is created for each application instance. So handling those messages on the MainWindow (which would be easy) does not help here.
public classWPFTouchUtil { //添加钩子,阻断设备改动消息 public staticvoid HandleDeviceChangedWM() { // hook into internal class SystemResources to keep it from updating the TabletDevices on system events object hwndWrapper = GetSystemResourcesHwnd(); if (hwndWrapper != null) { // invoke hwndWrapper.AddHook( .. our method ..) var internalHwndWrapperType = hwndWrapper.GetType(); // if the delegate is already set, we have already added the hook. if (_handleAndHideMessageDelegate == null) { // create the internal delegate that will hook into the window messages // need to hold a reference to that one, because internally the delegate is stored through a WeakReference object var internalHwndWrapperHookDelegate = internalHwndWrapperType.Assembly.GetType("MS.Win32.HwndWrapperHook"); var handleAndHideMessagesHandle = typeof(WPFTouchUtil).GetMethod(nameof(HandleAndHideMessages), BindingFlags.Static | BindingFlags.NonPublic); _handleAndHideMessageDelegate = Delegate.CreateDelegate(internalHwndWrapperHookDelegate, handleAndHideMessagesHandle); // add a delegate that handles WM_TABLET_ADD internalHwndWrapperType.InvokeMember("AddHook", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, hwndWrapper, new object[] { _handleAndHideMessageDelegate }); } } }
//移除钩子,恢复状态 public staticvoid RestoreDeviceChangedWM() { object hwndWrapper = GetSystemResourcesHwnd(); if (hwndWrapper != null) { var internalHwndWrapperType = hwndWrapper.GetType();