プロが教える店舗&オフィスのセキュリティ対策術

みなさま、いつも参考にさせていただいております。
今回はちょっと行きづまってしまいましたのでご存知の方、よろしくお願いいたします。

早速ですが、当方開発環境はVisualStudio2008にて行っております。
具体的にはテンキーのキーを操作するwindowsアプリを作成しているのですが、
テンキーを操作する事ができません。
NumLockがOFFの時にテンキーの2・4・6・8の矢印を操作したいのですが、
どうしても操作ができません。
NumLockがOFFの時に、テンキーの2・4・6・8を押したときどんな反応がでるかと、
KeyPressにて見ようと思ったのですが、イベントすら発動しませんでした。

これは操作できないと言うことなのでしょうか?
どなたかご存知の方ご享受くださいませ。

A 回答 (4件)

 こんばんは。

補足頂きました。

 当方はDirectInputで入力するのはチョッと経験がないので、分からないのですが、keybd_event()APIを使用すれば、簡単に出来ます。
 http://msdn.microsoft.com/ja-jp/library/cc364822 …

 本当はSendInput()APIを推奨しているのですが、今回はkeybd_event()APIの方で割愛させて頂きます。
 http://msdn.microsoft.com/ja-jp/library/cc411004 …

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());
}
}
}
    • good
    • 0
この回答へのお礼

おぉぉ!!
できました!!!

大変参考になりました。
直接コードをいただいてしまって大変恐縮ですm(__)m

ありがとうございました♪

お礼日時:2010/01/19 18:21

 こんばんは。


 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();
}
}
}

この回答への補足

machongola 様

びっくりしました!
参考コードまで載せていただき、大変参考になりました。
ありがとうございます。

一点、お聞きしたいのですが、上記コードでNumLockがOFFの時に
DirectXを用いて2・4・6・8をプッシュするにはどの様なコードが
あるのでしょうか?

よろしくお願いいたします。

補足日時:2010/01/19 11:10
    • good
    • 0

ですから、NumLockキーがOFFの時、2,4,6,8は矢印キーとして扱われます。


なので、KeyPressでは検知出来ません。
    • good
    • 0

KeyPressでは、矢印キー等を検知する事は出来ません。


以下を参考にどうぞ。
http://dobon.net/vb/dotnet/control/btndetectarra …

参考URL:http://dobon.net/vb/dotnet/control/btndetectarra …

この回答への補足

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

可能なのでしょうか?
よろしく願致します。

補足日時:2010/01/18 13:39
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!