如何以编程方式最小化打开的窗口文件夹

如何获取打开的文件夹列表,通过它进行枚举并以编程方式最小化每个文件夹?

有时,当从应用程序中的一个表单跳转到另一个表单时,一些打开的文件夹会从工具中窃取焦点。 防止这种情况对我们的客户来说是高度优先的。 客户是视障人士,因此他们只能通过屏幕阅读器访问机器。 最小化其他窗口(文件夹)根本不是问题,实际上是一个要求。

我试过这个:

foreach (Process p in Process.GetProcessesByName("explorer")) { p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized; } 

正如预期的那样没有好处。

更新

从这里的答案,我试过这个:

  delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); static IEnumerable EnumerateProcessWindowHandles(int processID) { List handles = new List(); EnumThreadDelegate addWindowHandle = delegate(IntPtr hWnd, IntPtr param) { handles.Add(hWnd); return true; }; foreach (ProcessThread thread in Process.GetProcessById(processID).Threads) EnumThreadWindows(thread.Id, addWindowHandle, IntPtr.Zero); return handles; } const int SW_MINIMIZED = 6; [DllImport("user32.dll")] static extern int ShowWindow(IntPtr hWnd, int nCmdShow); private void button1_Click(object sender, EventArgs e) { foreach (IntPtr handle in EnumerateProcessWindowHandles(Process.GetProcessesByName("explorer")[0].Id)) ShowWindow(handle, SW_MINIMIZED); } 

这就创造了很多看不见的探险家窗户,突然被列在禁区里。 我在处理Windows API时有点老板,所以代码本身实际上会有所帮助。

与此处提供的已接受答案相比,“hacky”解决方案更少: 最小化文件夹

它基于Shell Objects for Scripting 。 样品:

 const int SW_SHOWMINNOACTIVE = 7; [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static void MinimizeWindow(IntPtr handle) { ShowWindow(handle, SW_SHOWMINNOACTIVE); } //call it like: foreach (IWebBrowser2 window in new Shell().Windows()) { if (window.Name == "Windows Explorer") MinimizeWindow((IntPtr)window.HWND); } 

使用Internet Explorer对象模型可以实现同样的目的

 // add a reference to "Microsoft Internet Controls" COM component // also add a 'using SHDocVw;' foreach (IWebBrowser2 window in new ShellWindows()) { if (window.Name == "Windows Explorer") MinimizeWindow((IntPtr)window.HWND); } 

请尝试这个(代码有点凌乱,但为了这个目的,你应该能够通过它;))

 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using System.Text; using System.Globalization; namespace WindowsFormsApplication20 { static class Program { [STAThread] static void Main() { foreach (IntPtr handle in EnumerateProcessWindowHandles(Process.GetProcessesByName("explorer")[0].Id)) { SendMessage(handle, WM_SYSCOMMAND, SC_MINIMIZE, 0); } } [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); static string GetDaClassName(IntPtr hWnd) { int nRet; StringBuilder ClassName = new StringBuilder(100); //Get the window class name nRet = GetClassName(hWnd, ClassName, ClassName.Capacity); if (nRet != 0) { return ClassName.ToString(); } else { return null; } } delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); static IEnumerable EnumerateProcessWindowHandles(int processID) { List handles = new List(); EnumThreadDelegate addWindowHandle = delegate(IntPtr hWnd, IntPtr param) { string className = GetDaClassName(hWnd); switch (className) { case null: break; case "ExploreWClass": handles.Add(hWnd); break; case "CabinetWClass": handles.Add(hWnd); break; default: break; } return true; }; foreach (ProcessThread thread in Process.GetProcessById(processID).Threads) EnumThreadWindows(thread.Id, addWindowHandle, IntPtr.Zero); return handles; } [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam); const int WM_SYSCOMMAND = 274; const int SC_MINIMIZE = 0xF020; } } 

最好的祝福,

朱波罗卡

//通过引用COM库“Microsoft Shell控件和自动化”-shell32.dll来创建Shell类的实例

 Shell32.ShellClass objShell = new Shell32.ShellClass(); //Show Desktop ((Shell32.IShellDispatch4)objShell).ToggleDesktop(); 

编辑:在切换后显示您的应用程序(激活或最大化/恢复)实际上非常困难:

我试过了:

 Application.DoEvents(); System.Threading.Thread.Sleep(5000); 

即使重写WndProc也无法捕获事件:

 private const Int32 WM_SYSCOMMAND = 0x112; private const Int32 SC_MINIMIZE = 0xf020; protected override void WndProc(ref Message m) { if (m.Msg == WM_SYSCOMMAND) { if (m.WParam.ToInt32() == SC_MINIMIZE) return; } base.WndProc(ref m); } 

因此,我建议不要将所有其他窗口最小化,只需在操作过程中将其保持在最顶层,然后在完成关闭后始终保持在最佳状态:

  [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); const UInt32 SWP_NOSIZE = 0x0001; const UInt32 SWP_NOMOVE = 0x0002; const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE; public static void MakeTopMost (IntPtr hWnd) { SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); } 

如果您愿意使用p-invoke,可以使用EnumThreadWindows枚举进程的所有窗口。 然后使用ShowWindow将它们最小化。

我知道这是一个老post,但是如果人们还在寻找解决方案,这里有一个更短,更简单的方法:

使用Windows API:

声明一个窗口句柄:(最小化调用可执行文件)

 HWND wHandle; //can be any scope - I use it in main 

在任何地方调用以下内容(取决于wHandle的范围):

 wHandle = GetActiveWindow(); ShowWindow(wHandle, SW_SHOWMINNOACTIVE);