プロが教えるわが家の防犯対策術!

エンターを押すと、特定のコマンドボタンが押ささるプログラムを作っているのですが、エンターを押すとフォーカスがセットされているコマンドボタンが押ささってしまいます。
特定のコマンドボタンって言っても、1個のコマンドボタンなんですがなんかいい方法ありますか?

それから、キーボードの矢印キーで、並んであるコマンドボタンにフォーカスを移動させたいのですがいい方法ありますか?
TabIndexの関係だと思うのですが、上キーを押すと、すぐ上のボタンではなく右にいったり左にいったり・・・

どうか教えてください。
お願いします

A 回答 (4件)

KeyDownのイベントで、エンターが押されたときに、行いたい特定の処理をするようにすれば良いと思います。



同様に、矢印キーの場合も、それぞれにフォーカスをセットする(多分SetFocusだったと思う)ようにすれば良いのではないでしょうか
    • good
    • 0
この回答へのお礼

大変お礼が遅くなりました。申し訳ございません。
何とか、解決いたしました。
これからも、何かありましたらよろしくお願いします

お礼日時:2002/02/20 19:03

コマンドボタンのプロパティに[Default]という項目があります。


(初期値はfalseになってます)

こいつをTrueにすればフォーム上での[Enter]押下をClickイベントが受け取ります。
ボタンに「影」が付きますからよく見てね。



反対にEscを押下した際にClickイベントを発生させるのは プロパティ[Cansel]。

要するに「はい」「いいえ」のようなフォームの場合に、どちらを「主」とするか、
のような設定方法です。


> 並んであるコマンドボタンにフォーカスを移動させたいのですが
アクセスキーを利用した方が簡単でしょう。

Alt+(指定の文字)でフォーカスが移動します。
やり方はCaptionに&(指定の文字)とするだけ。

実行(E) (←カッコ内のEには下線が付く)の場合なら
Captionに 実行(&E)と記述するだけでOK。

見栄えがしますよ!
    • good
    • 0
この回答へのお礼

大変お礼が遅くなりました。申し訳ございません。
何とか、解決いたしました。
これからも、何かありましたらよろしくお願いします

お礼日時:2002/02/20 19:06

質問1.エンターを押すと、特定のコマンドボタンが押ささるプログラム


質問2.キーボードの矢印キーで、並んであるコマンドボタンにフォーカスを移動

まず最初に、、、
質問が二つ以上になる時は、別スレッドでお願いします。


質問2についてのサンプルです。
TabIndexを使用してフォーカスが順次移動するのは、知っての通りです。
VBの仕様を捻じ曲げなければなりません。ならばOSからVBに処理が渡る直前に、そのOSから届くイベントを処理しちゃいましょう。フックという方法を使用しました。これを使用すると、特定のイベントタイプを監視できます。


最初にコマンドボタンを25個、フォーム1に貼り付けます。
0,1,2,3,4
5,3,7,8,9
....
...
   ...24
といったようにコントロール配列にしてください。

下記のコードを貼り付け実行してください。
フォームのキャプションに注目すると
「フックしていません」
となっているはずです。[Enter]か[クリック]をすることにより
「フックしています」
になります。
その状態の時にカーソルを押すと、望みの結果が得られると思います。





-----Form1ここから-----
Option Explicit

Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hHook As Long) As Long
Private Declare Function SetWindowsHookEx Lib "user32.dll" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long

Private Const WH_KEYBOARD = 2

Private Sub Command1_Click(Index As Integer)
  'フック中でない時
  If g_lngHook = 0 Then
    '(キーボードからの入力を)フックする
    g_lngHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, 0&, App.ThreadID)
    Me.Caption = "フック中です"
    
  'フック中の時
  Else
    'フックを解除してあげる
    Call UnhookWindowsHookEx(g_lngHook)
    g_lngHook = 0
    Me.Caption = "フックしていません"
  End If
End Sub

Private Sub Command1_GotFocus(Index As Integer)
  '現在のフォーカスを持つコマンドボタンのインデックスを得る
  g_intIndex = Index
End Sub

Private Sub Form_Activate()
  If Me.Tag = "これから起動する" Then
    Command1(0).SetFocus
    Me.Tag = ""
  End If
End Sub

Private Sub Form_Load()
  Me.Tag = "これから起動する"
  Me.Caption = "フックしていません"
End Sub

Private Sub Form_Unload(Cancel As Integer)
  'フックした状態で終了しようとした時、フックを解除する
  If g_lngHook <> 0 Then
    Call UnhookWindowsHookEx(g_lngHook)
  End If
End Sub
-----Form1ここまで-----

-----標準モジュールここから-----
Option Explicit

Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public g_lngHook  As Long   'フックプロシージャのハンドル
Public g_intIndex  As Integer '現在のフォーカスを持つコマンドボタンのインデックス

Public Function KeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
              
  Static blnReEnter As Boolean  'キーイベント2重発生防止フラグ
  
  Select Case wParam
    'カーソルキーを押された時
    Case vbKeyRight, vbKeyLeft, vbKeyUp, vbKeyDown
      
      'キーイベント2重発生防止
      If blnReEnter = False Then
        blnReEnter = True
        KeyboardProc = 1
        Exit Function
      End If
      
      'カーソルによる処理分岐
      With Form1
        Select Case wParam
          Case vbKeyRight
            'カーソルが一番右列にある?
            If (g_intIndex Mod 5) = 4 Then
              .Command1(g_intIndex - 4).SetFocus
            Else
              .Command1(g_intIndex + 1).SetFocus
            End If
          Case vbKeyLeft
            'カーソルが一番左列にある?
            If (g_intIndex Mod 5) = 0 Then
              .Command1(g_intIndex + 4).SetFocus
            Else
              .Command1(g_intIndex - 1).SetFocus
            End If
          Case vbKeyUp
            'カーソルが一番上行にある?
            If (g_intIndex < 5) Then
              .Command1(g_intIndex + 20).SetFocus
            Else
              .Command1(g_intIndex - 5).SetFocus
            End If
          Case vbKeyDown
            'カーソルが一番下行にある?
            If (g_intIndex >= 20) Then
              .Command1(g_intIndex - 20).SetFocus
            Else
              .Command1(g_intIndex + 5).SetFocus
            End If
        End Select
      End With
      
      KeyboardProc = 1
      blnReEnter = False
    
    'カーソルキー以外を押された時
    Case Else
      '何もしない
      KeyboardProc = CallNextHookEx(g_lngHook, nCode, wParam, lParam)
      Exit Function
  End Select
End Function
-----標準モジュールここまで-----


・・・で、質問1の方は、これらを応用して、フラグを立てたらできるような気がします。
    • good
    • 0
この回答へのお礼

大変お礼が遅くなりました。申し訳ございません。
とても参考になりました。
ありがとうございました
これからも、何かありましたらよろしくお願いします

お礼日時:2002/02/20 19:07

ふと思ったのですが、オリジナルの処理を求めるのならば、コマンドボタンにこだわらない方がいいかもしれないですね。



いっそのことピクチャボックスにしてしまっては?
EnterとClickと処理を分けたいのであれば、それが一番手っ取り早いような気がするのですが。。。

ピクチャボックスにコマンドボタンの絵を張っておいて、フォーカスを得た時や失った時も必要なのであれば、LostやGotフォーカスで、絵の差し替えをしてあげると、同じような動きになると思います。クリックも反応させたいのであれば、マウスのUpDownMoveで差し替えることになります。

それをユーザコントロールにしておいたら非常に便利だと思いますよ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!