-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathWindowOverlay_WIN32.cpp
More file actions
123 lines (106 loc) · 3.09 KB
/
Copy pathWindowOverlay_WIN32.cpp
File metadata and controls
123 lines (106 loc) · 3.09 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
#include "hacklib/WindowOverlay.h"
using namespace hl;
static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
/* criteria: owned by current process, visible, not a child window and client size > 0
- owned by current process
- visible
- not a child window
- created by main module (exe)
- client size > 0
*/
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid == GetCurrentProcessId())
{
LONG_PTR styles = GetWindowLongPtr(hWnd, GWL_STYLE);
HINSTANCE hinst = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
if ((styles & WS_VISIBLE) && !(styles & WS_CHILDWINDOW) && hinst == GetModuleHandle(NULL))
{
RECT rect;
GetClientRect(hWnd, &rect);
if (rect.right != 0 && rect.bottom != 0)
{
*(HWND*)lParam = hWnd;
}
}
}
return TRUE;
}
WindowHandle WindowOverlay::GetTargetWindow()
{
HWND hWnd = NULL;
EnumWindows(EnumWindowsProc, (LPARAM)&hWnd);
return hWnd;
}
void WindowOverlay::cbWindowLoop()
{
// this method makes sure that the overlay is always matching the target window
bool changeFound = false;
UINT setWndPosFlags = SWP_NOACTIVATE;
// window position changes
POINT pt = {};
if (!ClientToScreen(m_targetWindow, &pt) || (m_posX == pt.x && m_posY == pt.y))
{
setWndPosFlags |= SWP_NOMOVE;
}
else
{
m_posX = pt.x;
m_posY = pt.y;
changeFound = true;
}
// window size changes
RECT rect = {};
if (!GetClientRect(m_targetWindow, &rect) || (m_width == rect.right && m_height == rect.bottom))
{
setWndPosFlags |= SWP_NOSIZE;
}
else
{
m_width = rect.right;
m_height = rect.bottom;
changeFound = true;
}
// window visibility changes
HWND insertAfter = NULL;
HWND foregroundWindow = GetForegroundWindow();
bool isForeground = m_targetWindow == foregroundWindow;
if (m_isTargetForeground == isForeground)
{
setWndPosFlags |= SWP_NOZORDER;
}
else
{
m_isTargetForeground = isForeground;
changeFound = true;
if (m_isTargetForeground)
{
// Set to topmost so the target can keep being the foreground window.
insertAfter = HWND_TOPMOST;
}
else
{
// Get the window above the target so we can insert after that one.
insertAfter = GetWindow(m_targetWindow, GW_HWNDPREV);
if (!insertAfter)
{
// Nothing above the target. Just make the overlay no longer topmost.
insertAfter = HWND_NOTOPMOST;
}
}
}
if (changeFound && m_hWnd)
{
SetWindowPos(m_hWnd, insertAfter, m_posX, m_posY, m_width, m_height, setWndPosFlags);
}
// if size has changed, reset the overlay
if (getContext() && !(setWndPosFlags & SWP_NOSIZE))
{
if (m_cbPreReset)
m_cbPreReset();
resetContext();
if (m_cbPostReset)
m_cbPostReset();
}
}