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.
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; } } }
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:
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.
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 } }
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?
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).
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.
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.