Avatar billede koppelgaard Praktikant
01. august 2010 - 09:09 Der er 17 kommentarer og
1 løsning

Check om alle Windows- vinduer er minimerede (XP)

Check om alle Windows-vinduer er minimerede.
Kan man det?
Avatar billede 220661 Ekspert
01. august 2010 - 10:29 #1
Ja ved at bruge knappen  "vis skrivebord"
Avatar billede 220661 Ekspert
01. august 2010 - 10:33 #2
Denne knap kommer til syne hvis du har hurtigstart aktiveret.
Det gør du ved at højreklikke på processlinien-værktøjslinier-hurtigstart.
Avatar billede koppelgaard Praktikant
01. august 2010 - 11:12 #3
Du misforstået mig. Jeg vil ikke minimere alle vinduer.
Jeg vil kontrollere om de ER minimeret fra C#.
Avatar billede heinzdmx Nybegynder
01. august 2010 - 11:39 #4
Du kan måske véd at lave noget dll import  af en funktion der hedder getforegroundwindow
Du kan google efter den

Det er i hvert fald ikke noget du bare kan direkte fra c# tror jeg.
Avatar billede koppelgaard Praktikant
01. august 2010 - 12:06 #5
okay tak
Avatar billede crazysnap Seniormester
01. august 2010 - 14:19 #6
Hej Koppelgaard,

Du kan jo tage udgangspunkt i dette kode som returnerer alle åbne vinduers titel (eller populerer en ArrayList med titlerne):

http://pinvoke.net/default.aspx/user32.EnumDesktopWindows


Så kan du jo lave denne struct:

http://pinvoke.net/default.aspx/Structures.WINDOWINFO


Og udskifte metoden GetWindowText fra koden i første link med GetWindowInfo som benytter struct'en ovenfor:

http://www.pinvoke.net/default.aspx/user32.GetWindowInfo


Forudsat selvfølgelig at WINDOWINFO indeholder information omkring vinduets minimerings-status (der er en member som hedder dwWindowStatus, mon ikke den kan bruges). Ellers må du lige lede efter den rette metode på pinvoke siden, det var dog den som umiddelbart så mest brugbar ud efter min mening.

Mvh.
CS
Avatar billede koppelgaard Praktikant
01. august 2010 - 21:46 #7
Cool!
Men det skal jeg vist lige lege lidt med og måske også have lidt  hjælp.
Det bliver i morgen aften - jeg vender tilbage.

Tak for hjælpen indtil videre.

/Michael alias Koppelgaard
Avatar billede koppelgaard Praktikant
02. august 2010 - 20:42 #8
Jeg kan få metoden i første link til køre.
Men så kniber det.
Hvor mange point skal du have for at lave den operation, som du har beskrevet ovenfor?
Avatar billede heinzdmx Nybegynder
02. august 2010 - 21:45 #9
Ifølge min metode, hvor du får en PID, som du derefter kan få proces navn på, så er skrivebordet proces navn "Program Manager"...

men det er muligvis samme som f.eks. alt+tab vil vise, så ikke 100 % sikkert. Men kan give en indikation af det.
Avatar billede koppelgaard Praktikant
03. august 2010 - 08:35 #10
Kære heinzdmx
Det forstod jeg ikke.
Avatar billede crazysnap Seniormester
03. august 2010 - 10:44 #11
Hej koppelgaard,

Jeg samler ikke på point, men har alligevel bixet lidt kode sammen til dig. Jeg har derfor lavet en WindowAuxiliary klasse som indeholder en enkelt public statisk metode GetDesktopWindowsStates() som returnerer en liste af vinduer og deres tilhørende minimized/maximized status. Du kan jo så f.eks loope gennem listen og se om alle vinduer er minimerede:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace XXXX
{
    public class WindowAuxiliary
    {
        private delegate bool EnumDelegate(IntPtr hWnd, int lParam);

        public struct WINDOWPLACEMENT
        {
            public int Length;
            public int Flags;
            public int ShowCmd; // 1 = Normal, 2 = Minimized, 3 = Maximized
            public System.Drawing.Point MinPosition;
            public System.Drawing.Point MaxPosition;
            public System.Drawing.Rectangle NormalPosition;
            public IntPtr WindowHandle;
            public string Title;

            public bool IsMinimized
            {
                get { return ShowCmd == 2; }
            }

            public bool IsMaximized
            {
                get { return ShowCmd == 3; }
            }
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

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

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

        private const int MAXTITLE = 255;

        private static List<WINDOWPLACEMENT> m_lstWindowInfo;


        private static bool EnumWindowsProcInfo(IntPtr hWnd, int lParam)
        {
            string title = GetWindowText(hWnd);
            WINDOWPLACEMENT wInfo = GetWindowInfo(hWnd);
            wInfo.WindowHandle = hWnd;
            wInfo.Title = title;

            if (IsWindowVisible(hWnd))
                m_lstWindowInfo.Add(wInfo);
            return true;
        }

        /// <summary>
        /// Return a WINDOWPLACEMENT struct by a given window handle
        /// </summary>
        private static WINDOWPLACEMENT GetWindowInfo(IntPtr hWnd)
        {
            WINDOWPLACEMENT info = new WINDOWPLACEMENT();
            GetWindowPlacement(hWnd, ref info);
            return info;
        }

        /// <summary>
        /// Returns the caption of a window by a given window handle
        /// </summary>
        private static string GetWindowText(IntPtr hWnd)
        {
            StringBuilder title = new StringBuilder(MAXTITLE);
            int titleLength = _GetWindowText(hWnd, title, title.Capacity + 1);
            title.Length = titleLength;

            return title.ToString();
        }


        /// <summary>
        /// Retrieve a list of visible desktop windows represented as a struct containing
        /// the window handle and additional information (e.g. minimized/maximized state).
        /// </summary>
        public static List<WINDOWPLACEMENT> GetDesktopWindowsStates()
        {
            m_lstWindowInfo = new List<WINDOWPLACEMENT>();
            EnumDelegate enumfunc = new EnumDelegate(EnumWindowsProcInfo);
            IntPtr hDesktop = IntPtr.Zero; // current desktop
            bool success = _EnumDesktopWindows(hDesktop, enumfunc, IntPtr.Zero);

            if (success)
            {
                // Copy the result to string array
                return m_lstWindowInfo;
            }
            else
            {
                // Get the last Win32 error code
                int errorCode = Marshal.GetLastWin32Error();

                string errorMessage = String.Format(
                "EnumDesktopWindows failed with code {0}.", errorCode);
                throw new Exception(errorMessage);
            }
        }
    }
}


Du kan så få listen af vinduer ved nedenstående kald:


List<WindowAuxiliary.WINDOWPLACEMENT> lst = WindowAuxiliary.GetDesktopWindowsStates();


Og loope gennem listen med en loop eller f.eks. bruge LINQ:


var v = from wp in lst
        where wp.IsMinimized
        select wp;

if (v.Count() == lst.Count)
  Console.WriteLine("All windows are minimized");


Og lige en sidste ting, hos mig returnerer GetDesktopWindowsStates() også nogle vinduer som ingen titel har og to vinduer som hedder "Start" og "Program Manager". Alt efter hvad du skal bruge dette til, vil du måske kun tjekke om de vinduer som du normalt åbner (f.eks. en browser, en tredje parts applikation, etc.) er minimerede. I så fald må du udvide if-sætningen i EnumWindowsProcInfo til f.eks. også at tjekke at Title != "" og måske Title != "Start" && Title != "Program Manager" så den ikke returnerer disse vinduer i listen. Men det kommer som sagt an på hvad du skal bruge det til.

Mvh.
CS
Avatar billede heinzdmx Nybegynder
03. august 2010 - 10:50 #12
Her et eksempel på kode der kan vise f.eks. "Process Manager", eller iexplore, explorer, firefox, osv.. alle process navnene der kan ses i joblisten uden ".exe" delen

Bemærk at det først er ved:
        #region Kode der køres for at få brugbare informationer
Det er den kode du bør kalde, da det efter min mening giver et mere overskueligt blik på hvordan du skal kalde de andre funktioner.


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace DefaultNameSpace
{
    public class Api_Functions
    {
        #region Import functions
        //This Function is used to get Active Window Title...
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetWindowText(IntPtr hwnd, String lpString, int cch);

        //This Function is used to get Handle for Active Window...
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr GetForegroundWindow();

        //This Function is used to get Active process ID...
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);

        #endregion
        #region Brugbar kode
        //This method is used to get Handle for Active Window using GetForegroundWindow() method present in user32.dll
        /// <summary>
        /// Get the handle of the active window
        /// </summary>
        public static IntPtr getforegroundWindow()
        {
            return GetForegroundWindow();
        }

        /// <summary>
        /// Gets the active windows PID
        /// </summary>
        public static Int32 GetActiveWindowProcessID()
        {
            Int32 pid;
            GetWindowThreadProcessId(GetForegroundWindow(), out pid);
            return pid;
        }

        //This Function is used to get Active process ID...
        public static Int32 GetWindowProcessID(IntPtr hwnd)
        {
            Int32 pid;
            GetWindowThreadProcessId(hwnd, out pid);
            return pid;
        }

        //This method is used to get active application's title using GetWindowText() method present in user32.dll
        public static String ActiveAppTitle()
        {
            IntPtr hwnd = getforegroundWindow();
            if (hwnd.Equals(IntPtr.Zero)) return "";
            String lpText = new String((char)0, 100);
            int intLength = GetWindowText(hwnd, lpText, lpText.Length);
            if ((intLength <= 0) || (intLength > lpText.Length)) return "unknown";
            return lpText.Trim();
        }

        #endregion

        #region Kode der køres for at få brugbare informationer

        // returnere titlen på det aktive program
        private string activeTitle()
        {
            return ActiveAppTitle();
        }

        // return process navnet f.eks. "Process Manager"
        private string activeProcessName()
        {
            return activeProcess().ProcessName;
        }

        // returnere en System.Diagnostics.Process man kan udføre methoder på.
        private Process activeProcess()
        {
            return Process.GetProcessById(GetActiveWindowProcessID());
        }
        #endregion
    }
}
Avatar billede koppelgaard Praktikant
04. august 2010 - 22:09 #13
Undskyld min langsomhed.
Flot det virker - til dels.
Programmer som  totalCommander og Irfanview fanges dog ikke af koden.
Hvorfor mon?
Avatar billede koppelgaard Praktikant
04. august 2010 - 22:34 #14
Jeg trækker mine ord tilbage. Irfanview og totalcommander var bare ikke maximerede. Hvis jeg spørger på !minimized virker det.
Får dog også ikke synlige programmer med.
Kan de pilles fra?
Altså kan man også tjekke for om programmer er synlige?
Avatar billede crazysnap Seniormester
05. august 2010 - 09:46 #15
Hej koppelgaard,

Hvis det er min kode du har brugt, tjekker den faktisk allerede for om vinduerne er "synlige". Hvis du kigger i EnumWindowsProcInfo-metoden i WindowAuxiliary-klassen, står der:


if (IsWindowVisible(hWnd))
    m_lstWindowInfo.Add(wInfo);


Dvs, den kun returnerer vinduer som er synlige. Du kan jo prøve at udvide den til:


if (IsWindowVisible(hWnd) && wInfo.Title != "")
    m_lstWindowInfo.Add(wInfo);


og se om den ændring skiller sig af med de sidste ikke synlige vinduer (idet du så forudsætter vinduerne har en titel).

Mvh.
CS
Avatar billede koppelgaard Praktikant
18. august 2010 - 13:29 #16
CS har du fået point???
Avatar billede crazysnap Seniormester
18. august 2010 - 14:10 #17
Hej Koppelgaard,

Jeg håber du fik løst problemet til sidst og der er ikke blevet tildelt point endnu nej. Jeg lægger et svar også kan du jo dele point ud til dem som fik skubbet dig i den rigtige retning.

Mvh.
CS
Avatar billede koppelgaard Praktikant
18. august 2010 - 17:06 #18
tak for hjælpen :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester