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

本文关键字:窗口 文件夹 最小化 编程 方式 | 更新日期: 2023-09-27 18:24:09

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

有时,当从应用程序中的一个窗体跳到另一个窗体时,一些打开的文件夹确实会从工具中窃取焦点。防止这种情况发生对我们的客户来说是非常重要的。客户是视力受损的人,所以他们只能通过屏幕阅读器访问机器。最小化其他窗口(文件夹)根本不是问题,实际上是一项要求。

我试过这个:

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<IntPtr> EnumerateProcessWindowHandles(int processID)
    {
        List<IntPtr> handles = new List<IntPtr>();
        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);
    }

这会创建大量不可见的资源管理器窗口,这些窗口会突然在taksbar中列出。我在处理Windows API方面有点迟钝,所以代码本身会有帮助。

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

请尝试一下(代码有些混乱,但出于这个目的,您应该能够浏览它;)

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<IntPtr> EnumerateProcessWindowHandles(int processID)
        {
            List<IntPtr> handles = new List<IntPtr>();
            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;
    }
}

致问候,

Żubrówka

//通过引用COM库"Microsoft Shell Controls And Automation"-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);
}

这里有一个比公认答案更不"黑客"的解决方案:最小化文件夹

它基于Shell脚本对象。样品:

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);
}

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

我知道这是一篇旧帖子,但这里有一个更短、更简单的方法,以防人们仍在寻找解决方案:

使用Windows API:

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

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

调用以下任意位置(取决于wHandle的范围):

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