2015-08-27 3 views
2

Я бы хотел проверить, будет ли какое-либо приложение экрана в полноэкранном режиме. У меня есть решение только для одного экрана, который код копируется здесь: [WPF] [C#] How-to : Detect if another application is running in full screen mode. Это решение основано наКак проверить, работает ли приложение в полноэкранном режиме на любом экране?

[DllImport("user32.dll")] 
private static extern IntPtr GetForegroundWindow(); 

, который собирает только активный дескриптор окна. Проблема в том, что у меня есть два экрана. Я искал много сайтов, но ни один из них не ответил на мой вопрос. Речь идет не о захвате скриншота, который прост и не зависит от P/Invoke.

Возможно ли это?

+0

'GetForgroundWindow' просто дает вам ручку окна (hWnd). Используйте любой способ перечисления окон, которые вам нравятся - все они дадут вам hWnd - и подключите эти значения вместо переднего плана hWnd. –

+0

Попробуйте следующее: http://www.codewrecks.com/blog/index.php/2014/01/29/change-appearance-of-a-control-if-the-windows-is-maximized-in-wpf/ Используя привязку, вы можете сохранить переменную, чтобы проверить, максимизирован ли sceen. – PieterSchool

+0

@PieterSchool - это не про WPF, но спасибо за ваше время :) – Fka

ответ

1

Нет готовых к употреблению раствор здесь, но давайте посмотрим ..

Получить список всех отображаемых окон и проверить позиции и размеры этих окон - возможно, много инструментов делает это, много статей о том, Я пропущу этот. Затем вы можете позвонить MonitorFromWindow для каждого или некоторых окон и сравнить размеры окна & по сравнению с информацией о мониторе. Если windowpos ~ = 0,0 и windowsize ~ = monitorresolution, вы можете предположить, что это окно находится в полноэкранном режиме.

С другой стороны, если уже имея список всех HWNDs, то почему бы не просто Query the window for its placement и проверить WINDOWPLACEMENT.showCmd для SW_MAXIMIZE/SW_SHOWMAXIMIZED флагов. Это не скажет вам, какой монитор это, но должен сказать вам хотя бы, если окно максимально и если этого достаточно для вас.

Я не знаю, как быстро и медленно это сделать, как это, но, да, кажется возможным.

1

Вы можете использовать EnumWindows совместно с Screen.FromHandle. И, возможно, GetWindowRect() для расчетов.

Нечто подобное (псевдо-код!):

//------------------------------ 
//this sample code is taken from http://pinvoke.net/default.aspx/user32/EnumWindows.html 

public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam); 

public static ArrayList GetWindows() 
{  
    ArrayList windowHandles = new ArrayList(); 
    EnumedWindow callBackPtr = GetWindowHandle; 
    EnumWindows(callBackPtr, windowHandles); 
    return windowHandles;  
} 

private static bool GetWindowHandle(IntPtr windowHandle, ArrayList windowHandles) 
{ 
    windowHandles.Add(windowHandle); 
    return true; 
} 

//------------------------------ 

[DllImport("user32.dll")] 
private static extern bool GetWindowRect(IntPtr hWnd, [In,Out] ref Rect rect); 

[StructLayout(LayoutKind.Sequential)] 
private struct Rect 
{ 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
} 

static void Main() { 
    foreach(IntPtr handle in GetWindows()) 
    { 
     Screen scr = Screen.FromHandle(handle); 

     if(IsFullscreen(handle, scr)) 
     { 
      // the window is fullscreen... 
     } 
    } 
} 

private bool IsFullscreen(IntPtr wndHandle, Screen screen) 
{ 
    Rect r = new Rect(); 
    GetWindowRect(wndHandle, ref r); 
    return new Rectangle(r.Left, r.Top, r.Right-r.Left, r.Bottom-r.Top) 
          .Contains(screen.Bounds); 
} 
1

Я написал кусок кода, который работает:

namespace EnumWnd 
{ 
using System; 
using System.Runtime.InteropServices; 
using System.Text; 

[StructLayout(LayoutKind.Sequential)] 
public struct Rect 
{ 
    public int Left; 

    public int Top; 

    public int Right; 

    public int Bottom; 
} 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
internal struct MonitorInfoEx 
{ 
    public int cbSize; 
    public Rect rcMonitor; 
    public Rect rcWork; 
    public UInt32 dwFlags; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDeviceName; 
} 

internal class Program 
{ 
    [DllImport("user32.dll")] 
    public static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect); 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    protected static extern int GetWindowTextLength(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); 

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

    [DllImport("User32")] 
    public static extern IntPtr MonitorFromWindow(IntPtr hWnd, int dwFlags); 

    [DllImport("user32", EntryPoint = "GetMonitorInfo", CharSet = CharSet.Auto, 
     SetLastError = true)] 
    internal static extern bool GetMonitorInfoEx(IntPtr hMonitor, ref MonitorInfoEx lpmi); 

    protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam) 
    { 
     const int MONITOR_DEFAULTTOPRIMARY = 1; 
     var mi = new MonitorInfoEx(); 
     mi.cbSize = Marshal.SizeOf(mi); 
     GetMonitorInfoEx(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), ref mi); 

     Rect appBounds; 
     GetWindowRect(hWnd, out appBounds); 
     int size = GetWindowTextLength(hWnd); 
     if (size++ > 0 && IsWindowVisible(hWnd)) 
     { 
      var sb = new StringBuilder(size); 
      GetWindowText(hWnd, sb, size); 

      if (sb.Length > 20) 
      { 
       sb.Remove(20, sb.Length - 20); 
      } 

      int windowHeight = appBounds.Right - appBounds.Left; 
      int windowWidth = appBounds.Bottom - appBounds.Top; 

      int monitorHeight = mi.rcMonitor.Right - mi.rcMonitor.Left; 
      int monitorWidth = mi.rcMonitor.Bottom - mi.rcMonitor.Top; 

      bool fullScreen = (windowHeight == monitorHeight) && (windowWidth == monitorWidth); 

      sb.AppendFormat(" Wnd:({0} | {1}) Mtr:({2} | {3} | Name: {4}) - {5}", windowWidth, windowHeight, monitorWidth, monitorHeight, mi.szDeviceName, fullScreen); 

      Console.WriteLine(sb.ToString()); 
     } 
     return true; 
    } 

    private static void Main() 
    { 
     while (true) 
     { 
      EnumWindows(EnumTheWindows, IntPtr.Zero); 
      Console.ReadKey(); 
      Console.Clear(); 
     } 
    } 

    protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); 
} 

}

Спасибо за @SamAxe и @quetzalcoatl для предоставления мне полезных советов.

 Смежные вопросы

  • Нет связанных вопросов^_^