Gå til innhold

C#: Finne ut om et fullscreen program kjører


Anbefalte innlegg

Jeg har noen idèer til et program jeg skal prøve meg på, men står litt fast og tenke å se om kansje noen her hadde noen tips.

En av funksjonene i programmet skal værtfall kunne sjekke om man kjører ett fullscreen program, og vilken prosess dette er.

jeg har gått gjennom hele msdn (nesten :p) og google så krampene i fingrene snart tar knekken på meg :hmm:

 

Siden jeg ikke fant noenting som kan hjelpe meg i .net rammeverket har jeg gått over på og søke gjennom unmanaged api calls (platform invoke).

 

her er dll filene og signaturene jeg har prøvd så langt:

// Returnerer en IntPtr til handle til vinduet/prosessen som er øverst i "the Z-order"

// ifølge msdn

[DllImport("user32.dll")]

static extern IntPtr GetForegroundWindow();

 

// Denne tar imot en handle til prosessen/vinduet

// og sjekker om vinduet er maximized.

[DllImport("user32.dll")]

private static extern bool IsZoomed(IntPtr hWnd);

 

så jeg lagde en test, med en timer og et kall til en funksjon som kjørte

brukte GetForegroundWindow(), brukte IntPtr for og matche mot <Process>.Handle i en for loop, fant den matchende prosessen, og returnerer prosessnavnet og en indikasjon på om vinduet er min eller maks i en string.

men det virker ikke som at IsZoomed tar fullscreen programmer som maximized, for den returnerer om jeg starter feks. cs.

hl - minimized

og jeg kjører cs fullscreen seff ;)

 

Så nå lurer jeg på om noen har vært borti noe lignende før?

Lenke til kommentar
Videoannonse
Annonse

Jeg tror ikke det finnes noen standard måte å la et program kjøre fullscreen på.

Jeg tok en kjapp test og fant ut at f.eks. IE setter skjermstørrelsen til en pixel større enn skjermen i alle retninger, mens Visual Studio ikke gjør dette. Uansett kan du jo leke deg videre med de metodene jeg brukte: Process, Process.MainWindowHandle og GetWindowRect (Win32 API).

Her er min kode:

 

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
  public int Left;    
  public int Top;    
  public int Right;    
  public int Bottom;
}

[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

...

Screen screen = Screen.PrimaryScreen;
Console.WriteLine(string.Format("Main screen: left: {0}, right: {1}, top: {2}, bottom: {3}", 
     screen.Bounds.Left, screen.Bounds.Right, screen.Bounds.Top, screen.Bounds.Bottom));
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
  IntPtr hwnd = process.MainWindowHandle;
  RECT rect;
  GetWindowRect(hwnd, out rect);
  Console.WriteLine(string.Format("Process: {0}: Left: {1}, right: {2}, top: {3}, bottom: {4}", 
     process.ProcessName, rect.Left, rect.Right, rect.Top, rect.Bottom));
}

Øyvind

Lenke til kommentar

Jeg ville prøvd å sjekke window handle for alle 4 hjørner på skjermen.

 

Dersom window handle er identisk for alle 4 punktene så ville jeg anta at det var en fullscreen application.

 

Selv med explorerbar i autohide er det en liten strek helt nederst som vil få denne testen til å feile.

Lenke til kommentar

Heisann og takker for svar :)

 

Har testet litt nå, og dette funker fint mot vanlige windows programmer, sant som du sier at internet explorer viser 1 pixel større alle veier.

 

men når jeg tester dette mot fullscreen applikasjoner, spill feks, så viser den noe helt galt.

bruker denne klassen i en console application.

postet hele klassen jeg bruker, men det er i metoden checkProc() all action foregår.

tester med spillet "Soldat".

jeg merket og at GetForegroundWindow() ikke registrerer noe hvis soldat som jeg testet med var foreground window, funker visst bare med vanlige windows forms.

 

her er da output fra console applikasjonen

Screen bounds: (firefox maximized)

Top: 0, Left: 0, Bottom: 864, Right: 1152

Process: firefox

Top: -4, Left: -4, Bottom: 808, Right: 1156

____________________________________

 

Screen bounds: (firefox fullscreen)

Top: 0, Left: 0, Bottom: 864, Right: 1152

Process: firefox

Top: 0, Left: 0, Bottom: 864, Right: 1152

____________________________________

 

Screen bounds: (soldat fullscreen)

Top: 0, Left: 0, Bottom: 864, Right: 1152

Process: Soldat

Top: 432, Left: 576, Bottom: 432, Right: 576

____________________________________

 

som man ser her, så er visst ikke spill vinduet 1*1 pixel en gang?

 

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Drawing;
using t = System.Threading;
using f = System.Windows.Forms;

namespace ConsoleApplication1
{
public class fullscreen
{
 private t.Thread checkThread = null;

 public fullscreen()
 {
 	checkThread = new t.Thread(new t.ThreadStart(this.threadStart));
 }
 
 //disse brukes av main metoden i console programmet for og styre threaden
 public void Start()
 {
 	checkThread.Start();
 }
 public void Stop()
 {
 	checkThread.Abort();
 }
 public void Suspend()
 {
 	checkThread.Suspend();
 }
 public void Resume()
 {
 	checkThread.Resume();
 }
 
 
 private void threadStart()
 {
 	while(true)
 	{
   this.checkProc();
   t.Thread.Sleep(5000);
 	}
 }

 //her er da metoden som sjekker vinduet som er øverst i Z-orderen
 private void checkProc()
 {
 	
 	IntPtr hwnd = GetForegroundWindow();
 	RECT hwndRect;

 	foreach(Process pp in Process.GetProcesses())
 	{
   if(pp.ProcessName.ToLower() == "soldat" || pp.ProcessName.ToLower() == "firefox")
   {
   	Rectangle scrRect = f.Screen.PrimaryScreen.Bounds;
     Console.WriteLine("Screen bounds:");
     printRect(scrRect);

     GetWindowRect(pp.MainWindowHandle, out hwndRect);
     Console.WriteLine("Process: {0}", pp.ProcessName);
     printRect(hwndRect);
     Console.WriteLine("____________________________________\r\n");
   	break;    	
   }
 	}
 }

 private void printRect(Rectangle rect)
 {
 	Console.WriteLine("Top: {0}, Left: {1}, Bottom: {2}, Right: {3}", rect.Top, rect.Left, rect.Bottom, rect.Right);
 }
 private void printRect(RECT rect)
 {
 	Console.WriteLine("Top: {0}, Left: {1}, Bottom: {2}, Right: {3}", rect.Top, rect.Left, rect.Bottom, rect.Right);
 }

 // Import og signaturer til de win32 api kallene vi trenger
 [DllImport("user32.dll")]
 private static extern IntPtr GetForegroundWindow();

 [DllImport("user32.dll")]
 private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
}

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
 public int Left;
 public int Top;
 public int Right;
 public int Bottom;
}

}

Endret av ZiZe
Lenke til kommentar

Sjekk om det finnes et vindu som dekker hele skjermen og som samtidig er forgrunn-vinduet.

 

Får du en match så har du en fullscreen app.

 

           int hwnd1 = WinManip.WindowFromPoint(Screen.PrimaryScreen.WorkingArea.Left, Screen.PrimaryScreen.WorkingArea.Top);
           int hwnd2 = WinManip.WindowFromPoint(Screen.PrimaryScreen.WorkingArea.Right-1, Screen.PrimaryScreen.WorkingArea.Bottom-1);
           int hwnd3 = WinManip.GetForegroundWindow();
           if (hwnd1 == hwnd2 && hwnd1 == hwnd3) {
               System.Diagnostics.Debug.WriteLine("FULLSCREEN APP hwnd: "  + hwnd1);
               foreach (Process p in Process.GetProcesses()) {
                   if (p.MainWindowHandle == (IntPtr)hwnd1) {
                       System.Diagnostics.Debug.WriteLine("FULLSCREEN APP prosess: " + p.ProcessName);
                   }
               }
           }

Lenke til kommentar

Der ja, takker for all hjelp :)

Her bruker jeg GetWindowRect mest bare for og sammenligne debug outputen jeg fikk, for og skjønne litt mer hvorfor den registrerte noen fullscreen programmer, mens ikke andre :)

 

findProcs.cs

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;

namespace Fullscreen
{
public class findProc
{
 private Thread wThread = null;
 
 public findProc()
 {
 	wThread = new Thread(new ThreadStart(workerThread));
 	wThread.Start();
 }

 private void workerThread()
 {
 	IntPtr hwnd;
 	IntPtr hwndTL;
 	IntPtr hwndBR;
 	
 	POINT pTl;
 	POINT pBr;

 	RECT winRect;
 	string pName = "";

 	Debug.WriteLine("Starting debug:", "start");
 
 	while(true)
 	{
   hwnd = GetForegroundWindow();

   if( hwnd.Equals(IntPtr.Zero) ||
hwnd == Process.GetCurrentProcess().MainWindowHandle ||
!IsWindow(hwnd) )
   {
   	Thread.Sleep(1000);
   	continue;
   }

   pTl = new POINT(Screen.PrimaryScreen.Bounds.Left, Screen.PrimaryScreen.Bounds.Top);    
   pBr = new POINT(Screen.PrimaryScreen.Bounds.Right - 1, Screen.PrimaryScreen.Bounds.Bottom - 1);
   
   hwndTL = WindowFromPoint(pTl);
   hwndBR = WindowFromPoint(pBr);
   GetWindowRect(hwnd, out winRect);

   foreach(Process pp in Process.GetProcesses())
   {
   	if(pp.MainWindowHandle == hwnd)
   	{
     pName = pp.ProcessName;
     break;
   	}
   }
   

   if(hwnd == hwndTL && hwnd == hwndBR)
   {
   	Debug.WriteLine(pTl.ToString(), "TopLeft");
   	Debug.WriteLine(pBr.ToString(), "BottomRight");
   	Debug.WriteLine(winRect.ToString(), "window size");
   	Debug.WriteLine("Vi har et fullscreen window ("+ pName +")", "Fullscreen");
   }
   else
   {
   	//Debug.WriteLine("Vi har ikke et fullscreen window ("+ pName +")", "Normal");
   	Thread.Sleep(1000);
   	continue;
   }

   Debug.Flush();
   Thread.Sleep(2000);
 	}
 }

 
 //www.pinvoke.net/default.aspx/user32/IsWindow.html
 [DllImport("user32.Dll")]
 private static extern bool IsWindow(IntPtr hWnd);

 //www.pinvoke.net/default.aspx/user32/GetForegroundWindow.html
 [DllImport("user32.Dll")]
 private static extern IntPtr GetForegroundWindow();

 //www.pinvoke.net/default.aspx/user32.WindowFromPoint
 [DllImport("user32.dll")]
 static extern IntPtr WindowFromPoint(POINT Point);

 //www.pinvoke.net/default.aspx/user32/GetWindowRect.html
 [DllImport("user32.dll")]
 static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
}
}

 

Structs.cs

using System;
using System.Runtime.InteropServices;

namespace Fullscreen
{
[StructLayout( LayoutKind.Sequential )]
public struct POINT 
{
 public int X;
 public int Y;

 public POINT( int x, int y ) 
 {
 	this.X = x;
 	this.Y = y;
 }

 public static implicit operator System.Drawing.Point( POINT p ) 
 {
 	return new System.Drawing.Point( p.X,  p.Y );
 }

 public static implicit operator POINT( System.Drawing.Point p ) 
 {
 	return new POINT( p.X, p.Y );
 }

 public override string ToString()
 {
 	return String.Format("X: {0} Y: {1} ", X, Y);
 }

}

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
 public int Left;    
 public int Top;    
 public int Right;    
 public int Bottom;

 public override string ToString()
 {
 	return string.Format("Top:{0}, Left:{1}, Right:{2}, Bottom:{3}", Top, Left, Right, Bottom);
 }

}
}

Endret av ZiZe
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...