我有一个用户表单,当用户从 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 有一个独特的标题,您可以使用 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