我有一個用戶窗體,當用戶從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事件,請記住在工作簿關閉或類似時禁用定時器。
編輯:
假設用戶窗體具有獨特的標題,你可以使用用戶窗體標題
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
用戶表單沒有HWND。 –
您的權利,我正在考慮WinForms。它仍然做OP所要求的問題:) – osknows
是的,創意解決方案+1。我仍然想知道是否有辦法將這個事件陷入困境。 –
只需打開另一個應用程序沒有關閉工作表找到HWND。工作表仍處於活動狀態。據我所知,在Excel中原生的任何事件都會在應用程序失去焦點時捕獲。 –
您可以使用窗口句柄和WinAPI來完成它,但它超出了我的範圍。我可以問爲什麼?似乎很複雜:P –
我認爲你可以通過'GetForeGroundWindow'或'GetActiveWindow'得到這個,但仍然需要一種方法來捕獲事件... –