2017-02-23 81 views
1

開放WPF窗口的列表我有一個混合形式/ WPF應用程序(主窗口是WindowsForms),我想實現自動註銷功能來關閉所有形式/窗口,除了主窗口。獲取應用形式

對於形式我可以打電話:My.Application.OpenForms

但是調用System.Windows.Application.Current.Windows結果在一個空引用異常。

我怎樣才能從Windows窗體的WPF窗口的列表?

+0

你如何創建WPF窗口?另外,你是否有這樣混合兩個特定的原因? – Abion47

+0

是的,我們有更舊的應用程序正在更新,以使用我們在所有應用程序中使用的通用UI庫。 WPF Windows正在以標準方式創建並使用ShowDialog。 – apc

回答

0

我們都面臨着類似的問題。我們通過將應用程序設置爲WPF應用程序而不是Windows窗體應用程序來解決此問題。這將允許您訪問這兩個WPF System.Windows.Application.Current.WindowsSystem.Windows.Forms.Application.OpenForms

另一種解決方案是一種實用工具類創建的所有打開的窗體和窗口列表和走路的時候關閉其所有的名單。這裏可以使用基本窗體/窗口。

+0

我會在未來看看,但目前我不想將它保存爲Windows窗體應用程序。謝謝 – apc

0

我已經找到解決的辦法是讓所有的窗口句柄相關的過程中,得到打開的窗體和那些屬於過程,是可見的,是不是開表單列表窗口句柄是WPF視窗。

雖然這可能不是因爲它似乎是不夠好,我的目的所有環境下工作:

<DllImport("user32.dll", SetLastError:=True)> 
Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As ArrayList) As Boolean 

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> 
Private Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As ArrayList) As Boolean 
End Function 

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> 
Public Shared Function GetWindowThreadProcessId(handle As IntPtr, ByRef processId As Integer) As Integer 
End Function 

<DllImport("user32.dll", CharSet:=CharSet.Auto)> 
Private Shared Function SendMessage(hWnd As IntPtr, Msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr 
End Function 


Public Function AutoLogout_CloseWindow(hwnd As IntPtr, windowHandles As ArrayList) As Boolean 
    Dim processId As Integer 
    GetWindowThreadProcessId(hwnd, processId) 
    If processId = Process.GetCurrentProcess.Id Then 
     windowHandles.Add(hwnd) 
    End If 
    Return True 
End Function 

Public Sub AutoLogout() 

    Dim windowHandles As New ArrayList() 

    EnumWindows(New EnumWindowsProc(AddressOf AutoLogout_CloseWindow), windowHandles) 

    Dim openFormHandles As New List(Of IntPtr) 
    For Each f As Form In My.Application.OpenForms 
     openFormHandles.Add(f.Handle) 
    Next 

    For Each hwnd As IntPtr In windowHandles 
    If Not openFormHandles.Contains(hwnd) Then 
     If IsWindowVisible(hwnd) Then    
      SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero) 
     End If 
    End If 
    Next 

End Sub