Visual Basic Tips


Enterでフォーカス移動


SendKeysでTabを送るのが一番手軽で簡単ですが、SendKeysはメモリリーク等の問題もあるのであまりお勧めできません。というわけでデフォルトボタンとキャンセルボタンを使用して実現させてみました。
サンプルは下のようなフォームを作成してテストしました。CmdNextをデフォルトボタン、CmdPrevをキャンセルボタンとしています。
※上記2つのコマンドボタンはForm_Loadイベントで画面から外しています。


'--------------------------------------------------------
' Form
'--------------------------------------------------------
Public colCtl As Collection

Private Sub
Form_Load()
  CmdNext.Default =
True 'デフォルトボタン
  CmdNext.TabStop =
False
  CmdNext.Top = CmdNext.Top * -1
'見えない所へ移動

  CmdPrev.Cancel =
True 'キャンセルボタン
  CmdPrev.TabStop =
False
  CmdPrev.Top = CmdPrev.Top * -1
'見えない所へ移動

  
Call EnumControl(Me, colCtl)
End Sub

Private Sub
CmdNext_Click()
  
Call NextPrevFocus(Me, colCtl, "Next")
End Sub

Private Sub CmdPrev_Click()
  
Call NextPrevFocus(Me, colCtl, "Prev")
End Sub

'--------------------------------------------------------
' Module
'--------------------------------------------------------
Public Sub EnumControl(MyForm As Form, MyCollection As Collection)
  
Dim ctl As Control
  
Dim i As Integer

  
Set MyCollection = New Collection

  
For Each ctl In MyForm.Controls
    
If TypeOf ctl Is Menu Then
    
Else
      MyCollection.Add Item:=ctl, Key:="TabIndex"
& CStr(ctl.TabIndex)
    
End If
  
Next
End Sub


Public Sub NextPrevFocus(MyForm As Form, MyCollection As Collection, Flg As String)
  
Dim ctl As Control
  
Dim iMaxTabIndex As Integer
  
Dim iMinTabIndex As Integer
  
Dim i As Integer
  
Dim iTab() As Integer
  
Dim colTab As New Collection
  
Dim sv_iTab As Integer

  
If Flg = "Next" Or Flg = "Prev" Then
  
Else
    
Exit Sub
  
End If

  
ReDim iTab(1 To MyCollection.Count)

  
'一番近い次のTabIndexを検索します
  iMaxTabIndex = -9999
  iMinTabIndex = 9999
  
For i = 1 To MyCollection.Count
    
Set ctl = MyCollection(i)
    
If ctl.TabStop = True And ctl.Enabled = True And ctl.Visible = True Then
      iTab(i) = ctl.TabIndex - MyForm.ActiveControl.TabIndex
      colTab.Add Item:=ctl.TabIndex, Key:=CStr(iTab(i))
      
'最小のタブインデックスを取得
      
If iMinTabIndex > ctl.TabIndex Then
        iMinTabIndex = ctl.TabIndex
      
End If
      
'最大のタブインデックスを取得
      
If iMaxTabIndex < ctl.TabIndex Then
        iMaxTabIndex = ctl.TabIndex
      
End If
    
End If
  
Next
  
If Flg = "Next" Then
    
If iMinTabIndex = 9999 Then
      
Exit Sub
    
End If
    sv_iTab = 9999
    
For i = 1 To MyCollection.Count
      
If iTab(i) > 0 Then
        
If iTab(i) < sv_iTab Then
          sv_iTab = iTab(i)
        
End If
      
End If
    
Next
    
'一番近いTabIndexのコントロールへSetFocusします
    
If sv_iTab <> 9999 Then
      
Set ctl = MyCollection("TabIndex" & colTab(CStr(sv_iTab)))
      ctl.SetFocus
    
Else
      
'直近のTabIndexが見つからなかった時は先頭へ移動
      
Set ctl = MyCollection("TabIndex" & iMinTabIndex)
      ctl.SetFocus
    
End If
  
Else
    
If iMaxTabIndex = -9999 Then
      
Exit Sub
    
End If
    sv_iTab = -9999
    
For i = 1 To MyCollection.Count
      
If iTab(i) < 0 Then
        
If iTab(i) > sv_iTab Then
          sv_iTab = iTab(i)
        
End If
      
End If
    
Next
    
'一番近いTabIndexのコントロールへSetFocusします
    
If sv_iTab <> -9999 Then
      
Set ctl = MyCollection("TabIndex" & colTab(CStr(sv_iTab)))
      ctl.SetFocus
    
Else
      
'直近のTabIndexが見つからなかった時は最後へ移動
      
Set ctl = MyCollection("TabIndex" & iMaxTabIndex)
      ctl.SetFocus
    
End If
  
End If
  
Set colTab = Nothing
End Sub


DownLoad vbtips069.lzh 3KB (VB6.0)