HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0827
まーる修飾キーの右と左を判定したい7解決


まーる

リンク

2017/8/27(Sun) 15:19:15|NO.81135

HSP3.5b5です。SHIFTキーである、CTRLキーであることは判定できています。
どうしたら、右Shiftキーと左Shiftキーを区別して判定できるのでしょうか?
デバッグウィンドウで見ると、右・左Shiftキーの場合 wparam,lparam,iparam ともに同じ値が来るようです。

Ctrlキーでは、右キーと左キーを入力判別できました。

AltキーだとonkeyやWM_KEYDOWNに反応しないようで、ALTキーの判定ができません。
onkeyではAltキー入力の検出ができないのでしょうか。
可能ならonkey内でも右Altキー、左Altキーの判定がしたいです。
右Altキーが押されている、左Altキーが押されていることを検出する方法は他にあるのでしょうか?

以下サンプルですが、onkey内でなくてもかまいません。



screen 0, 640,480 #const VK_SHIFT 16 #const VK_LSHIFT 160 #const VK_RSHIFT 161 onkey gosub *OnKeyDown stop *OnKeyDown getkey ShiftR, VK_RSHIFT if (0 == ShiftR) { } else { mes strf("getkey: 右SHIFTキーが押されました!") } getkey ShiftL, VK_LSHIFT if (0 == ShiftL) { } else { mes strf("getkey: 左SHIFTキーが押されました!") } getkey Shift, VK_SHIFT if (0 == Shift) { } else { mes strf("getkey: とにかくSHIFTキーが押されました。") } return



この記事に返信する


科学太郎

リンク

2017/8/27(Sun) 17:23:32|NO.81139

> どうしたら、右Shiftキーと左Shiftキーを区別して判定できるのでしょうか?
こちらの環境では、提示されてるサンプルで正しく判別できてます。

> デバッグウィンドウで見ると、右・左Shiftキーの場合 wparam,lparam,iparam ともに同じ値が来るようです。
そのようですね。

> Ctrlキーでは、右キーと左キーを入力判別できました。
こちらの環境でも判別できてます。

> AltキーだとonkeyやWM_KEYDOWNに反応しないようで、ALTキーの判定ができません。
当然です。

> onkeyではAltキー入力の検出ができないのでしょうか。
はい。
出来ません。

・キーボードイベント
http://wisdom.sakura.ne.jp/system/winapi/win32/win30.html

WM_KEYDOWNメッセージの他にも
WM_SYSKEYDOWNメッセージもあります。

> 可能ならonkey内でも右Altキー、左Altキーの判定がしたいです。
onkey は WM_KEYDOWN メッセージ内ですから無理だと思います。

> 右Altキーが押されている、左Altキーが押されていることを検出する方法は他にあるのでしょうか?
oncmd で WM_SYSKEYDOWN メッセージ内で行います。

//------------------------------------------------------------------------------ // SHIFT・CTRL・ALTキーの取得 by 科学太郎 //============================================================================== // @URL(http://hsp.tv/play/pforum.php?mode=all&num=81135)→「修飾キーの右と左を判定したい」 // @URL(http://wisdom.sakura.ne.jp/system/winapi/win32/win30.html)→「キーボードイベント」 //------------------------------------------------------------------------------ //-------------------------------------- // 記号定数(API定数) //-------------------------------------- #const global WM_KEYDOWN $00000100 #const global WM_SYSKEYDOWN $00000104 //-------------------------------------- // 仮想キーの列挙定数 //-------------------------------------- #enum なし1=0 #enum VK_LBUTTON #enum VK_RBUTTON #enum VK_CANCEL #enum VK_MBUTTON #enum VK_XBUTTON1 #enum VK_XBUTTON2 #enum 未定義1 #enum VK_BACK #enum VK_TAB #enum 予約1 #enum 予約2 #enum VK_CLEAR #enum VK_RETURN #enum なし2 #enum なし3 #enum VK_SHIFT #enum VK_CONTROL #enum VK_MENU #enum VK_PAUSE #enum VK_CAPITAL #enum VK_KANA #enum VK_HANGUL=VK_KANA ;重複 #enum VK_HANGEUL=VK_KANA ;重複 #enum なし4 #enum VK_JUNJA #enum VK_FINAL #enum VK_HANJA #enum VK_KANJI=VK_HANJA ;重複 #enum なし5 #enum VK_ESCAPE #enum VK_CONVERT #enum VK_NONCONVERT #enum VK_ACCEPT #enum VK_MODECHANGE #enum VK_SPACE #enum VK_PRIOR #enum VK_NEXT #enum VK_END #enum VK_HOME #enum VK_LEFT #enum VK_UP #enum VK_RIGHT #enum VK_DOWN #enum VK_SELECT #enum VK_PRINT #enum VK_EXECUTE #enum VK_SNAPSHOT #enum VK_INSERT #enum VK_DELETE #enum VK_HELP #enum VK_0 #enum VK_1 #enum VK_2 #enum VK_3 #enum VK_4 #enum VK_5 #enum VK_6 #enum VK_7 #enum VK_8 #enum VK_9 #enum なし6 #enum なし7 #enum なし8 #enum なし9 #enum なし10 #enum なし11 #enum 未定義2 #enum VK_A #enum VK_B #enum VK_C #enum VK_D #enum VK_E #enum VK_F #enum VK_G #enum VK_H #enum VK_I #enum VK_J #enum VK_K #enum VK_L #enum VK_M #enum VK_N #enum VK_O #enum VK_P #enum VK_Q #enum VK_R #enum VK_S #enum VK_T #enum VK_U #enum VK_V #enum VK_W #enum VK_X #enum VK_Y #enum VK_Z #enum VK_LWIN #enum VK_RWIN #enum VK_APPS #enum 予約3 #enum VK_SLEEP #enum VK_NUMPAD0 #enum VK_NUMPAD1 #enum VK_NUMPAD2 #enum VK_NUMPAD3 #enum VK_NUMPAD4 #enum VK_NUMPAD5 #enum VK_NUMPAD6 #enum VK_NUMPAD7 #enum VK_NUMPAD8 #enum VK_NUMPAD9 #enum VK_MULTIPLY #enum VK_ADD #enum VK_SEPARATOR #enum VK_SUBTRACT #enum VK_DECIMAL #enum VK_DIVIDE #enum VK_F1 #enum VK_F2 #enum VK_F3 #enum VK_F4 #enum VK_F5 #enum VK_F6 #enum VK_F7 #enum VK_F8 #enum VK_F9 #enum VK_F10 #enum VK_F11 #enum VK_F12 #enum VK_F13 #enum VK_F14 #enum VK_F15 #enum VK_F16 #enum VK_F17 #enum VK_F18 #enum VK_F19 #enum VK_F20 #enum VK_F21 #enum VK_F22 #enum VK_F23 #enum VK_F24 #enum 未定義3 #enum 未定義4 #enum 未定義5 #enum 未定義6 #enum 未定義7 #enum 未定義8 #enum 未定義9 #enum 未定義10 #enum VK_NUMLOCK #enum VK_SCROLL #enum VK_OEM_NEC_EQUAL #enum VK_OEM_FJ_JISHO=VK_OEM_NEC_EQUAL ;重複 #enum VK_OEM_FJ_MASSHOU #enum VK_OEM_FJ_TOUROKU #enum VK_OEM_FJ_LOYA #enum VK_OEM_FJ_ROYA #enum 未定義11 #enum 未定義12 #enum 未定義13 #enum 未定義14 #enum 未定義15 #enum 未定義16 #enum 未定義17 #enum 未定義18 #enum 未定義19 #enum VK_LSHIFT #enum VK_RSHIFT #enum VK_LCONTROL #enum VK_RCONTROL #enum VK_LMENU #enum VK_RMENU #enum VK_BROWSER_BACK #enum VK_BROWSER_FORWARD #enum VK_BROWSER_REFRESH #enum VK_BROWSER_STOP #enum VK_BROWSER_SEARCH #enum VK_BROWSER_FAVORITES #enum VK_BROWSER_HOME #enum VK_VOLUME_MUTE #enum VK_VOLUME_DOWN #enum VK_VOLUME_UP #enum VK_MEDIA_NEXT_TRACK #enum VK_MEDIA_PREV_TRACK #enum VK_MEDIA_STOP #enum VK_MEDIA_PLAY_PAUSE #enum VK_LAUNCH_MAIL #enum VK_LAUNCH_MEDIA_SELECT #enum VK_LAUNCH_APP1 #enum VK_LAUNCH_APP2 #enum 予約4 #enum 予約5 #enum VK_OEM_1 ;[;][:] #enum VK_OEM_PLUS ;[+] #enum VK_OEM_COMMA ;[,] #enum VK_OEM_MINUS ;[-] #enum VK_OEM_PERIOD ;[.] #enum VK_OEM_2 ;[/][?] #enum VK_OEM_3 ;[`][~] #enum 予約6 #enum 予約7 #enum 予約8 #enum 予約9 #enum 予約10 #enum 予約11 #enum 予約12 #enum 予約13 #enum 予約14 #enum 予約15 #enum 予約16 #enum 予約17 #enum 予約18 #enum 予約19 #enum 予約20 #enum 予約21 #enum 予約22 #enum 予約23 #enum 予約24 #enum 予約25 #enum 予約26 #enum 予約27 #enum 予約28 #enum 未定義20 #enum 未定義21 #enum 未定義22 #enum VK_OEM_4 ;[[][{] #enum VK_OEM_5 ;[\][|] #enum VK_OEM_6 ;[]][}] #enum VK_OEM_7 ;['][] #enum VK_OEM_8 #enum 予約29 #enum VK_OEM_AX ;[A][X] #enum VK_OEM_102 ;[\][|] #enum VK_ICO_HELP ;[Help] #enum VK_ICO_00 ;[00] #enum VK_PROCESSKEY #enum VK_ICO_CLEAR #enum VK_PACKET #enum 未定義23 #enum VK_OEM_RESET #enum VK_OEM_JUMP #enum VK_OEM_PA1 #enum VK_OEM_PA2 #enum VK_OEM_PA3 #enum VK_OEM_WSCTRL #enum VK_OEM_CUSEL #enum VK_OEM_ATTN #enum VK_OEM_FINISH #enum VK_OEM_COPY #enum VK_OEM_AUTO #enum VK_OEM_ENLW #enum VK_OEM_BACKTAB #enum VK_ATTN #enum VK_CRSEL #enum VK_EXSEL #enum VK_EREOF #enum VK_PLAY #enum VK_ZOOM #enum VK_NONAME #enum VK_PA1 #enum VK_OEM_CLEAR #enum 予約30 //-------------------------------------- // メイン部 //-------------------------------------- *Main screen 0,640,480,SCREEN_NORMAL|SCREEN_FIXEDSIZE syscolor 15:boxf:color:title "SHIFT・CTRL・ALTキーの取得 by 科学太郎" oncmd gosub *OnKeyDown, WM_KEYDOWN oncmd gosub *OnSysKeyDown, WM_SYSKEYDOWN stop //-------------------------------------- // WM_KEYDOWNメッセージの処理 //-------------------------------------- *OnKeyDown getkey k,VK_LSHIFT :if(k):mes strf("getkey: 左SHIFTキーが押されました!") getkey k,VK_RSHIFT :if(k):mes strf("getkey: 右SHIFTキーが押されました!") getkey k,VK_LCONTROL :if(k):mes strf("getkey: 左CTRLキーが押されました!") getkey k,VK_RCONTROL :if(k):mes strf("getkey: 右CTRLキーが押されました!") title strf("wParam=%08X",wParam) return //-------------------------------------- // WM_SYSKEYDOWNメッセージの処理 //-------------------------------------- *OnSysKeyDown getkey k,VK_LMENU :if(k):mes strf("getkey: 左ALTキーが押されました!") getkey k,VK_RMENU :if(k):mes strf("getkey: 右ALTキーが押されました!") title strf("wParam=%08X",wParam) return //------------------------------------------------------------------------------ // End of sample201(SHIFT・CTRL・ALTキーの取得).hsp //------------------------------------------------------------------------------
[ALT]キーを押すと何かのモードに入るようです。
よって2回[ALT]キーを押すことになります。



まーる

リンク

2017/8/27(Sun) 21:17:13|NO.81150

書き込みありがとうございます。
スクリプト参考になりました。
改めてテストしたら、こちらでも右Shiftキーが判定できました。

ALTキーは WM_SYSKEYDOWN に来るのですね。
それでもキー2回押さないと判定できないのは仕様なんでしょうか。
修飾キー判定として使うのは、あまり向かないようですね‥

onkeyやWM_SYSKEYDOWNでなくてもいいので
右Altキー、左Altキーが押されているか(押しっぱなしか)どうかを
キー押し1回で判定することはできないでしょうか?

もし、他のやり方もあるようでしたらお待ちしてます。



掘木

リンク

2017/8/27(Sun) 21:38:56|NO.81151

>[ALT]キーを押すと何かのモードに入るようです。
>よって2回[ALT]キーを押すことになります。

>右Altキー、左Altキーが押されているか(押しっぱなしか)どうかを
>キー押し1回で判定することはできないでしょうか?

それ、デフォルトプロシージャの動作ですよ。


HSPのoncmdの項を読むとわかるけども、
デフォルト動作を行わせるために返り値を省略したreturnをしているのです。


ちなみに、WM_SYSKEYDOWNの項を見ると
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms646286(v=vs.85).aspx
キーの処理をアプリケーション独自で行ったなら、0を返すべきとのことなので、こうなる。

*SysKeyDown //…中略… if ( <<altキーの入力>> ){ return 0 // ←返り値を指定する。 } return // ←興味のないキーはデフォルトの処理をしてもらう
みんなoncmdのreturn引数省略したがるよね。



暇人

リンク

2017/8/27(Sun) 21:48:10|NO.81152

>それでもキー2回押さないと判定できないのは仕様なんでしょうか。
ALTはVK_MENUとあるように、メニューが動作します。
ALTを押してから↓キーを押せば、何故一回キーが反応しないのか分かると思う

>キー押し1回で判定することはできないでしょうか?
ALTが押された時のreturnを

return 0
にすればメニュー動作は防げる
メニューを動かしたい時に困るけど・・・



暇人

リンク

2017/8/27(Sun) 21:49:56|NO.81153

かぶってしまった・・・



科学太郎

リンク

2017/8/28(Mon) 07:17:24|NO.81161

質問者ではないけれど

掘木さん。
暇人さん。

oncmd の return 問題を教えてくれてありがとうございます。
確かに「return 0」にすると1回で取得できましたね。

まーるさんへ。

> それでもキー2回押さないと判定できないのは仕様なんでしょうか。
これは「デフォルトのプロシージャ」の動作ですね。

どうやら「return」で抜けるとHSP内部で「デフォルトのプロシージャ」が実行されるようです。
よって、「return」に何か値を返せば良いのです。
既に回答ありますけど。



まーる

リンク

2017/8/30(Wed) 21:07:35|NO.81188

掘木さん、暇人さん、科学太郎さん
回答ありがとうございます。

・ALTキー=VK_MENUは、メニューを開くキーである
・ALTキーはWM_SYSKEYDOWNに来る
・WM_SYSKEYDOWN+getkey VK_LMENU/VK_RMENUを使い、ALTキーが押されている場合は return 0 とする
ことで、デフォルトプロシージャ(2回押し判定)ではなくキーの処理を独自に行うようにする

これでALTキー押し1回で、右Altキー/左Altキーが押されていることが判定できました。
今回はメニューを使わない用途なので、これでOKです。
皆様ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.