-
-
Notifications
You must be signed in to change notification settings - Fork 302
Expand file tree
/
Copy pathFullScreenApi.cs
More file actions
128 lines (106 loc) · 4.52 KB
/
FullScreenApi.cs
File metadata and controls
128 lines (106 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
using System;
using System.Runtime.InteropServices;
namespace WinDynamicDesktop
{
// Code based on https://stackoverflow.com/a/10280800/5504760
// and https://www.richard-banks.org/2007/09/how-to-detect-if-another-application-is.html
class FullScreenApi
{
public bool runningFullScreen = false;
public bool timerEventPending = false;
private Action timerEventHandler;
private IntPtr winEventHook;
private WinEventDelegate winEventProc;
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
private const uint WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_FOREGROUND = 3;
private delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject,
int idChild, uint dwEventThread, uint dwmsEventTime);
public FullScreenApi(Action timerEventHandler)
{
this.timerEventHandler = new Action(() =>
{
LoggingHandler.LogMessage("Scheduler event triggered by fullscreen app closing");
timerEventHandler();
});
if (JsonConfig.settings.fullScreenPause)
{
SetFullScreenPause(true);
}
}
public void ToggleFullScreenPause()
{
bool fullScreenPause = JsonConfig.settings.fullScreenPause ^ true;
TrayMenu.fullScreenItem.Checked = fullScreenPause;
SetFullScreenPause(fullScreenPause);
JsonConfig.settings.fullScreenPause = fullScreenPause;
}
private void SetFullScreenPause(bool fullScreenPause)
{
if (fullScreenPause)
{
winEventProc = new WinEventDelegate(WinEventProc);
winEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
}
else
{
UnhookWinEvent(winEventHook);
}
}
private bool IsRunningFullScreen()
{
IntPtr desktopHandle = GetDesktopWindow();
IntPtr shellHandle = GetShellWindow();
IntPtr hWnd = GetForegroundWindow();
#pragma warning disable 0472
if (hWnd != null && !hWnd.Equals(IntPtr.Zero))
#pragma warning restore 0472
{
if (!(hWnd.Equals(desktopHandle) || hWnd.Equals(shellHandle)))
{
GetWindowRect(hWnd, out RECT appBounds);
System.Drawing.Rectangle screenBounds = System.Windows.Forms.Screen.FromHandle(hWnd).Bounds;
if ((appBounds.Bottom - appBounds.Top) == screenBounds.Height &&
(appBounds.Right - appBounds.Left) == screenBounds.Width)
{
return true;
}
}
}
return false;
}
private void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime)
{
runningFullScreen = IsRunningFullScreen();
if (!runningFullScreen && timerEventPending)
{
timerEventPending = false;
timerEventHandler.Invoke();
}
}
}
}