- 締切済み
DirectXのDIK発進について
初めまして、お世話になります。 C#カテゴリがなく、DirectX関係なのでこちらに投稿させて頂きます。 C#で作成したフォームからDIK_LEFTの発信等は可能でしょうか? 現在目標としているものは「SendInput・SendKeyやkeybd_eventではなく、生身の人間がキーボードの"←"を押した状態を作る」といったものです。 DirectXやDirectInputで検索をかけてみたりはしたのですが、入力されたキー情報の判定等のサイトが多く、目的のもの(キー発信)が見つからず途方にくれておりました。 もし可能であればその方法、またはサイト等を教えて頂きたいです。 よろしくお願いします。
- みんなの回答 (8)
- 専門家の回答
みんなの回答
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>私の実力では「C#でFormからのDirectXアプリへのキー入力」の壁は少し >厚かったようです。また、資料の多い言語で再び挑戦したいと思います! 技量不足というよりも「言語の選択を誤っただけ」でしょう。 ぶっちゃけ、DirectXでゲームを書いているプロは、滅多な事が無い限りC#なんか使いません。 C#は「小さな親切が余計なお世話になっていて、実行コードが肥大化する傾向にあり、しかも実行速度が遅い」ので、リアルタイム性が重視されるゲームには向きません。 C++であれば、多少コードを書く量が増えますが、その分「かゆい所に手が届く」ので、ゲーム作成に向いているのです。 今後もゲームを作成するつもりなら「早い段階でC#を捨てるべき」です。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>IntPtr wParam, lParam;//Param変数宣言 これ要らない。 >wParam = new IntPtr(0x38);//↑キーwParam値設定 >lParam = new IntPtr(0x01480001);//↑キーlParam値設定 >PostMessage(hwnd, 0x0100, wParam, lParam);//WM_KEYDOWN送信 は PostMessage(hwnd, WM_KEYDOWN, (WPARAM)VK_UP, (LPARAM)0x01480001);//WM_KEYDOWN送信 で良い。 >wParam = new IntPtr(0x38);//↑キーwParam値設定 >lParam = new IntPtr(0xc1480001);//↑キーlParam値設定 >PostMessage(hwnd, 0x0101, wParam, lParam);//WM_UP送信 も PostMessage(hwnd, WM_KEYUP, (WPARAM)VK_UP, (LPARAM)0xc1480001);//WM_KEYUP送信 で良い。 >lParam = new IntPtr(0xc1480001);//↑キーlParam値設定 >の部分で算術演算オーバーフロウが発生してしまいます。 当然。 IntPtrは「実行するまで、32ビットか64ビットか未確定」です。 で「実行時、32ビットと判ったら、-2147483648~2147483647の範囲の数値のみ受け付け、この範囲を超える数値はオーバーフロー」として例外を発生します。 0xc1480001は「3242721281」ですから、当然、実行すると「-2147483648~2147483647の範囲を超えているからオーバーフロー」です。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>VisualC++ 2008Express Editionの場合 >デバッグを実行したところ VC++2008ですね。VC++2008はちょっと「標準的じゃない部分」があるので、Win32でのAPIアプリを書く場合、設定変更をする(方法その1)か、VC++の方言に合わせる必要(方法その2)があります。 ●方法その1 1.[プロジェクト プロパティ] - [リンカ] - [詳細] - [エントリーポイント] を [WinMainCRTStartup] に設定する 2.[プロジェクト プロパティ] - [構成プロパティ] - [全般] - [文字セット] を [マルチバイト文字セットを使用する]に変更する 上記の設定と変更をしないと、メイン関数(プログラムが開始される関数)は int main(array<System::String ^> ^args) である事が期待されます。 また、文字セットがUNICODEのままだと、LPCSTRやLPSTRなどが要求される部分で「char *をLPCSTRに変換できない」などのエラーが出ます。 そのため、デフォルトの設定のままビルドを行うと「char *をLPCSTRに変換できないよ~」とか「mainが無いよ~」とかって怒られてしまいます。 VC++2008のデフォルトの設定(通常、Win32のフォームアプリケーションを作成する設定になっている)では、プログラムはWinMainではなくmainから書き始めるのです。 しかし、フォームアプリケーションではない、自分でCreateWindow()関数などのAPI関数を呼び出すWin32APIアプリケーションでは、CreateWindow()関数を呼ぶ際に、引数にインスタンスハンドルが必要になる為、 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) というメイン関数から開始される必要があります。 このWinMainは「基本ライブラリの中の、WinMainCRTStartupと言う場所から呼び出されている」ので、エントリーポイントをWinMainCRTStartupにすれば、この中からWinMainが呼ばれ、最終的に「WinMain関数がメイン関数になる」のです。 注:文字セットにUNICODEを使用する場合、エントリーポイントは「wWinMainCRTStartup」でなければならず、メイン関数は「_tWinMain」になります。また、コンパイル時に「#include <tchar.h>」も必要になり、色々と面倒です。なので、今回は「マルチバイト文字セット」を使います。使用している文字に全角文字(2バイト文字)が無いならば「マルチバイト文字セット」でOKです。 ●方法その2 前述の1、2の設定をしないで、メイン関数を int main(array<System::String ^> ^args) にします。つまり int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) を int main(array<System::String ^> ^args) に書き替えます。 あとは、hInstanceさえ拾えれば、CreateWindow()を呼ぶ事が出来ます。 インスタンスハンドルは HINSTANCE hInstance; hInstance = GetModuleHandle(NULL); で拾えます。 なお、hPreInstは拾えないので、無視しましょう。 すると、以下のようになります。 (前の方、変更点が無いので略) //メインプログラム //int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow)//削除 int main(array<System::String ^> ^args)//追加 { HWND hWnd; MSG msg; WNDCLASS myProg; HINSTANCE hInstance;//追加 hInstance = GetModuleHandle(NULL);//追加 //親のインスタンスが無いなら //if (!hPreInst) {//削除 myProg.style =CS_HREDRAW | CS_VREDRAW; myProg.lpfnWndProc =WndProc; myProg.cbClsExtra =0; myProg.cbWndExtra =0; myProg.hInstance =hInstance; myProg.hIcon =NULL; myProg.hCursor =LoadCursor(NULL, IDC_ARROW); myProg.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszMenuName =NULL; myProg.lpszClassName =MyClassName; //クラスを登録する if (!RegisterClass(&myProg)) return FALSE; //}//削除 //ウィンドゥを作成 (以下、変更点が無いので略) どっちも試してどっちも駄目なら、回答のお礼か補足で、再度お尋ね下さい。
お礼
ご返答ありがとうございます!! chie65535さんのご指示通りに●方法その1で試行してみたところ、無事コンパイルが成功し、アプリケーションが動作いたしました。 結果:↑キーの場合 WM_KEYDOWN wParam=38 IParam=0x01480001 WM_KEYUP wParam=38 IParam=0xc1480001 この情報を元にソースコードへ記入しました。 //user32DLLはインポート済 //フォームのボタンクリックで関数呼び出し private void button3_Click(object sender, EventArgs e) { IntPtr wParam, lParam;//Param変数宣言 IntPtr hwnd = FindWindow(null, textBox1.Text);//ウィンドウ検索 textBox1には「hoge」←アプリ名 if (hwnd != IntPtr.Zero) { if (IsWindowVisible(hwnd)) { SetForegroundWindow(hwnd); // hogeアプリをアクティブにする System.Threading.Thread.Sleep(500);//0.5sec待機 wParam = new IntPtr(0x38);//↑キーwParam値設定 lParam = new IntPtr(0x01480001);//↑キーlParam値設定 PostMessage(hwnd, 0x0100, wParam, lParam);//WM_KEYDOWN送信 System.Threading.Thread.Sleep(500);//0.5sec待機 wParam = new IntPtr(0x38);//↑キーwParam値設定 lParam = new IntPtr(0xc1480001);//↑キーlParam値設定 PostMessage(hwnd, 0x0101, wParam, lParam);//WM_UP送信 } } } 私が入力対象としているアプリを立ち上げ、バックグラウンドにし、上記の関数を呼び出したところ、 アプリが最前面に移動 → しばらく停止2~3秒 → フォームフリーズ といった状態になります。
補足
追記です。文字数がオーバーしてしまいましたので。。 ====続き==== デバッガを見てみると、 lParam = new IntPtr(0xc1480001);//↑キーlParam値設定 の部分で算術演算オーバーフロウが発生してしまいます。 もしよければ、自作Formからhoge.exe(どのようにして作られたかよくわからないアプリ)へWM_DOWNなどのキー情報を送信するとき、どのような流れで送られるか教えてください。m(_ _)m 以上です。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
投稿したら「勝手に半角スペースが削られてしまった」ので、追記。 sprintf(buf,"WM_KEYDOWN:wParam=%3d lParam=0x%08x ",KDwParam,KDlParam); と sprintf(buf,"WM_KEYUP:wParam=%3d lParam=0x%08x ",KUwParam,KUlParam); の行の「%08xの後ろ」に、以下のように「半角スペースを5個くらい」入れて下さい。 sprintf(buf,"WM_KEYDOWN:wParam=%3d lParam=0x%08x_____",KDwParam,KDlParam); sprintf(buf,"WM_KEYUP:wParam=%3d lParam=0x%08x_____",KUwParam,KUlParam); 注:連続した半角スペースは投稿できないので、代わりに _ で表記してます。実際に打ち込む場合は半角スペースで打って下さい。
お礼
ご返答ありがとうございます! chie65535さんのコードを拝借し、コンパイルしたところ、 VisualC++ 2008Express Editionの場合 デバッグを実行したところ 1>------ ビルド開始: プロジェクト: win32Pro, 構成: Debug Win32 ------ 1>リンクしています... 1>MSVCRTD.lib(crtexe.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。 1>C:\Documents and Settings\********\My Documents\Visual Studio 2008\Projects\win32Pro\Debug\win32Pro.exe : fatal error LNK1120: 外部参照 1 が未解決です。 1>ビルドログは "file://c:\Documents and Settings\********\My Documents\Visual Studio 2008\Projects\win32Pro\win32Pro\Debug\BuildLog.htm" に保存されました。 1>win32Pro - エラー 2、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== EclipseCDT +MinGW+MSYS+gdb gccVersion 3.4.5の場合 デバッグをしたところ(ファイル名 WMKEYTEST.c) エラー3項目 説明 リソース パス ロケーション 型 undefined reference to `GetStockObject@4' WMKEYTEST.c Myfirstproj/src 行 39 C/C++ 問題 説明 リソース パス ロケーション 型 undefined reference to `TextOutA@20' WMKEYTEST.c Myfirstproj/src 行 81、85 C/C++ 問題 警告 説明 リソース パス ロケーション 型 unsigned int format, LPARAM arg (arg 4) WMKEYTEST.c Myfirstproj/src 行 79 C/C++ 問題 説明 リソース パス ロケーション 型 unsigned int format, LPARAM arg (arg 4) WMKEYTEST.c Myfirstproj/src 行 83 C/C++ 問題 とエラーが表示されてしまいました。 本当に間が抜けていましたが、今更ながら私の環境を表記したいと思います。 OS:WindowsXP SP3 .NETFramework3.5 IDE:Visual Studio 2008 (C# C++)Express Edition EclipseCDT+MinGW+MSYS+GDBは本日インストールしました。
補足
文字数が足りなくなったので、追記します。 ========================================= Borland C++ のコンパイラについては、http://www.codegear.com/jp のサイトにつながらず、まだ試行していません。(19時~2時30分) また日を改めてサイトにアクセスしたいと思います。(ブラウザ:Mozilla Firefox最新版) VCEEの使い方にまだ慣れず、ソースコードの使い方がおかしいかもしれないので、また色々な方法でコンパイルしてみたいと思います。 今回は 新規作成 → プロジェクトの種類:VisualC++ → Win32プロジェクト → プロジェクトの設定 → アプリケーションの種類:Windowsアプリケーション → 追加オプション:空のプロジェクト → ファイル → 新規作成 → ファイル(test.c)にソース貼り付け という手順を行いました。 以上です。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>すごく解りやすい説明に少し感動致しましたが、まだまだ経験が浅く、上記の条件を満たすプログラムが想像できませんでした。(泣) 以下のプログラムをウィンドゥアプリケーションとしてコンパイルして実行して、キーを押したり離したりしてみて下さい。 //WM_KEYDOWN WM_KEYUPテストプログラム //全角スペースでインデントしてあるので、全角スペースを半角スペース2個に置換してからコンパイルすること #include <stdio.h> #include <windows.h> #define MY_WIN_WIDTH 400 #define MY_WIN_HEIGHT 90 //WM_KEYDOWN、WM_KEYUPイベントが来た時のwParamとlParamを保存して //おくグローバル変数。代入と参照がそれぞれ異なるイベントで行われる //ので、グローバル変数にしないとならない //代入タイミング:WM_KEYDOWN、WM_KEYUPイベント発生時 //参照タイミング:WM_PAINTイベント発生時 WPARAM KDwParam,KUwParam; LPARAM KDlParam,KUlParam; //ウィンドゥプローシジャコールバック関数のプロトタイプ宣言 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //文字を表示する関数のプロトタイプ宣言 void ShowText(HWND hWnd); //このプログラムのクラス名 char MyClassName[] = "WinClass"; //メインプログラム int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hWnd; MSG msg; WNDCLASS myProg; //親のインスタンスが無いなら if (!hPreInst) { myProg.style =CS_HREDRAW | CS_VREDRAW; myProg.lpfnWndProc =WndProc; myProg.cbClsExtra =0; myProg.cbWndExtra =0; myProg.hInstance =hInstance; myProg.hIcon =NULL; myProg.hCursor =LoadCursor(NULL, IDC_ARROW); myProg.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); myProg.lpszMenuName =NULL; myProg.lpszClassName =MyClassName; //クラスを登録する if (!RegisterClass(&myProg)) return FALSE; } //ウィンドゥを作成 hWnd = CreateWindow(MyClassName, "WM_KEYDOWN WM_KEYUP TEST", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, MY_WIN_WIDTH, MY_WIN_HEIGHT, NULL, NULL, hInstance, NULL); //作成したウィンドゥを表示 ShowWindow(hWnd, nCmdShow); //作成したウィンドゥに描画指示 UpdateWindow(hWnd); //メッセージループ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //終了コードをOSに返して終了 return (msg.wParam); } //文字を表示する関数 void ShowText(HWND hWnd) { HDC hdc; PAINTSTRUCT paint; char buf[256]; //描画開始をウィンドゥに通知し、表示するデバイスコンテキストを取得 hdc = BeginPaint(hWnd, &paint); //表示する文字列を作成 sprintf(buf,"WM_KEYDOWN:wParam=%3d lParam=0x%08x ",KDwParam,KDlParam); //デバイスコンテキストに文字を表示 TextOut(hdc, 10, 10, (LPCSTR)buf, strlen(buf)); //表示する文字列を作成 sprintf(buf,"WM_KEYUP:wParam=%3d lParam=0x%08x ",KUwParam,KUlParam); //デバイスコンテキストに文字を表示 TextOut(hdc, 10, 30, (LPCSTR)buf, strlen(buf)); //描画終了をウィンドゥに通知 EndPaint(hWnd, &paint); return; } //ウィンドゥプローシジャコールバック関数 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { //[X]ボタンで終了する時 case WM_DESTROY: PostQuitMessage(0); return (0L); //キーが押し下げられた時 case WM_KEYDOWN: KDwParam = wParam; KDlParam = lParam; InvalidateRect(hWnd, NULL, FALSE); //強制的にWM_PAINTを UpdateWindow(hWnd); //発生させるためのオマジナイを2行 break; //キーが離された時 case WM_KEYUP: KUwParam = wParam; KUlParam = lParam; InvalidateRect(hWnd, NULL, FALSE); //強制的にWM_PAINTを UpdateWindow(hWnd); //発生させるためのオマジナイを2行 break; //ウィンドゥを描画する必要がある時 case WM_PAINT: ShowText(hWnd); return (0L); default: break; } //他のイベントはデフォルトの動作 return(DefWindowProc(hWnd, msg, wParam, lParam)); }
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>//「hWndで指定した対象に0x26(UPキー)押す」を送信する際はこの記述でいいのでしょうか?? wParam、lParamの指定が正しくないです。 wParamのnVirtKeyは、windows.hまたはwinuser.hに定義されているVK_????を指定して下さい。UPキーであればVK_UPです。 lParamのlKeyDataは、以下のHPを参考に、適切な値を指定して下さい。 http://yokohama.cool.ne.jp/chokuto/urawaza/message/WM_KEYDOWN.html また、WM_KEYDOWNとWM_KEYUPでは、以下HPに書いてある通り、lParamのlKeyDataの値が異なるので注意して下さい。 http://yokohama.cool.ne.jp/chokuto/urawaza/message/WM_KEYUP.html lParamのlKeyDataの各ビットに何を指定すれば良いか判りにくいと思いますので、適当なテストプログラムで「WM_KEYDOWN、WM_KEYUPイベントを受け取った時、lParamがどういう値になっているか表示するテスト」を行って「実際に受け取っている値を表示させ、それと同じ値を指定」して下さい。 少なくとも「lParam(一番右の引数)が0では駄目」です。 なお「WM_KEYDOWN、WM_KEYUPイベントを受け取るウィンドゥにキーボードフォーカスが無い場合」には、受け取り側が正しくイベントを受け取らない可能性があります(これは「受け取り側」の問題。メモ帖などは、キーボードフォーカスが無い場合はEnterキーなどの一部のキーを受け付けず、メッセージを捨てる仕様になっている。それ以外の通常キーならば受け取る事もある) 正しくキー入力を受け取らせたいなら、対象ウィンドゥをSetFocusして下さい。 以下蛇足。 処理系によっては「WM_KEYPRESS」がヘッダに定義されていないかも知れません。 実は #define WM_KEYPRESS WM_KEYDOWN と定義されてて「WM_KEYPRESSは、WM_KEYDOWNと同じ」だったりします。 つまり、キー押下イベントは「キーが離されるまで、WM_KEYDOWNイベントが、何度も繰り返して発生する」のです。 で「初回の押下でのWM_KEYDOWNはlParamのビット30が0、リピートし始めた2回目以降のWM_KEYDOWNはlParamのビット30が1」になります。 そして、最後の最後に「WM_KEYUPイベント」が起きて「キーが離された」というのが通知されます。 メモ帖でのEnterキーのように「押しっぱなしでリピートされては困る物」の場合、たいていのアプリは「WM_KEYDOWNはすべて無視し、WM_KEYUPだけをトリガーにして処理」したりするので、最後に必ずWM_KEYUPイベントを送るようにして下さい。
お礼
ご返答ありがとうございます! >lParamのlKeyDataの各ビットに何を指定すれば良いか判りにくいと思いますので、適当なテストプログラムで「WM_KEYDOWN、WM_KEYUPイベントを受け取った時、lParamがどういう値になっているか表示するテスト」を行って「実際に受け取っている値を表示させ、それと同じ値を指定」して下さい。 すごく解りやすい説明に少し感動致しましたが、まだまだ経験が浅く、上記の条件を満たすプログラムが想像できませんでした。(泣) そこで、キーコードを直接入力しようと考え http://yokohama.cool.ne.jp/chokuto/urawaza/message/WM_KEYUP.html様 を参考に調べたところ、自身のキーボードがPS/2なので http://www.ne.jp/asahi/shared/o-family/ElecRoom/AVRMCOM/PS2_RS232C/KeyCordList.pdf様に辿りつきましたが、 http://yokohama.cool.ne.jp/chokuto/urawaza/message/WM_KEYDOWN.html様のサイトで説明されているlKeyDataの対応bitを参考にしたのですが、「↑」キーのスキャンコードの説明が8bitに対し、スキャンコード一覧のサイト様では「E0、75」とあり16bitでした。 自身の知識が浅く、どう扱えばいいのか理解するに至りませんでした。(泣) 「キーボードの状態を取得する」というプログラムをこれからも調査を進めていく予定なのですが、もしよろしければ、参考になるサイト等を教えていただけませんか? 我がままを言って申し訳ないです。。
- machongola
- ベストアンサー率60% (434/720)
こんにちは。 此れは、SendInput()やkeybd_event()を使用するのではないでしょうか(実際にメモ帳へ入力しているサンプルもあります)。 http://www.google.co.jp/search?hl=ja&q=sendinput%E3%80%80%E6%93%8D%E4%BD%9C&lr=&aq=f&oq= 取り敢えず、DirectInput系列では無理そうです。 以下に有るIDirectInputDevice8::SendDeviceData()が其れらしいのですが、ただ存在するだけで、使用してはいけないようです。 http://msdn.microsoft.com/ja-jp/library/cc351892.aspx http://msdn.microsoft.com/ja-jp/library/bb205977(VS.85).aspx 上記を手がかりに辿ると、フォースフィードバックを推奨するとあります。 http://msdn.microsoft.com/ja-jp/library/bb173409(VS.85).aspx 以下IDirectInputEffectインターフェース? と言う事ですが、よく見るとゲーム用コントローラをブルブルさせたりする為の代物なのでキーボードとは関係ないようです。 http://msdn.microsoft.com/ja-jp/library/bb205986(VS.85).aspx
お礼
ご返答ありがとうございます。 メモ帳に対してはSendInput等は試して成功したのですが、今回の対象にはメッセージは届きませんでした。 上記のURLを参考にさせて頂きます!
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
最も単純なのが「PostMessage()で、WM_KEYDOWNをVK_LEFTでポストし、適当に待ってから、WM_KEYUPをVK_LEFTでポストする」と言う方法。 なお「押しっぱなしでキーリピート」も再現する場合は、WM_KEYPRESSも一定間隔でポストする事。 キーリピート無しの場合は ・WM_KEYDOWNポスト(キーを押し下げた) ・適当な待機時間(この時間が「キーを押している時間」になる) ・WM_KEYUPポスト(キーから指を離した) となります。 キーリピート有りの場合は ・WM_KEYDOWNポスト(キーを押し下げた) ・リピートスタートまでの待機時間(キーボードのプロパティから取得可能) ・WM_KEYPRESSポスト(リピートによる2文字目入力) ・キーリピート間隔の待機時間(キーボードのプロパティから取得可能) ・WM_KEYPRESSポスト(リピートによる3文字目入力) ・キーリピート間隔の待機時間 (繰り返し) ・WM_KEYPRESSポスト(リピートによるn-2文字目入力) ・キーリピート間隔の待機時間 ・WM_KEYPRESSポスト(リピートによるn-1文字目入力) ・キーリピート間隔の待機時間 ・WM_KEYPRESSポスト(リピートによるn文字目入力) ・適当な待機時間 ・WM_KEYUPポスト(キーから指を離した) となります。
お礼
ご返答ありがとうございます。 調べていたら返事が遅れてしまいました。 PostMessageはまだ試行していませんでした。 PostMessageを使う際なのですが、 PostMessage(hWnd, WM_KEYDOWN, 0x26, 0); //「hWndで指定した対象に0x26(UPキー)押す」を送信する際はこの記述でいいのでしょうか?? もし必要であれば、C#のソースコードですが記載させていただきます。
お礼
ご返答ありがとうございます! 数日間ネットで調べていたのですが、望み通りの資料が見つからなく、言語の壁が厚く、実装するに至りませんでした。(泣) 私の実力では「C#でFormからのDirectXアプリへのキー入力」の壁は少し厚かったようです。また、資料の多い言語で再び挑戦したいと思います! ありがとうございました!