3

I am trying to minimize the window with the title located in the string p (specified by the user at runtime). The window is guaranteed to be a main window, because the user can only choose from main windows. I have tried showCmd, flags, and a mixture of the two, but every time, regardless of whether the window is minimized, I am shown the dialog box that states "Minimizing". How can I fix it?

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

To get the 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;
    }
}

And:

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 Answers 2

5

Did you check what value the wp.showCmd has?

Try with this code:

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; 
    } 
}  
6
  • Thanks, now I know that it captured a iTunes Window called HelperMsgListenerWnd instead of Taskbar - Microsoft Visual Studio. Any help on this?
    – m12
    Commented Apr 1, 2012 at 0:09
  • And what exactly is the problem at the moment? You click the Visual Studio window, but it changes the iTunes window?
    – aKzenT
    Commented Apr 1, 2012 at 0:24
  • I click the button to minimize Visual Studio, I get the message box "Minimizing", and nothing else. I click again, get "Restoring", and I get either a transparent window with random letters for the title, or a blank square without a frame. @aKzenT
    – m12
    Commented Apr 1, 2012 at 0:28
  • Try using the ShowWindowAsync function instead, passing the handle as the first parameter and the 2 or 9 as the second parameter.
    – aKzenT
    Commented Apr 1, 2012 at 0:38
  • Thanks this worked for me. Please note that you may need to run your process as administrator for this to work. This can be done by adding a app.manifest file and using <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> Commented Jun 10, 2016 at 20:00
1
this.WindowState = FormWindowState.Minimized;

Not the answer you're looking for? Browse other questions tagged or ask your own question.