zoukankan      html  css  js  c++  java
  • .NET批量操作窗口样式

    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())
    

    4. 参考:

  • 相关阅读:
    Web server failed to start. Port 8080 was already in use.
    org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplic
    HttpClient测试框架
    Mock接口平台Moco学习
    自动化测试框架TestNG
    css常用记录...个人查看使用
    常用JS工具类 .....持续更新中 ...CV大法好
    element-upload覆盖默认行为(多个文件上传调用一次接口)
    基础术语理解
    MVC和MVVM设计模式简单理解
  • 原文地址:https://www.cnblogs.com/EasonWu/p/minimize-multiple-windows-in-apps.html
Copyright © 2011-2022 走看看