- ベストアンサー
Ctrlキーが押されたことの検出
コントロールキーを押しながらコマンドボタンを押した時と、単にコマンドボタンを押した時とで、処理を変えようかと考えています。 Application.OnKey "^{}", "ctrl"で、キーを捕まえようかと考えましたが。エラーになります。 で、質問ですが、1つは、Ctrlキー、Shiftキー、Altキーを単体で押したときに任意のプロシージャーを実行することってできますか? 2つ目は、任意のプロシージャーではなく、押されているかどうかの状態のみ調べる方法ってありますか? どなたか、詳しい方教えて頂けないでしょうか?宜しくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。KenKen_SP です。 ついでの余談ですが、、、 GetAsyncKeyState 関数はキーの同時押しをうまく判定できません。 [SHIFT]+[CONTROL]キーの同時押しなどを判定する必要があれば、 GetKeyboardState 関数を使います。 あとは NT 系の OS に限定されますが、SHIFT、CNTROL、ALT の左右 を判定することも可能です。 サンプルを見て下さい。今回のご質問にあわせてボタンクリック時 のキーの状態を表示させてますが、もちろん、任意のタイミングで キーの状態を取得できますよ。 これらの API は KeyDown イベントなどが使えない(用意されてい ない)場合、つまり今回のなどで用いることが '// キーの同時押しを判定 Private Sub CommandButton1_Click() Dim KeyState(255) As Byte GetKeyboardState KeyState(0) If CBool(KeyState(VK_SHIFT) And &H80) And _ CBool(KeyState(VK_CONTROL) And &H80) And _ CBool(KeyState(VK_MENU) And &H80) Then MsgBox "[SHIFT]+[CONTROL]+[ALT]+[クリック]" ElseIf CBool(KeyState(VK_SHIFT) And &H80) And _ CBool(KeyState(VK_MENU) And &H80) Then MsgBox "[SHIFT]+[ALT]+[クリック]" ElseIf CBool(KeyState(VK_SHIFT) And &H80) And _ CBool(KeyState(VK_CONTROL) And &H80) Then MsgBox "[SHIFT]+[CONTROL]+[クリック]" ElseIf CBool(KeyState(VK_CONTROL) And &H80) And _ CBool(KeyState(VK_MENU) And &H80) Then MsgBox "[CONTROL]+[ALT]+[クリック]" ElseIf CBool(KeyState(VK_SHIFT) And &H80) Then MsgBox "[SHIFT]+[クリック]" ElseIf CBool(KeyState(VK_CONTROL) And &H80) Then MsgBox "[CONTROL]+[クリック]" ElseIf CBool(KeyState(VK_MENU) And &H80) Then MsgBox "[ALT]+[クリック]" Else MsgBox "[クリック]" End If End Sub '// SHIFT、CTRL、ALT キーの左右を判定(NT系OSのみ) Private Sub CommandButton2_Click() Dim KeyState(255) As Byte GetKeyboardState KeyState(0) If CBool(KeyState(VK_LCONTROL) And &H80) Then MsgBox "[左CTRL]+[クリック]" ElseIf CBool(KeyState(VK_RCONTROL) And &H80) Then MsgBox "[右CTRL]+[クリック]" Else MsgBox "[クリック]" End If End Sub '【標準モジュール】---------------------------------------------------- '// Win32API キーボードの仮想キーの状態を取得する Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long '// キーコード定数 Public Const VK_SHIFT = &H10 'Shift Public Const VK_CONTROL = &H11 'Ctrl Public Const VK_MENU = &H12 'Alt Public Const VK_LSHIFT = &HA0 'NT系OS only 左Shift Public Const VK_RSHIFT = &HA1 'NT系OS only 右Shift Public Const VK_LCONTROL = &HA2 'NT系OS only 左Ctrl Public Const VK_RCONTROL = &HA3 'NT系OS only 右Ctrl
その他の回答 (2)
- KenKen_SP
- ベストアンサー率62% (785/1258)
#1 の > 簡易的には Key_Down イベントでキーコードを判定し、CTRLキーならモジュール > レベルのフラグを立てる方法がありますが、確実ではありません。 をコーディングするとこんな感じ。API を使いません。ただし、クリックの事前に CommandButton1 にフォーカスが無いと KeyDown イベントが発生しないので、 それで、「確実ではない」となりますね、、、 Private mblnFLAG As Boolean Private Sub CommandButton1_Click() If mblnFLAG Then MsgBox "[CTRL]+[CLICK]" Else MsgBox "[CLICK]" End If End Sub Private Sub CommandButton1_KeyDown( _ ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If Shift = 2 Then 'fmCtrlMask mblnFLAG = True End If End Sub Private Sub CommandButton1_KeyUp( _ ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) mblnFLAG = False End Sub
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。KenKen_SP です。 簡易的には Key_Down イベントでキーコードを判定し、CTRLキーならモジュール レベルのフラグを立てる方法がありますが、確実ではありません。 そこで、API を使ってキーの状態を調べます。こんな感じ。 Private Sub CommandButton1_Click() 'Win32API の GetAsyncKeyState に渡す vKey は VB定数があります 'ので、それを利用します 'vbKeyShift 0x10 Shift Key 'vbKeyControl 0x11 Ctrl Key 'vbKeyMenu 0x12 Alt Key 'GetAsyncKeyState関数の戻り値が 0 以外ならそのキーは押下状態 If GetAsyncKeyState(vbKeyControl) <> 0 Then MsgBox "CTRLキーを押しながらクリックされましたよ" End If End Sub '【標準モジュール】---------------------------------------------------- '// Win32API キーボードのキーが押されているかどうかを調べる Declare Function GetAsyncKeyState Lib "user32.dll" _ (ByVal vKey As Long) As Long
お礼
いつもいつもいつも有難う御座います。 お礼が大変遅くなり申し訳ありませんでした。 単純にコピペするだけで実現できました。 いつもながらアッパレと感じました。ただただ、感服しております。Win32APIに関する本って最低でもVBの本になってしまうと思いますので、何度かご指導頂いた使い方と照らし合わせて自分でも使いこなせるように努力したいと思います。(参考に(無謀とは思いつつ)VisualBasicTips1000+ガリバー著ソシム出版を買いました)すると、GetAsyncKeyState 関数も、GetKeyboardState 関数も載っていました。しかし、使い方が解らないので取り合えず中を見てみようと、(VBを持っていないので!)拡張子(frx,vbp,bas,frm)をtxtに変えて中を見てみましたが、 さっぱり解りません。(期待したコードは見れませんでした。)まぁ自分的には、今後の課題とします。まだまだ、minaraiを脱することは出来そうにありません。今後とも宜しくお願い致します。本当に本当に有難う御座いました。