前提
とあるゲーム(ぷよぷよ™テトリス®のSteam版)で, プログラムにプレイさせるようなことをしたいのですが, そもそもキー入力がうまくできません. 下で詳しく説明します.
発生している問題・エラーメッセージ
私はkeybd_event()関数でこれを実現できると思い, これをバックグラウンドで0.1秒に一回fとjのキーボードを入力するとしたコードを書きました. 確かにプログラムは動いているようで, GoogleChromeのほうでは期待した反応を見せた一方, ゲームのほうでは動きませんでした.
カレントの時間([msec])をウィンドウに表示させるようにしており, ゲームプレイ(ウィンドウモードで)中でもその表示が常に動いていることを確認したので, バックグラウンドで動作はしているのは確かだと思います.
該当のソースコード
C++
1#include<windows.h> 2#include<mmsystem.h> 3#include <string> 4#include<thread> 5#include <mutex> 6 7#pragma(lib, "WinMM.Lib") 8 9std::mutex mtx_; 10 11LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { 12 switch (msg) { 13 case WM_DESTROY: 14 PostQuitMessage(0); 15 return 0; 16 case WM_CLOSE: 17 int close=MessageBoxW(hWnd, L"Are you sure to close this window?", L"about to be closed", MB_YESNO); 18 if (close == IDNO) { 19 return 0; 20 } 21 else { 22 DestroyWindow(hWnd); 23 PostQuitMessage(0); 24 return 0; 25 } 26 } 27 return DefWindowProc(hWnd, msg, wp, lp); 28} 29 30namespace myGlobalVars { 31 HWND hWnd; 32 MSG msg; 33 WNDCLASSEX wcex; 34 bool isErr = false; 35 HINSTANCE hI; 36 HINSTANCE hP; 37 PSTR lp; 38 int nC; 39}; 40 41using namespace myGlobalVars; 42 43void ThreadA() { 44 45 std::lock_guard<std::mutex> lock(mtx_); 46 47 ZeroMemory(&wcex, sizeof(WNDCLASSEX)); 48 49 wcex.cbSize = sizeof(WNDCLASSEX); 50 wcex.style = CS_HREDRAW | CS_VREDRAW; 51 wcex.lpfnWndProc = WndProc; 52 wcex.hInstance = hI; 53 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 54 wcex.lpszMenuName = NULL; 55 wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 56 wcex.lpszClassName = L"mWnd"; 57 58 if (!RegisterClassEx(&wcex)) { 59 isErr = true; 60 return; 61 } 62 63 hWnd = CreateWindowEx( 64 NULL, 65 L"mWnd", 66 L"aa", 67 WS_OVERLAPPEDWINDOW, 68 300, 300, 69 800, 600, 70 NULL, 71 NULL, 72 hI, 73 NULL 74 ); 75 76 if (hWnd == NULL) { 77 isErr = true; 78 return; 79 } 80 81 ShowWindow(hWnd, nC); 82 83 bool isQuit = false; 84 85 timeBeginPeriod(1); 86 DWORD timeMarker = timeGetTime(); 87 88 while (1) { 89 while (1) 90 { 91 DWORD curTime = timeGetTime(); 92 93 std::wstring str = std::to_wstring(curTime) + L" " + std::to_wstring(timeMarker); 94 95 HDC hdc = GetDC(hWnd); 96 TextOutW(hdc, 50, 50, str.c_str(), lstrlen(str.c_str())); 97 ReleaseDC(hWnd, hdc); 98 99 if (msg.message == WM_QUIT) { 100 isQuit++; 101 break; 102 } 103 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); 104 TranslateMessage(&msg); 105 DispatchMessage(&msg); 106 107 if (timeMarker < curTime - 100) { 108 timeMarker = curTime; 109 keybd_event(0x46, 0x00, KEYEVENTF_EXTENDEDKEY | 0, 0); 110 keybd_event(0x46, 0x00, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 111 112 keybd_event(0x4a, 0x00, KEYEVENTF_EXTENDEDKEY | 0, 0); 113 keybd_event(0x4a, 0x00, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 114 } 115 } 116 if (isQuit) { 117 break; 118 } 119 } 120 121 return; 122} 123 124int WINAPI WinMain( 125 HINSTANCE hInstance, 126 HINSTANCE hPrevInstance, 127 PSTR lpCmdLine, 128 int nCmdShow 129) { 130 131 hI=hInstance; 132 hP=hPrevInstance; 133 lp=lpCmdLine; 134 nC=nCmdShow; 135 136 std::thread th_a(ThreadA); 137 th_a.join(); 138 139 140 if (isErr) { 141 return 0; 142 } 143 144 return msg.wParam; 145}
実現したいこと
言語はC++のままで, 仮想のキーボードを作るようなことができればよいなと考えております. ゲームパッドの入力でも問題ありません. Win32は今勉強中なので使ってみたいという気持ちから使っていますが, もしWin32でできないようでしたらほかの方法でも結構なので, 教えていただけるとありがたいです. マルチスレッドは特に使わない予定なので, 無視してもらって大丈夫です. (先ほど別の問題の原因だと思って導入したものです. 濡れ衣でしたが...)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/05 09:06
2020/08/05 09:34
2020/08/05 10:01