ユーザーがExcelから別のプログラムに変更したときに閉じたいユーザーフォームがあります。ThisWorkbook でシート非アクティブ化イベントを使用しようとしましたが、うまくいきません。
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Unload UserForm1
End Sub
ユーザーがExcelから別のプログラムに変更したときに閉じたいユーザーフォームがあります。ThisWorkbook でシート非アクティブ化イベントを使用しようとしましたが、うまくいきません。
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Unload UserForm1
End Sub
このようなものはどうですか
Declare PtrSafe Function GetForegroundWindow Lib "user32.dll" () As LongPtr
Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr
Sub test()
Dim wbHwnd As LongPtr
Dim fHwnd As LongPtr
Dim aHwnd As LongPtr
'replace with timer class that ticks
Application.OnTime Now + TimeValue("00:00:10"), "test", , True
wbHwnd = Application.hWnd
fHwnd = GetForegroundWindow
aHwnd = GetActiveWindow
If wbHwnd <> fHwnd Then
Debug.Print "Lost focus"
Else
Debug.Print "Has focus"
End If
End Sub
これは、現在のアプリケーションの Hwnd を取得し、フォアグラウンド ウィンドウと比較するだけです。Application.Ontime を使用するよりも、設定された間隔で作動するタイマー クラスを使用する方がよい場合があります。
また、より具体的にして、アプリケーションではなくユーザーフォームに Hwnd を使用することもできます。Ontime イベントを保持する場合は、ワークブックを閉じたり、同様にタイマーを無効にすることを忘れないでください。
編集:
ユーザーフォームに固有のキャプションがあると仮定すると、USerform キャプションを使用して HWnd を見つけることができます
Declare PtrSafe Function GetForegroundWindow Lib "User32.dll" () As LongPtr
Declare PtrSafe Function GetActiveWindow Lib "User32.dll" () As LongPtr
Private Declare PtrSafe Function FindWindow Lib "User32.dll" Alias "FindWindowA" _
(ByVal ClassName As String, ByVal WindowName As String) As LongPtr
Sub test()
Dim wbHwnd As LongPtr
Dim fHwnd As LongPtr
Dim aHwnd As LongPtr
Dim ufHwnd As LongPtr
'replace with timer class that ticks
Application.OnTime Now + TimeValue("00:00:10"), "test", , True
wbHwnd = Application.hWnd
fHwnd = GetForegroundWindow
aHwnd = GetActiveWindow
ufHwnd = FindWindow("ThunderDFrame", UserForm1.Caption)
If wbHwnd <> fHwnd Then
Debug.Print "Lost focus " & wbHwnd & " " & fHwnd & " " & aHwnd & " " & ufHwnd
Else
Debug.Print "Has focus " & wbHwnd & " " & fHwnd & " " & aHwnd & " " & ufHwnd
End If
End Sub