• ベストアンサー

押しっぱなしの処理

今Windows APIでゲームを作っています。 例えばキャラクターがマスを移動するときに左ボタンを押すと左に動き 押し続けると一定時間あいたあとにある速さで連続して左に動きます。 case WM_KEYDOWN: if(wParam == VK_LEFT){ Move(LEFT); } 現状のプログラムはこんな感じです。 それを押し続けて時間があいてからではなくすぐに左に動くようにしたいです。 それとその後の左に行き続ける速さもできれば調節したいです。 そうするにはどうすればよいのでしょうか?

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>左ボタンを押すと左に動き >押し続けると一定時間あいたあとにある速さで連続して左に動きます。 WM_KEYDOWNメッセージで処理している…ということは、「キーリピート」に反応しているのでしょう。 # マウスのボタンでもキーリピート効くんですねぇ……試したこと無かったですが。 >それを押し続けて時間があいてからではなくすぐに左に動くようにしたいです。 メッセージで処理している場合は…無理じゃないでしょうかね? スレッド作って、GetKeyState()で自分で状態を見る。ということになるかと。 >それとその後の左に行き続ける速さもできれば調節したいです。 スレッド内でのGetKeyState()のコール頻度などで制御…でしょうかね。 あとは…DirectInput使うとか。 …使ったことないんですけど。 「DirectInput マウス ボタン」辺りで検索すればみつかるんじゃないでしょうか。

cern5100
質問者

お礼

回答ありがとうございます。 調べてみます。

関連するQ&A

  • キーコードとAltキー

    矢印キーのVK_UPが押された時、Altキーも押されているかを調べたいのですが、どうしたらよいですか? DLLはできるだけ使いたくありません。 case WM_KEYDOWN:  if(wParam == VK_UP){   if(Alt){   }  }

  • win32api 画面のちらつき

    win32api ビットマップを描画したとき、タイマーで少しずつ動かしているのですが、 画面がかなりちらつきます。   調べても、イマイチわからなくてどうすればいいかわかりません。 是非、わかりやすく教えていただきたいです。   タイマーの中身です。 ugokuはタイマーがあるかないかを判断するためにいれました。 なかなかいい方法が見つからなかったので。 playermukiはそのままです。 case WM_TIMER:  ugoku=1; if(playermuki==1){ playerX-=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==2){ playerX+=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==3){ playerY+=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==4){ playerY-=3; InvalidateRect(VisualWnd,NULL,TRUE); } break; また、タイマーをセットするとき case WM_KEYDOWN: if(wParam==VK_RIGHT){ playermuki=1; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_LEFT){ playermuki=2; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_UP){ playermuki=3; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_DOWN){ playermuki=4; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } } return 0; タイマーを切るとき case WM_KEYUP: if(wParam==VK_RIGHT){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_LEFT){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_UP){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_DOWN){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; } return 0;

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • キィーボードをフックしません、何故ですか???

    パソコンを現在人間が実際に操作中であるか否かを判定しながら進めるアプリを作っています 簡易的にキィーボードを操作していれば操作中と判断します(マウス操作も含めますが話を簡単にするため今はキィーだけとします) グローバルフックでKEY_DOWNをフックする為に以下のDLL(主要部分のみ)を作りました キィーが押されるとMW_KEYDOWN_DLLというメッセージをアプリに送ります EXPORT LRESULT CALLBACK HookProc( int nCode, WPARAM wParam, LPARAM lParam) { if(nCode == HC_ACTION) { CWPSTRUCT *pcwp = (CWPSTRUCT *)lParam; if(pcwp->message == WM_KEYDOWN) { SendMessage(g_hWnd, WM_KEYDOWN_DLL, pcwp->wParam, pcwp->lParam); ←(1) } } return (CallNextHookEx(g_hHook, nCode, wParam, lParam)); } MW_KEYDOWN_DLLメッセージを受けたアプリは操作中フラグを立てます(主要部分のみ) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_KEYDOWN_DLL: ここで操作中フラグを立てます ←(2)  このフラグは一定時間後にタイマーが倒します break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return (0L); } 実行してみると(1)に来ません、当然(2)のフラグは立ちません WM_KEYDOWNの代わりにWM_CREATE、WM_CLOSEだときちんとフックします WM_CHAR、MW_KEYUPなどのキィーボード系のメッセージだとフックしません なぜでしょうか??? 多分きわめて初歩的な知識の欠如によるものでしょうが分かりません 宜しくご指導願います

  • テキストボックスからフォーカス外す

     editBox = CreateWindow(   "EDIT",   "あああ",   SS_CENTER | WS_CHILD | WS_VISIBLE,   0,0,100,20,   hWnd,   NULL,   hInstance,   NULL); テキストボックスのフォーカスを外すにはどうしたら いいんですか? ESCキーでフォーカスを外そうと思ったら、 テキストボックスにフォーカスがあるせいで case WM_KEYDOWN が動作しません。 フォーカスを外すというソース自体も分かっていません。  case WM_KEYDOWN:   if( wParam == VK_ESCAPE )    ?  break;

  • ダイヤログボックス内のマウスイベントの処理

    WinXP + BCC でCのプログラムを作成しています。 ダイヤログボックス内のマウスイベントの処理で、ALTキーが押されている場合と押されていない場合で処理を変えたいのです。 alt_downという変数を用意してみましたがダメでした。 case WM_MOUSEMOVE:  if(alt_down == 1) {   ALTキーが押されているときの処理  } else {   ALTキーが押されていないときの処理  }  break; case WM_SYSKEYDOWN:  if(wParam == VK_MENU) alt_down=1;  break; case WM_SYSKEYUP:  if(wParam == VK_MENU) alt_down=0;  break;

  • WM_KEYDOWNでPrtScを捕まえる方法??

    ごく普通のウィンドウプロシージャでキーの判別を行っています 下記のように条件(1)が WM_KEYUP の際には(2)、(3)ともに検出します LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_KEYUP: ............ (1) switch(wp) { case VK_RETURN: { break; } ..... (2) case VK_SNAPSHOT: { break; } ..... (3) default: { break; } } break; } return; ところが条件(1)を WM_KEYDOWN に変更すると(2)の Enter は検出しますが、(3)の PrtSc を検出してくれません 質問1 なぜ PrtSc を WM_KEYDOWN では検出しないのですか? 質問2 WM_KEYUP WM_KEYDOWN のいずれか一方にしか反応しないキーはまだありますか? 質問3 どのようにしたら PrtSc の WM_KEYDOWN を捕まえることが出来ますか? 自分でも調べてみましたが、どうも判然と致しません 宜しくご指導のほどお願い申し上げます

  • ウィンドウが表示されない

    あるサンプルプログラムを改造しようとしているのですが、g_hWnd=CreateWindow( _T(__FILE__),_T("シューティングゲーム"),WINDOW_STYLE, CW_USEDEFAULT,CW_USEDEFAULT,rc.right-rc.left,rc.bottom-rc.top, NULL,NULL,hInst,NULL);のところのWINDOW_STYLEをWS_OVERLAPPEDWINDOWに変えたらウィンドウが表示されません。どうしたら表示されるのでしょうか。わかる方いらいしたらご教授お願いします。多分ここだろうなというところのコードを載せます。 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_KEYDOWN: switch(wParam) { case VK_F1: ChangeDisplayMode(); return 0; case VK_ESCAPE: PostMessage(hWnd,WM_CLOSE,0,0); return 0; } return 0; case WM_DISPLAYCHANGE: // IDirect3DDevice9::Reset メソッドから Send される DisplayChange(); return 0; case WM_SIZE: if(g_bWndMode==false || wParam==SIZE_MINIMIZED) return 0; g_D3DPP.BackBufferWidth = LOWORD(lParam); g_D3DPP.BackBufferHeight = HIWORD(lParam); if(wParam==SIZE_MAXIMIZED || wParam==SIZE_RESTORED) ChangeWindowSize(); return 0; case WM_ACTIVATE: g_bActive=(LOWORD(wParam)!=WA_INACTIVE); return 0; case WM_DESTROY: CleanupD3DObject(); CleanupDXGraphics(); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,msg,wParam,lParam); }

  • Alt+P,Alt+NをPostmessageで送るには

    あるアプリがあり、そのハンドルを取得してからメッセージを送るプログラムを作っています。 PageUp,PageDownをそれぞれAlt+P,Alt+Nに変換して送るものです。 関数・定数宣言部は省略しています。 Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)   Dim hTest As Long   hTest = FindWindow(vbNullString, "Test")   If KeyCode = 33 Then 'PageUp     PostMessage MPL, WM_SYSKEYDOWN, VK_ALT, 0     PostMessage MPL, WM_KEYDOWN, VK_N, 0     PostMessage MPL, WM_KEYUP, VK_N, 0     PostMessage MPL, WM_SYSKEYUP, VK_ALT, 0   ElseIf KeyCode = 34 Then 'PageDown     PostMessage MPL, WM_SYSKEYDOWN, VK_ALT, 0     PostMessage MPL, WM_KEYDOWN, VK_P, 0     PostMessage MPL, WM_KEYUP, VK_P, 0     PostMessage MPL, WM_SYSKEYUP, VK_ALT, 0   End If End Sub 送り先(Test.exe)では、 Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)   Dim L As String   L = ""   If Shift = 4 Then L = "Alt + "   Label1.Caption = L & KeyCode End Sub ラベルで「Alt+P」などが来ているかどうか見ています。こちらのウィンドウで「Alt+P」を押すとちゃんと表示されます。 しかし、この2つを組み合わせるとPのみやNのみしか送られてきません。どこかおかしいのでしょうか。 Alt+PなどをPostMessageで送る方法でよい方法があれば、お教え下さい。 よろしくお願いします。

  • VC++&グローバルフックについて質問です

    vc++2008,Windows Vistaの環境でプログラムを作成しています。 以下、aが押されたら、設定したhWndにWM_KEYDOWN,VK_LEFTのメッセージを送るプログラムのつもりで書きました。 http://www.shos.info/develop/cwin/tipswin.html#windows008 を参考にしています。 しかし、dllにしてWinMainで呼び出したのですが動作しません。 エラーも出ないのでなぜ動かないのかがわかりません。 このプログラムをちゃんと動かすにはどうしたらいいでしょうか。 どうかご指摘ください。よろしくお願いします。 //hook.h #ifdef HOOKAPI #else #define HOOKAPI extern "C" __declspec(dllimport) #endif HOOKAPI HINSTANCE _hInstance; HOOKAPI HHOOK _hHook; HOOKAPI HWND _hWnd; HOOKAPI BOOL Set(HWND hWnd); HOOKAPI void Reset(); //hook.cpp #include <windows.h> #define HOOKAPI extern "C" __declspec(dllexport) #include "hook.h" #pragma data_seg(".share") HHOOK _hHook = NULL; HWND _hWnd = NULL; HINSTANCE _hInstance; #pragma data_seg() #pragma comment(linker, "/section:.share,rws") LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) { /* ここでは 'A' が押されたら予め設定済みの _hWnd にメッセージを送る */ if (nCode >= 0 && nCode != HC_NOREMOVE && wParam == 'A') { PostMessage(_hWnd, WM_KEYDOWN, VK_LEFT, 0); CallNextHookEx(_hHook, nCode, wParam, lParam); return 1; } return CallNextHookEx(_hHook, nCode, wParam, lParam); } BOOL Set(HWND hWnd) { /* キーのフック */ _hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookProc, _hInstance, 0); /* ここで hInstance は DLL のインスタンス ハンドル */ _hWnd = hWnd; return (_hHook != NULL); } void Reset() { if (_hHook != NULL) { UnhookWindowsHookEx(_hHook); _hHook = NULL; } }

専門家に質問してみよう