VB6.0用掲示板の過去のログ(No.2)−VBレスキュー(花ちゃん)
[記事リスト] [新規投稿] [新着記事] [ワード検索] [管理用]

投稿日: 2006/09/26(Tue) 11:26
投稿者YK
Eメール
URL
タイトルRe: EXCEL2000のVBAでIMEHoldを実現する

こんにちは。

ExitとEnterのイベントキャッチの方法です。
終了は必ずフォームから行って下さい。
VBEのリセットをかけるとお化けが出るときが有ります。
コードを見ていただければ説明は不要と思いますので省略します。
実はパクリです。

'クラスモジュール(Class1)
Private Declare Function SetTimer Lib "user32" ( _
    ByVal Hwnd As Long, ByVal nIDEvent As Long _
    , ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Sub KillTimer Lib "user32" ( _
    ByVal Hwnd As Long, ByVal nIDEvent As Long)

Event EnterControl(ByVal Ctrl As MSForms.Control)
Event ExitControl(ByVal Ctrl As MSForms.Control)

Private myForm As UserForm
Private myPreActiveControl As MSForms.Control

Private myTimerId As Long

Private Function GetActiveControl( _
    ByVal ParentObject As Object) As MSForms.Control
    Dim myContena As Object
    Dim myActiveControl As MSForms.Control
    On Error GoTo LstHdl
    If TypeName(ParentObject) = "MultiPage" Then
        Set myContena = ParentObject.SelectedItem
    Else
        Set myContena = ParentObject
    End If
    Set myActiveControl = myContena.ActiveControl
    Select Case TypeName(myActiveControl)
        Case "Frame", "MultiPage"
            Set myActiveControl _
                = GetActiveControl(myActiveControl)
    End Select
    Set GetActiveControl = myActiveControl
LstHdl:
    Set myContena = Nothing
    Set myActiveControl = Nothing
End Function

Public Sub CheckActiveControl()
    Dim myActiveControl As MSForms.Control
    On Error Resume Next
    Set myActiveControl = GetActiveControl(myForm)
    If myActiveControl Is Nothing Then Exit Sub
    If myActiveControl Is myPreActiveControl Then GoTo LstHdl
    RaiseEvent ExitControl(myPreActiveControl)
    RaiseEvent EnterControl(myActiveControl)
    Set myPreActiveControl = myActiveControl
LstHdl:
    Set myActiveControl = Nothing
End Sub

Public Sub Init(ByVal myNewForm As UserForm)
    Set myForm = myNewForm
    Set myPreActiveControl = GetActiveControl(myForm)
    RaiseEvent EnterControl(myPreActiveControl)
    myTimerId = SetTimer(0&, 0&, 0&, AddressOf TimerProc)
End Sub

Private Sub Class_Terminate()
    KillTimer 0&, myTimerId
    Set myForm = Nothing
    Set myPreActiveControl = Nothing
End Sub

'標準モジュール
Private Declare Sub KillTimer Lib "user32" ( _
    ByVal Hwnd As Long, ByVal nIDEvent As Long)

Public Sub TimerProc(ByVal Hwnd As Long _
    , ByVal uMsg As Long, ByVal idEvent As Long _
    , ByVal dwTime As Long)
    On Error Resume Next
    If UserForms.Count = 0 Then
        KillTimer 0&, idEvent
        Exit Sub
    End If
    UserForm1.EventClass.CheckActiveControl
End Sub

'フォームモジュール(UserForm1)
Private WithEvents myClass As Class1

Private myCollection As Collection

Public Property Get EventClass() As Class1
    Set EventClass = myClass
End Property

Private Function CheckControl( _
    ByVal Ctrl As MSForms.Control) As Boolean
    Dim myCtrl As MSForms.Control
    For Each myCtrl In myCollection
        If myCtrl Is Ctrl Then Exit For
    Next
    CheckControl = Not myCtrl Is Nothing
    Set myCtrl = Nothing
End Function

'Enter時の処理(Ctrlはフォーカスを得たコントロールへの参照)
Private Sub myClass_EnterControl(ByVal Ctrl As MSForms.Control)
    If Not CheckControl(Ctrl) Then Exit Sub
    Ctrl.BackColor = vbBlack
End Sub

'Exit時の処理(Ctrlはフォーカスを得たコントロールへの参照)
Private Sub myClass_ExitControl(ByVal Ctrl As MSForms.Control)
    If Not CheckControl(Ctrl) Then Exit Sub
    Ctrl.BackColor = vbWhite
End Sub

Private Sub UserForm_Activate()
    Static f As Boolean
    Dim    i As Long

    If f Then Exit Sub
    Set myCollection = New Collection
    'イベントをハンドルしたいコントロールへの参照を
    'コレクションに追加
    With myCollection
        For i = 1 To 10
            .Add Me.Controls("TextBox" & i)
        Next
    End With
    Set myClass = New Class1
    myClass.Init Me
    f = True
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Intege
r)
    Set myClass = Nothing
End Sub


- 関連一覧ツリー (★ をクリックするとツリー全体を一括表示します)

- 返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)

- VBレスキュー(花ちゃん) - - Web Forum -