-
Notifications
You must be signed in to change notification settings - Fork 6
/
utils.pas
133 lines (118 loc) · 3.99 KB
/
utils.pas
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
129
130
131
132
133
unit utils;
interface
uses
Windows, Forms, Classes, TLHelp32, PsAPI, SysUtils, Registry, Graphics, DWMAPI,
OleAcc, Variants, DirectDraw, ActiveX, ShellAPI;
function IsDirectXAppRunningFullScreen: Boolean;
function DetectFullScreen3D: Boolean;
function DetectFullScreenApp(AHandle: HWND = 0): Boolean;
function IsDesktopWindow(AHandle: HWND): Boolean;
implementation
function GetShellWindow:HWND;stdcall;
external user32 Name 'GetShellWindow';
function IsDirectXAppRunningFullScreen: Boolean;
var
LSPI: Boolean;
begin
Result := False;
if SystemParametersInfo(SPI_GETCURSORSHADOW, 0, @LSPI, 0) and not LSPI then
begin
if SystemParametersInfo(SPI_GETHOTTRACKING, 0, @LSPI, 0) and not LSPI then
begin
Result := DetectFullScreen3D;
end;
end;
end;
function DetectFullScreen3D: Boolean;
var
DW: IDirectDraw7;
HR: HRESULT;
begin
Result := False;
HR := coinitialize(nil);
if Succeeded(HR) then
begin
HR := DirectDrawCreateEx(PGUID(DDCREATE_EMULATIONONLY), DW, IDirectDraw7, nil);
if HR = DD_OK then
begin
HR := DW.TestCooperativeLevel;
if HR = DDERR_EXCLUSIVEMODEALREADYSET then
Result := True;
end;
end;
CoUninitialize;
end;
function DetectFullScreenApp(AHandle: HWND = 0): Boolean;
var
curwnd: HWND;
wndPlm: WINDOWPLACEMENT;
R: TRect;
Mon: TMonitor;
begin
Result := False;
if AHandle = 0 then
curwnd := GetForegroundWindow
else
curwnd := AHandle;
if curwnd <= 0 then Exit;
// ignore maximized windows with caption bar
if GetWindowLong(curwnd, GWL_STYLE) and WS_CAPTION = WS_CAPTION then
Exit;
if not IsWindow(curwnd) then Exit;
if IsDesktopWindow(curwnd) then Exit;
Mon := Screen.MonitorFromWindow(curwnd);
{ TODO : This workaround kind of fixes, but it blocks on fast fullscreen apps detection leaving them as if it were full app, }
// if Assigned(Mon) then //o fix Mon.BoundsRect EAccessViolation ... added Assigned(Mon) to following 2 comparisons
begin
GetWindowRect(curwnd, R);
GetWindowPlacement(curwnd, wndPlm);
if (wndPlm.showCmd and SW_SHOWMAXIMIZED) = SW_SHOWMAXIMIZED then
begin
if Assigned(Mon) and (Mon.BoundsRect.Width = R.Width) and (Mon.BoundsRect.Height = R.Height) then
Result := True;
end
else
begin
// some applications do not set SW_SHOWMAXIMIZED flag e.g. MPC-HC media player
// ignore maximized when workarearect is similar (i.e. taskbar is on top, might not be the same on secondary monitor)
// if IsTaskbarAlwaysOnTop then
// begin
// if (Screen.MonitorCount > 1) and (Mon.Handle =
// if ((Screen.MonitorCount > 1) and (FindWindow('Shell_SecondaryTrayWnd', nil)<>0) and (Mon.WorkareaRect <> Mon.BoundsRect))
// // if there is another monitor without taskbar then
// or ((Screen.MonitorCount > 1) and (FindWindow('Shell_SecondaryTrayWnd', nil)=0) and (Mon.WorkareaRect = Mon.BoundsRect))
// then
begin
if Assigned(Mon) and (Mon.BoundsRect.Width = R.Width) and (Mon.BoundsRect.Height = R.Height) then
Result := True;
// end;
end;
end;
end;
end;
// detect desktop is present
// those are different on specific conditions, like slideshow, win10 special features, and maybe third party tools installed for desktop handling
function IsDesktopWindow(AHandle: HWND): Boolean;
var
AppClassName: array[0..255] of char;
ChildHwnd: HWND;
begin
Result := False;
if AHandle = GetDesktopWindow then Result := True
else if AHandle = GetShellWindow then Result := True
else
begin
GetClassName(AHandle, AppClassName, 255);
if AppClassName = 'WorkerW' then
begin
// it should have a children with 'SHELLDLL_DefView' present
ChildHwnd := FindWindowEx(AHandle, 0, 'SHELLDLL_DefView', nil);
if ChildHwnd <> 0 then
begin
//if DetectFullScreenApp(AHandle) then
Result := True;
end;
end;
end;
end;
end.