1. 背景
我们在开发过程中,可能会遇到需要批量控制程序中窗体的大小或其它一些操作, 这些窗体有可能是属于程序本身的,也许是其它程序的窗口。本文就是基于此的一篇关于如何批量操作窗口样式的,我们主要是通过批量最小化窗体来阐述。
2. 窗体类别
- 窗口属于程序自己的
- 窗口不属于程序自己的
下面我们分别针对这两种情况来找出相应的解决方法
2.1 窗口属于程序自己的
具体的来说就是,将要操作的这些窗体或窗口都是由当前程序创建的。
利用Form的WindowState属性, WindowState属性的值是一个FormWindowState枚举值。
- Maximized 窗口最大化状态
- Minimized 窗口最小化状态
- Normal 窗口正常状态
我们可以修改窗体的WindowState属性来变换窗口的状态。 下面是一个简单的例子。
using System; using System.Windows.Forms; public class Demo { static void Main() { // Creat 3 Forms
for (int i = 1; i <= 3; i++) { CreateForm("Form " + i); } Console.WriteLine("Do you want to minizie all open windows? (Y/N)"); string minWindows = Console.ReadLine(); if (minWindows == "Y") { // 最小化次程序打开的窗口 foreach (Form frm in Application.OpenForms) { // Use property WindowState to minizie all opened forms. frm.WindowState = FormWindowState.Minimized; } } Console.WriteLine("Press any key to exit."); Console.ReadKey(); } static void CreateForm(string title) { Form aForm = new Form(); aForm.Text = title; aForm.Show(); } }
其实如果窗体时属于当前程序创建的话,建议可以使用MDI窗体来控制,所有子窗体会在父窗体最小化时也最小化。
2.2 窗体属于其他程序的
具体来讲,将要操作的这些窗口/窗体不光是由当前程序创建的,还有系统中其他程序或系统创建。对于自己创建的系统我们可以通过WindowState属性来操作,但外部程序创建的窗体则不能。我们可以在我们的.NET程序中, 通过P/Invoke调用Win32的API函数来实现。
最重要的一个函数就是ShowWindow
[DllImport("User32")] private static extern int ShowWindow(int hwnd, int nCmdShow);
下面这段代码会最小化目前系统中所有打开的窗体。
using System; using System.Runtime.InteropServices; namespace PInvokeApps { /// <summary> /// EnumDesktopWindows Demo - shows the caption of all desktop windows, /// and minimize all these windows /// Based on the code snippet: http://pinvoke.net/default.aspx/user32.EnumDesktopWindows. /// </summary> public class User32 { /// <summary> /// filter function /// </summary> public delegate bool EnumDelegate(IntPtr hWnd, int lParam); /// <summary> /// check if windows visible /// </summary> [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr hWnd); /// <summary> /// return windows text /// </summary> [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount); /// <summary> /// enumarator on all desktop windows /// </summary> [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)] public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam); /// <summary> /// Sets the specified window's show state /// </summary> [DllImport("user32.dll", EntryPoint = "ShowWindow", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static void Main() { var collection = new List<string>(); Console.WriteLine("Do you want to minizie all open windows? (Y/N)"); string minWindows = Console.ReadLine(); bool needsMinimize = !string.IsNullOrEmpty(minWindows) && minWindows == "Y"; User32.EnumDelegate filter = delegate(IntPtr hWnd, int lParam) { StringBuilder strbTitle = new StringBuilder(255); int nLength = User32.GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1); string strTitle = strbTitle.ToString(); if (User32.IsWindowVisible(hWnd) && string.IsNullOrEmpty(strTitle) == false) { collection.Add(strTitle); // Minimize visible windows if needs if (needsMinimize) User32.ShowWindow(hWnd, ShowWindowCommands.Minimized.ToInt()); } return true; }; if (User32.EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero)) { foreach (var item in collection) { Console.WriteLine(item); } } Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } /// <summary> /// Here we can also directly define some const variable in User32 class. /// Example: /// private const int WmSize = 5; /// private const int SizeRestored = 0; /// private const int SizeMinimized = 1; /// private const int SizeMaximized = 2; /// private const int SizeShow = 3; /// private const int SizeHide = 4; /// </summary> internal enum ShowWindowCommands : int { Hide = 0, Normal = 1, Minimized = 2, Maximized = 3, } public static class EnumExtensions { public static int ToInt(this Enum enumValue) { return (int)((object)enumValue); } } }
3. 延伸:最小化特定程序的窗口
假定我们有一个名叫 "notepad"的程序,我们还是可以利用P/Invoke来实现最小化其窗口。这个时候的难点是如何得到窗口句柄hWnd,我们可以通过下面这行语句得到窗口句柄:
Process[] p = Process.GetProcessesByName("notepad"); hWnd = (int)p[0].MainWindowHandle;
然后只要调用上面程序中的ShowWindow方法,
User32.ShowWindow(hWnd, ShowWindowCommands.Minimized.ToInt())