Vba 当用户激活另一个程序时卸载userform
我有一个userform,当用户从excel更改到另一个程序时,我希望关闭它。 我已尝试在此工作簿中使用sheet deactivate事件,但它没有起作用Vba 当用户激活另一个程序时卸载userform,vba,Vba,我有一个userform,当用户从excel更改到另一个程序时,我希望关闭它。 我已尝试在此工作簿中使用sheet deactivate事件,但它没有起作用 Private Sub Workbook_SheetDeactivate(ByVal Sh As Object) Unload UserForm1 End Sub 像这样的怎么样 Declare PtrSafe Function GetForegroundWindow Lib "user32.dll" () As LongPtr De
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
将PtrSafe函数getForeGroundIndow Lib“user32.dll”()声明为LongPtr
将PtrSafe函数GetActiveWindow库“user32.dll”()声明为LongPtr
子测试()
变暗wbHwnd为长PTR
变暗fHwnd为长PTR
暗淡无光
'替换为滴答作响的计时器类
Application.OnTime Now+TimeValue(“00:00:10”),“test”,True
wbHwnd=Application.hWnd
fHwnd=GetForegroundWindow
aHwnd=GetActiveWindow
如果wbHwnd fHwnd,则
调试。打印“失去焦点”
其他的
Debug.Print“有焦点”
如果结束
端接头
这只是获取当前应用程序的Hwnd,并将其与前台窗口进行比较。与使用Application.Ontime相比,最好使用一个以设置的间隔滴答作响的计时器类
此外,您可以更具体地将Hwnd用于userform而不是应用程序。如果保持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
将PtrSafe函数getForeGroundIndow Lib“User32.dll”()声明为LongPtr
将PtrSafe函数GetActiveWindow库“User32.dll”()声明为LongPtr
私有声明PtrSafe函数findwindowlib“User32.dll”别名“FindWindowA”_
(ByVal ClassName作为字符串,ByVal WindowName作为字符串)作为LongPtr
子测试()
变暗wbHwnd为长PTR
变暗fHwnd为长PTR
暗淡无光
变暗ufHwnd为长PTR
'替换为滴答作响的计时器类
Application.OnTime Now+TimeValue(“00:00:10”),“test”,True
wbHwnd=Application.hWnd
fHwnd=GetForegroundWindow
aHwnd=GetActiveWindow
ufHwnd=FindWindow(“ThunderDFrame”,UserForm1.Caption)
如果wbHwnd fHwnd,则
调试。打印“失去焦点”&wbHwnd&&fHwnd&&aHwnd&&ufHwnd
其他的
Debug.Print“有焦点”&wbHwnd&&fHwnd&&aHwnd&&ufHwnd
如果结束
端接头
仅打开另一个应用程序不会停用工作表。工作表仍处于活动状态。据我所知,Excel中有任何本机事件会在应用程序失去焦点时捕获。您可以使用窗口句柄和WinAPI进行捕获,但这超出了我的范围。我能问一下为什么吗?看起来很复杂:我想你可以通过GetForeGroundWindow
或GetActiveWindow
来实现这一点,但仍然需要一种方法来捕获事件…用户表单没有HWND。没错,我想到的是WinForms。它仍然符合OP提出的问题:)是的,创造性解决方案+1。我仍然想知道是否有一种方法可以像一个事件一样抓住这个机会。这可能会有更多的信息