-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
153 lines (131 loc) · 4.15 KB
/
Copy pathmain.cpp
File metadata and controls
153 lines (131 loc) · 4.15 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <Windows.h>
#include <iostream>
#include <vector>
#include <winuser.h>
int posX = 0;
int posY = 0;
float horizontalV = 0.0f;
float verticalV = 0.0f;
float gravity = 0.8f;
float friction = 0.98f;
float bounceFactor = 0.5f;
bool isDragging = false; // If user dragged the window
struct Position {
int x, y;
DWORD timestamp;
};
std::vector<Position> recentPositions;
const int MAX_POSITION_HISTORY = 10;
const int MIN_DISTANCE = 50;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
#define IDT_TIMER1 1
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CREATE:
SetTimer(hwnd, IDT_TIMER1, 16, NULL); // ~60 FPS
return 0;
case WM_ENTERSIZEMOVE:
isDragging = true;
horizontalV = 0;
verticalV = 0;
return 0;
case WM_EXITSIZEMOVE: // Stopped dragging
isDragging = false;
RECT rect;
GetWindowRect(hwnd, &rect);
posX = rect.left;
posY = rect.top;
return 0;
case WM_MOVING: {
RECT *pRect = (RECT *)lParam;
DWORD currentTime = GetTickCount();
Position pos = {pRect->left, pRect->top, currentTime};
if (recentPositions.size() != 0) {
int dx = pos.x - recentPositions.back().x;
int dy = pos.y - recentPositions.back().y;
if (dx * dx + dy * dy < MIN_DISTANCE * MIN_DISTANCE)
return 0; // Skip insignificant jitter
}
std::cout << "X:" << pos.x << ", Y:" << pos.y << std::endl;
recentPositions.push_back(pos);
if (recentPositions.size() > MAX_POSITION_HISTORY) {
recentPositions.erase(recentPositions.begin());
}
// Calculate velocities
if (recentPositions.size() >= 2) {
Position &first = recentPositions.front();
Position &last = recentPositions.back();
float deltaTime = (last.timestamp - first.timestamp) / 1000.0f;
if (deltaTime < 0.05f)
deltaTime = 0.05f;
if (deltaTime > 0.0f) {
horizontalV = (last.x - first.x) / deltaTime;
verticalV = (last.y - first.y) / deltaTime;
}
}
break;
}
case WM_TIMER:
if (wParam == IDT_TIMER1 && !isDragging) {
RECT rect;
RECT workArea;
GetWindowRect(hwnd, &rect);
int windowHeight = rect.bottom - rect.top;
int windowWidth = rect.right - rect.left;
SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
int screenHeight = workArea.bottom - workArea.top;
int screenWidth = workArea.right - workArea.left;
verticalV += gravity;
verticalV *= friction;
horizontalV *= friction;
if (std::abs(horizontalV) < 0.01f)
horizontalV = 0;
posY += (int)verticalV;
posX += (int)horizontalV;
// Vertical bounce
if (posY <= 0) {
posY = 0;
verticalV = -verticalV * bounceFactor;
} else if (posY + windowHeight >= screenHeight) {
posY = screenHeight - windowHeight;
verticalV = -verticalV * bounceFactor;
}
// Horizontal bounce
if (posX <= 0) {
posX = 0;
horizontalV = -horizontalV * bounceFactor;
} else if (posX + windowWidth >= screenWidth) {
posX = screenWidth - windowWidth;
horizontalV = -horizontalV * bounceFactor;
}
SetWindowPos(hwnd, HWND_TOPMOST, posX, posY, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
}
return 0;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSW wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"BouncyWindowClass";
RegisterClassW(&wc);
HWND hwnd = CreateWindowExW(
WS_EX_TOPMOST, // Extended style
L"BouncyWindowClass", // Class name
L"bouncy", // Window title
WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, // Style
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}