如何在C#中最小化/还原窗口

3

我试图最小化窗口,该窗口的标题位于用户在运行时指定的字符串p中。这个窗口保证是一个主窗口,因为用户只能从主窗口中选择。我尝试使用showCmd,flags以及两者的混合,但每次不管窗口是否被最小化,都会显示对话框,上面写着“最小化”。如何解决呢?

private void button1_Click(object sender, EventArgs e)
{
    foreach (Process proc in Process.GetProcesses())
    {
        if (proc.MainWindowTitle.Contains(p))
        {
            IntPtr handle = proc.Handle;
            Program.WINDOWPLACEMENT wp = new Program.WINDOWPLACEMENT();
            Program.GetWindowPlacement(handle, ref wp);
            if ((wp.showCmd & 2) == 2)
            {
                wp.showCmd = 9;
                MessageBox.Show("Restoring");
            }
            else
            {
                wp.showCmd = 2;
                MessageBox.Show("Minimizing");
            }
            wp.length = Marshal.SizeOf(wp);
            Program.SetWindowPlacement(handle, ref wp);
            break;
        }
    }  

}

What I'm using as p -

string p;
PictureBox i;
bool windowShowing = false;
bool minimized = false;
public TaskbarItem(string window)
{
    InitializeComponent();
    p = window;
    button1.Text = window;
}

获取窗口:

class WindowEnumerator
{
    public delegate bool EnumDelegate(IntPtr hWnd, int lParam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);


    public static List<IntPtr> GetChildWindows(IntPtr parent)
    {
        List<IntPtr> result = new List<IntPtr>();
        GCHandle listHandle = GCHandle.Alloc(result);
        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
            EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            if (listHandle.IsAllocated)
                listHandle.Free();
        }
        return result;
    }
    public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

    public static LinkedList<IntPtr> EnumMethod2(bool includeChild)
    {
        LinkedList<IntPtr> pss = new LinkedList<IntPtr>();
        Process[] ps = Process.GetProcesses();
        foreach (Process p in ps)
        {
            string s = p.MainWindowTitle;
            if (s.Equals("") || s.Equals("Mod_Taskbar"))
            {
                continue;
            }
            LinkedListNode<IntPtr> node = new LinkedListNode<IntPtr>(p.MainWindowHandle);
            pss.AddLast(node);
            if (includeChild){
                List<IntPtr> l = GetChildWindows(p.MainWindowHandle);
                foreach (IntPtr i in l)
                {
                    StringBuilder stb = new StringBuilder(255);
                    WindowEnumerator.GetWindowText(i, stb, 255);
                    if (stb.ToString().StartsWith("Address:") || stb.ToString().EndsWith("View") || stb.ToString().EndsWith("Control") ||
                        stb.ToString().EndsWith("Bar") || stb.ToString().EndsWith("bar") || stb.ToString().Contains("Host"))
                    {
                        continue;
                    }
                    if (Vars.excludes.Contains(stb.ToString()))
                    {
                        continue;
                    }
                    pss.AddAfter(node, i);
                }
            }
        }
        return pss;
    }
    private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
        GCHandle gch = GCHandle.FromIntPtr(pointer);
        List<IntPtr> list = gch.Target as List<IntPtr>;
        list.Add(handle);
        return true;
    }
}

并且:

private void LoadWindows(object sender, EventArgs e)
{
    panel1.Controls.Clear();
    foreach (IntPtr p in WindowEnumerator.EnumMethod2(false))
    {
        StringBuilder stb = new StringBuilder(255);
        WindowEnumerator.GetWindowText(p, stb, 255);
        TaskbarItem t = new TaskbarItem(stb.ToString());
        t.Dock = DockStyle.Left;
        panel1.Controls.Add(t);
    }
}
2个回答

5
你检查过 wp.showCmd 的值了吗?尝试使用以下代码:
foreach (Process proc in Process.GetProcesses()) 
{ 
    if (proc.MainWindowTitle.Contains(p)) 
    { 
        IntPtr handle = proc.Handle; 
        Program.WINDOWPLACEMENT wp = new Program.WINDOWPLACEMENT(); 
        Program.GetWindowPlacement(handle, ref wp); 
        if ((wp.showCmd & 2) == 2) 
        { 
            wp.showCmd = 9; 
            MessageBox.Show("Restoring"); 
        } 
        else 
        { 
            wp.showCmd = 2; 
            MessageBox.Show("Minimizing"); 
        } 
        wp.length = Marshal.SizeOf(wp); 
        Program.SetWindowPlacement(handle, ref wp); 
        break; 
    } 
}  

谢谢,现在我知道它捕获了一个名为HelperMsgListenerWnd的iTunes窗口,而不是任务栏 - Microsoft Visual Studio。有什么帮助吗? - m12
目前的问题是什么?你点击了Visual Studio窗口,但它却切换到了iTunes窗口? - aKzenT
我点击按钮以最小化Visual Studio,我会收到消息框“最小化”,除此之外没有其他反应。我再次点击,会得到“恢复”,然后我要么得到一个标题为随机字母的透明窗口,要么得到一个没有边框的空白方块。@aKzenT - m12
尝试使用ShowWindowAsync函数,将句柄作为第一个参数传递,将2或9作为第二个参数传递。 - aKzenT
谢谢,这对我有用。请注意,您可能需要以管理员身份运行您的进程才能使其正常工作。这可以通过添加一个app.manifest文件并使用<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 来实现。 - keshav.bahadoor
另外,我不得不使用proc.MainWindowHandle而不是proc.Handle。这可能只是我的情况,但如果有人遇到问题,也可以尝试这个。 - keshav.bahadoor

1
this.WindowState = FormWindowState.Minimized;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接