Closing OpenFileDialog/SaveFileDialog

后端 未结 4 1704
星月不相逢
星月不相逢 2020-12-11 06:29

We have a requirement to close child form as part of auto logoff. We can close the child forms by iterating Application.OpenForms from the timer thread. We are not able to c

4条回答
  •  死守一世寂寞
    2020-12-11 06:44

    My answer is conceptually similar to Hans Passant's answer.

    However, using GetCurrentThreadId() as the tid parameter to EnumThreadWindows did not work for me since I was calling it from another thread. If you're doing that, then either enumerate the process' thread IDs and try each one until you find the windows you need:

    ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads;
    foreach (ProcessThread thread in currentThreads) {
        CloseAllDialogs(thread.Id);
    }
    

    Or save off the thread IDs that do the ShowDialog to open the CommonDialog:

    threadId = GetCurrentThreadId();
    threadIds.Add(threadId);
    result = dialog.ShowDialog()
    threadIds.Remove(threadId);
    

    and then:

    foreach (int threadId in threadIds) {
        CloseAllDialogs(threadId);
    }
    

    Where CloseAllDialogs looks like:

    public void CloseAllDialogs(int threadId) {
        EnumThreadWndProc callback = new EnumThreadWndProc(checkIfHWNDPointsToWindowsDialog);
        EnumThreadWindows(threadId, callback, IntPtr.Zero);
        GC.KeepAlive(callback);
    }
    
    private bool checkIfHWNDPointsToWindowsDialog(IntPtr hWnd, IntPtr lp) {
        StringBuilder sb = new StringBuilder(260);
        GetClassName(hWnd, sb, sb.Capacity);
        if (sb.ToString() == "#32770") {
            SendMessage(hWnd, 0x0010, IntPtr.Zero, IntPtr.Zero);
        }
        return true;
    }
    
    private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern int GetCurrentThreadId();
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
    

提交回复
热议问题