-
Notifications
You must be signed in to change notification settings - Fork 1
/
FlippyWindow.cpp
135 lines (119 loc) · 4.43 KB
/
FlippyWindow.cpp
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
134
135
// Copyright (c) 2016-2018 Damien Dart, <https://www.robotinaponcho.net/>.
// This file is distributed under the MIT licence. For more information,
// please refer to the accompanying "LICENCE" file.
#include <windows.h>
#include <magnification.h>
#include <VersionHelpers.h>
#include "FlippyWindow.h"
DWORD ErrorMessage(LPTSTR message)
{
// TODO: Add to message with "GetLastError" and "FormatMessage".
MessageBox(NULL, message, TEXT("FlippyWindow"), MB_OK | MB_ICONERROR);
return 0; // TODO: Find a more appropriate return value?
}
LRESULT CALLBACK HostWndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
switch (message) {
LRESULT cursorPosition;
RECT hostClientRect;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_EXIT:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
case ID_HOMEPAGE:
ShellExecute(NULL, "open", "https://www.robotinaponcho.net/projects/flippywindow/",
NULL, NULL, SW_SHOWNORMAL);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_NCHITTEST:
// Allow the window to be draggable by its client area.
cursorPosition = DefWindowProc(hWnd, message, wParam, lParam);
return (cursorPosition == HTCLIENT ? HTCAPTION : cursorPosition);
case WM_SIZE:
GetClientRect(hWnd, &hostClientRect);
SetWindowPos(GetWindow(hWnd, GW_CHILD), NULL, hostClientRect.left,
hostClientRect.top, hostClientRect.right, hostClientRect.bottom, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void CALLBACK UpdateMagnificationWindow(HWND hWnd, UINT uMsg,
UINT_PTR idEvent, DWORD dwTime)
{
MAGTRANSFORM magnifierTranformationMatrix;
RECT magnificationSourceRect;
GetWindowRect(hWnd, &magnificationSourceRect);
magnifierTranformationMatrix = {-1.0f, 0,
(float)(magnificationSourceRect.right - magnificationSourceRect.left),
0, 1.0f, 0, 0, 0, 1.0f};
MagSetWindowTransform(hWnd, &magnifierTranformationMatrix);
MagSetWindowSource(hWnd, magnificationSourceRect);
InvalidateRect(hWnd, NULL, TRUE);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwndHost, hwndMagnifier;
MSG msg;
UINT_PTR timerId;
// FlippyWindow (ab)uses the second release of the Magnification API
// which is only available on Windows 8 and later operating systems.
if (!IsWindows8OrGreater()) {
return ErrorMessage("Windows 8 or later is required.");
}
if (MagInitialize()) {
WNDCLASSEX wcex = {};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(FLIPPYWINDOWICON), IMAGE_ICON, 0, 0,
LR_DEFAULTCOLOR | LR_SHARED | LR_DEFAULTSIZE);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = HostWndProc;
wcex.lpszClassName = TEXT("FlippyWindowWindow");
wcex.lpszMenuName = MAKEINTRESOURCE(FLIPPYWINDOWMENU);
wcex.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wcex);
hwndHost = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED,
TEXT("FlippyWindowWindow"), TEXT("FlippyWindow"),
WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
GetSystemMetrics(SM_CXSCREEN) / 2, GetSystemMetrics(SM_CYSCREEN) / 2,
NULL, NULL, hInstance, NULL);
if (hwndHost) {
RECT hostClientRect;
SetLayeredWindowAttributes(hwndHost, 0, 255, LWA_ALPHA);
GetClientRect(hwndHost, &hostClientRect);
hwndMagnifier = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"),
WS_CHILD | WS_VISIBLE, 0, 0, hostClientRect.right,
hostClientRect.bottom, hwndHost, NULL, hInstance, NULL);
if (!hwndMagnifier) {
return ErrorMessage(TEXT("Unable to create magnification window."));
}
} else {
return ErrorMessage(TEXT("Unable to create main window."));
}
} else {
return ErrorMessage(
TEXT("Unable to initialise magnification run-time objects."));
}
ShowWindow(hwndHost, nCmdShow);
UpdateWindow(hwndHost);
// Update the magnification window 60 times a second.
timerId = SetTimer(hwndMagnifier, 0, 16, UpdateMagnificationWindow);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KillTimer(NULL, timerId);
MagUninitialize();
return (int)msg.wParam;
}