2017-08-19 36 views
0

背景:私はHoloLensのUnityを使用して作業しようとしているキーボードスキャンコード(EnumからKeyCodesではない)を必要とするライブラリを持っています。ユニバーサルWindowsプラットフォームで動作するようにWH_KEYBOARD_LLを取得する方法

私がこれまでに発見したのC#からのスキャンコードを取得する唯一の方法は、SetWindowsHookEx

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

ドキュメントhttps://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx

提案方法によってWH_KEYBOARD_LLためのフックを登録することでのPInvokeて、Windowsのフックシステムを使用することですこのように呼び出すことです。

IntPtr hHook; 

using (Process process = Process.GetCurrentProcess()) 
using (ProcessModule module = process.MainModule) 
{ 
    IntPtr hModule = GetModuleHandle(module.ModuleName); 

    hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, hook, hModule, 0); 
} 

http://www.pinvoke.net/default.aspx/user32.setwindowshookexを参照してください。

このビルドをPC上でうまく動作しますが、SetWindowsHookExのドキュメントでUWPのための備考が私を混乱さ:

Windowsストアアプリの開発をのdwThreadIdがゼロの場合は、ウィンドウのフック DLLがインをロードされませんWindowsストアのAppプロセス用のプロセスと、 UIAccessプロセス(アクセシビリティツール)のいずれかによってインストールされていない限り、Windowsランタイムブローカープロセス をインストールする必要があります。ときこの動作は、フックDLLとターゲット アプリケーションプロセス間のアーキテクチャの不一致があるとき 例えば、何が起こるかに似ている WH_JOURNALPLAYBACK WH_JOURNALRECORD WH_KEYBOARD WH_KEYBOARD_LL WH_MOUSE WH_MOUSE_LL:通知は これらのフックのためのインストーラのスレッドに配信されますフックDLLは32ビットで、 アプリケーションは64ビットを処理します。

UWPでdwThreadIdを指定する必要があります。それ以外の場合は動作しません。

ERROR_GLOBAL_ONLY_HOOK 
1429 (0x595) 
This hook procedure can only be set globally. 

が有効hookID作成しますが、再び何のイベントが到着しないNULLにGetModuleHandle(NULL)dwThreadIdからhModの設定:私は(再びのPInvoke経由)GetCurrentThreadId()を使用しない場合でも、私は、エラーコードを取得します。

は、それ以来、私は、モジュールのハンドルを取得する方法を探してみましたが、UWPに取り組んでいますどのような方法を見つけられませんでした:

  • Process.GetCurrentProcessはコンパイルされません、
  • GetType().Module.Nameを逃す
  • Marshal.GetHINSTANCEを逃します紛失(GetModuleHandle

他に何を試すことができますか?

答えて

0

C言語のスキャンコードを取得する唯一の方法は、SetWindowsHookExを使用してWH_KEYBOARD_LLのフックを登録することにより、Windows HookシステムをPInvokeで使用することです。

残念ながら、あなたが言及した解決策は、UWPには適用されません。あなたの要件のためにはAcceleratorKeyActivatedeventを、AcceleratorKeyEventArgsにはScanCodeの値を直接指定できます。

public MainPage() 
{ 
    this.InitializeComponent(); 
    Window.Current.Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated; 
} 

private void Dispatcher_AcceleratorKeyActivated(Windows.UI.Core.CoreDispatcher sender, Windows.UI.Core.AcceleratorKeyEventArgs args) 
{ 
    var scanCode = args.KeyStatus.ScanCode; 
} 
関連する問題