• ベストアンサー

C#でテンキーの操作は可能でしょうか?

みなさま、いつも参考にさせていただいております。 今回はちょっと行きづまってしまいましたのでご存知の方、よろしくお願いいたします。 早速ですが、当方開発環境はVisualStudio2008にて行っております。 具体的にはテンキーのキーを操作するwindowsアプリを作成しているのですが、 テンキーを操作する事ができません。 NumLockがOFFの時にテンキーの2・4・6・8の矢印を操作したいのですが、 どうしても操作ができません。 NumLockがOFFの時に、テンキーの2・4・6・8を押したときどんな反応がでるかと、 KeyPressにて見ようと思ったのですが、イベントすら発動しませんでした。 これは操作できないと言うことなのでしょうか? どなたかご存知の方ご享受くださいませ。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

 こんばんは。補足頂きました。  当方はDirectInputで入力するのはチョッと経験がないので、分からないのですが、keybd_event()APIを使用すれば、簡単に出来ます。  http://msdn.microsoft.com/ja-jp/library/cc364822.aspx  本当はSendInput()APIを推奨しているのですが、今回はkeybd_event()APIの方で割愛させて頂きます。  http://msdn.microsoft.com/ja-jp/library/cc411004.aspx using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX.DirectInput; using DirectInput = Microsoft.DirectX.DirectInput; namespace WindowsFormsApplication2 { public partial class Form1 : Form { const int VK_NUMLOCK = 0x90; const int VK_NUMPAD2 = 0x62; const int VK_NUMPAD4 = 0x64; const int VK_NUMPAD6 = 0x66; const int VK_NUMPAD8 = 0x68; const int EVENT_KEYBOARD = 0; const int EVENT_EXIT = 1; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool GetKeyboardState(byte [] lpKeyState); //此れを追加 [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern uint keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); delegate void KeyboardDeleggate(); KeyboardDeleggate kbDelegate; System.Threading.Thread thread; Device directInput; System.Threading.WaitHandle[] handles = new System.Threading.WaitHandle[2]; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.handles[EVENT_KEYBOARD] = new System.Threading.AutoResetEvent(false); this.handles[EVENT_EXIT] = new System.Threading.AutoResetEvent(false); this.directInput = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard); this.directInput.SetEventNotification(handles[EVENT_KEYBOARD]); this.directInput.Acquire(); this.kbDelegate = new KeyboardDeleggate(this.CheckKeyboard); this.thread = new System.Threading.Thread(this.KeyboardProc); this.thread.Start(); } public void CheckKeyboard() { byte[] bufKeyState = new byte[256]; GetKeyboardState(bufKeyState); if (bufKeyState[VK_NUMLOCK] != 0) return; KeyboardState keyState = directInput.GetCurrentKeyboardState(); if (keyState[DirectInput.Key.NumPad2]) { //押した keybd_event(VK_NUMPAD2, 0, 0, (UIntPtr)0); //離した keybd_event(VK_NUMPAD2, 0, 2, (UIntPtr)0); } if (keyState[DirectInput.Key.NumPad4]) { keybd_event(VK_NUMPAD4, 0, 0, (UIntPtr)0); keybd_event(VK_NUMPAD4, 0, 2, (UIntPtr)0); } if (keyState[DirectInput.Key.NumPad6]) { keybd_event(VK_NUMPAD6, 0, 0, (UIntPtr)0); keybd_event(VK_NUMPAD6, 0, 2, (UIntPtr)0); } if (keyState[DirectInput.Key.NumPad8]) { keybd_event(VK_NUMPAD8, 0, 0, (UIntPtr)0); keybd_event(VK_NUMPAD8, 0, 2, (UIntPtr)0); } } public void KeyboardProc() { bool bLoop = true; while (bLoop) { int result = System.Threading.WaitHandle.WaitAny(handles, 200, false); switch (result) { case EVENT_KEYBOARD: Invoke(kbDelegate); break; case EVENT_EXIT: bLoop = false; break; case System.Threading.WaitHandle.WaitTimeout: break; } } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { System.Threading.AutoResetEvent exitEvent = this.handles[EVENT_EXIT] as System.Threading.AutoResetEvent; exitEvent.Set(); this.thread.Join(); } private void Form1_KeyPress(object sender, KeyPressEventArgs e) { //ココに来るはず MessageBox.Show(e.KeyChar.ToString()); } } }

neo_ts
質問者

お礼

おぉぉ!! できました!!! 大変参考になりました。 直接コードをいただいてしまって大変恐縮ですm(__)m ありがとうございました♪

その他の回答 (3)

回答No.3

 こんばんは。  DirectXのDirectInputを使用すれば可能です。DirectXの導入については以下を参照。  http://www.clks.jp/csg/dx002.html  以下はNUMLOCKがOFFの時だけ2,4,6,8を検出してメッセージボックスを表示します。改善の余地もあるかとは思いますが、参考程度に。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX.DirectInput; using DirectInput = Microsoft.DirectX.DirectInput; namespace WindowsFormsApplication1 { public partial class Form1 : Form { const int VK_NUMLOCK = 0x90; const int EVENT_KEYBOARD = 0; const int EVENT_EXIT = 1; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool GetKeyboardState(byte [] lpKeyState); delegate void KeyboardDeleggate(); KeyboardDeleggate kbDelegate; System.Threading.Thread thread; Device directInput; System.Threading.WaitHandle[] handles = new System.Threading.WaitHandle[2]; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //イベントの作成 this.handles[EVENT_KEYBOARD] = new System.Threading.AutoResetEvent(false); this.handles[EVENT_EXIT] = new System.Threading.AutoResetEvent(false); //DirectInputの作成 this.directInput = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard); this.directInput.SetEventNotification(handles[EVENT_KEYBOARD]); this.directInput.Acquire(); //デリゲートの作成 this.kbDelegate = new KeyboardDeleggate(this.CheckKeyboard); //スレッドを回す this.thread = new System.Threading.Thread(this.KeyboardProc); this.thread.Start(); } public void CheckKeyboard() { //NUMLOCKの状態を確認 byte[] bufKeyState = new byte[256]; GetKeyboardState(bufKeyState); //NUMLOCKがONなので引き返す if (bufKeyState[VK_NUMLOCK] != 0) return; //DirectInputで2,4,6,8キーを検出 KeyboardState keyState = directInput.GetCurrentKeyboardState(); if (keyState[DirectInput.Key.NumPad2]) { MessageBox.Show("2"); } if (keyState[DirectInput.Key.NumPad4]) { MessageBox.Show("4"); } if (keyState[DirectInput.Key.NumPad6]) { MessageBox.Show("6"); } if (keyState[DirectInput.Key.NumPad8]) { MessageBox.Show("8"); } } public void KeyboardProc() { //200ミリ秒でイベント待ち bool bLoop = true; while (bLoop) { int result = System.Threading.WaitHandle.WaitAny(handles, 200, false); switch (result) { //キー入力があった case EVENT_KEYBOARD: Invoke(kbDelegate); break; //スレッドを終了しろと言われた case EVENT_EXIT: bLoop = false; break; //タイムアウトした case System.Threading.WaitHandle.WaitTimeout: break; } } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //スレッドを止める為のイベントをシグナル化 System.Threading.AutoResetEvent exitEvent = this.handles[EVENT_EXIT] as System.Threading.AutoResetEvent; exitEvent.Set(); this.thread.Join(); } } }

neo_ts
質問者

補足

machongola 様 びっくりしました! 参考コードまで載せていただき、大変参考になりました。 ありがとうございます。 一点、お聞きしたいのですが、上記コードでNumLockがOFFの時に DirectXを用いて2・4・6・8をプッシュするにはどの様なコードが あるのでしょうか? よろしくお願いいたします。

  • S-Fuji
  • ベストアンサー率36% (592/1624)
回答No.2

ですから、NumLockキーがOFFの時、2,4,6,8は矢印キーとして扱われます。 なので、KeyPressでは検知出来ません。

  • S-Fuji
  • ベストアンサー率36% (592/1624)
回答No.1

KeyPressでは、矢印キー等を検知する事は出来ません。 以下を参考にどうぞ。 http://dobon.net/vb/dotnet/control/btndetectarraykey.html

参考URL:
http://dobon.net/vb/dotnet/control/btndetectarraykey.html
neo_ts
質問者

補足

早々のご回答ありがとうございます。 大変に参考になったのですが、主旨として、やりたい事は、 NumLockがOFFの時にテンキーの2・4・6・8の矢印をDownしたいのです。 可能なのでしょうか? よろしく願致します。

関連するQ&A