]> gitweb.ps.run Git - autorec/blob - src/main.cpp
Makefile, auto ico
[autorec] / src / main.cpp
1 #ifndef WIN32\r
2   #define WIN32\r
3 #endif\r
4 #include <WinSock2.h>\r
5 #include "win.h"\r
6 #include "ws.h"\r
7 \r
8 #define LAY_IMPLEMENTATION\r
9 #include "layout.h"\r
10 \r
11 #include <Psapi.h>\r
12 #include <stdbool.h>\r
13 #include <stdio.h>\r
14 #include <string.h>\r
15 #include <windows.h>\r
16 #include <shlwapi.h>\r
17 \r
18 bool recording = false;\r
19 HANDLE process = NULL;\r
20 HWND hwnd;\r
21 HINSTANCE hInstance;\r
22 \r
23 \r
24 NOTIFYICONDATAA niData = { 0 };\r
25 const UINT ICON_MSG = WM_APP+1;\r
26 void\r
27 ShowNotificationIcon()\r
28 {\r
29   Shell_NotifyIconA(NIM_ADD, &niData);\r
30   Shell_NotifyIconA(NIM_SETVERSION, &niData);\r
31 }\r
32 \r
33 void\r
34 HideNotificationIcon()\r
35 {\r
36   Shell_NotifyIconA(NIM_DELETE, &niData);\r
37 }\r
38 \r
39 void changeIcon(HWND hwnd, HINSTANCE hInstance, WORD id)\r
40 {\r
41   HICON icon = LoadIcon(hInstance, MAKEINTRESOURCE(id));\r
42   niData.hIcon = icon;\r
43   if (! IsWindowVisible(hwnd))\r
44     Shell_NotifyIconA(NIM_MODIFY, &niData);\r
45   SendMessage(hwnd, WM_SETICON, 0, (LPARAM)icon);\r
46   SendMessage(hwnd, WM_SETICON, 1, (LPARAM)icon);\r
47 }\r
48 \r
49 \r
50 \r
51 void\r
52 startRecording()\r
53 {\r
54   ws::sendRequest("StartRecord");\r
55   changeIcon(hwnd, hInstance, IDI_ICON_GREEN);\r
56 }\r
57 \r
58 void\r
59 stopRecording()\r
60 {\r
61   ws::sendRequest("StopRecord");\r
62   changeIcon(hwnd, hInstance, IDI_ICON_RED);\r
63 }\r
64 \r
65 bool\r
66 checkProcessRunning(HANDLE handle)\r
67 {\r
68   DWORD exit_code;\r
69 \r
70   if (handle != NULL && GetExitCodeProcess(handle, &exit_code)) {\r
71     return exit_code == STILL_ACTIVE;\r
72   }\r
73 \r
74   return false;\r
75 }\r
76 \r
77 HANDLE\r
78 getHwndProcess(HWND hwnd)\r
79 {\r
80   DWORD processId, threadId = GetWindowThreadProcessId(hwnd, &processId);\r
81   return OpenProcess(PROCESS_QUERY_INFORMATION, false, processId);\r
82 }\r
83 \r
84 // HWND getProcessHwnd(HANDLE handle) {}\r
85 \r
86 bool\r
87 checkFullscreenWindow()\r
88 {\r
89   HWND desktopHwnd = GetDesktopWindow();\r
90   HWND fgHwnd = GetForegroundWindow();\r
91 \r
92   if (fgHwnd != desktopHwnd && fgHwnd != GetShellWindow()) {\r
93     RECT windowRect, desktopRect;\r
94     // Get Window and Desktop size\r
95     GetWindowRect(fgHwnd, &windowRect);\r
96     GetWindowRect(desktopHwnd, &desktopRect);\r
97 \r
98     bool fullscreen = windowRect.bottom == desktopRect.bottom &&\r
99                       windowRect.top == desktopRect.top &&\r
100                       windowRect.left == desktopRect.left &&\r
101                       windowRect.right == desktopRect.right;\r
102 \r
103     return fullscreen;\r
104   }\r
105 \r
106   return false;\r
107 }\r
108 \r
109 bool\r
110 checkForegroundProcess(std::string exeName)\r
111 {\r
112   HWND fgHwnd = GetForegroundWindow();\r
113   HANDLE fgHandle = getHwndProcess(fgHwnd);\r
114 \r
115   char filename[1024];\r
116   int len = GetModuleFileNameExA(fgHandle, NULL, filename, 1024);\r
117   PathStripPathA(filename);\r
118 \r
119   return strcmp(filename, exeName.c_str()) == 0;\r
120 }\r
121 \r
122 int WINAPI\r
123 WinMain(HINSTANCE hInstance,\r
124         HINSTANCE hPrevInstance,\r
125         LPSTR lpCmdLine,\r
126         int nCmdShow)\r
127 //int main(int argc, char **argv)\r
128 {\r
129   hInstance = GetModuleHandle(0);\r
130 \r
131   win::Window window("Title", "MyWindowClass", hInstance);\r
132   hwnd = window.hwnd;\r
133 \r
134   niData.cbSize = sizeof(niData);\r
135   niData.uID = 12345;\r
136   niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;\r
137   niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_WHITE));\r
138   niData.hWnd = window.hwnd;\r
139   niData.uCallbackMessage = ICON_MSG;\r
140   niData.uVersion = NOTIFYICON_VERSION_4;\r
141 \r
142   window.handlers[WM_SIZE].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
143     if (wParam == SIZE_MINIMIZED) {\r
144       ShowNotificationIcon();\r
145       ShowWindow(hwnd, false);\r
146     }\r
147   });\r
148   window.handlers[WM_DESTROY].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
149     HideNotificationIcon();\r
150   });  \r
151   window.handlers[ICON_MSG].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
152     if (LOWORD(lParam) == NIN_SELECT) {\r
153       HideNotificationIcon();\r
154       ShowWindow(hwnd, true);\r
155       SetForegroundWindow(hwnd);\r
156       SetActiveWindow(hwnd);\r
157     }\r
158   });\r
159 \r
160   window.handlers[WM_GETMINMAXINFO].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
161           MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;\r
162           mmInfo->ptMinTrackSize.x = 400;\r
163           mmInfo->ptMinTrackSize.y = 200;\r
164   });\r
165 \r
166   lay_context *ctx = &window.ctx;\r
167   lay_id root = window.lId;\r
168 \r
169   lay_id row1 = win::createLayId(&window.ctx, window.lId, 0, 25, LAY_ROW, LAY_LEFT);\r
170   lay_set_margins_ltrb(ctx, row1, 5, 5, 5, 5);\r
171   lay_id row2 = win::createLayId(&window.ctx, window.lId, 0, 0, LAY_ROW, LAY_FILL);\r
172   lay_set_margins_ltrb(ctx, row2, 5, 5, 5, 5);\r
173 \r
174   win::CheckBox cbWindowTitle(&window, "Window Title", row1, 100, 25, 0, 0);\r
175   win::CheckBox cbFullscreenWindow(&window, "Any Fullscreen Application", row1, 200, 25, 0, 0);\r
176 \r
177   win::Button btnConnect(&window, "Connect", row1, 100, 25, 0, 0);\r
178   btnConnect.onClick([&]() {\r
179     ws::connect("ws://127.0.0.1:4444");\r
180   });\r
181   win::Button btnTest(&window, "Test", row1, 100, 25, 0, 0);\r
182   btnTest.onClick([&]() {\r
183     changeIcon(window.hwnd, hInstance, IDI_ICON_GREEN);\r
184   });\r
185 \r
186   win::ListBox lstActiveProcesses(&window, row2, 0, 0, 0, LAY_FILL);\r
187   \r
188   lay_id col1 = win::createLayId(&window.ctx, row2, 80, 0, LAY_COLUMN, LAY_VCENTER);\r
189   lstActiveProcesses.addStyle(WS_VSCROLL);\r
190 \r
191   lay_set_margins_ltrb(ctx, col1, 5, 0, 5, 0);\r
192 \r
193   win::ListBox lstMonitoredProcesses(&window, row2, 0, 0, 0, LAY_FILL);\r
194   lstMonitoredProcesses.addStyle(WS_VSCROLL);\r
195 \r
196   win::Button btnUpdateWindows(&window, "Update", col1, 85, 25, 0, 0);\r
197   win::Button btnStartMonitoringName(&window, "Exe name >>", col1, 85, 25, 0, 0);\r
198   win::Button btnStartMonitoringPath(&window, "Full path >>", col1, 85, 25, 0, 0);\r
199   win::Button btnStopMonitoring(&window, "Remove", col1, 85, 25, 0, 0);\r
200   btnUpdateWindows.onClick([&]() {\r
201     lstActiveProcesses.clear();\r
202     for (HWND hwnd = GetTopWindow(NULL); hwnd != nullptr;\r
203          hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {\r
204       if (!IsWindowVisible(hwnd))\r
205         continue;\r
206 \r
207       RECT rect;\r
208       GetWindowRect(hwnd, &rect);\r
209 \r
210       char str[1024];\r
211       if (GetModuleFileNameExA(getHwndProcess(hwnd), 0, str, 1024) != 0 &&\r
212           lstActiveProcesses.findString(str) == LB_ERR) {\r
213         lstActiveProcesses.addString(str);\r
214       }\r
215     }\r
216   });\r
217   btnStartMonitoringName.onClick([&]() {\r
218     int sel = lstActiveProcesses.getSelectedIndex();\r
219     if (sel < 0) return;\r
220 \r
221     std::string selStr = lstActiveProcesses.getText(sel);\r
222     \r
223     char *filename = new char[selStr.size()];\r
224     std::memcpy(filename, selStr.c_str(), selStr.size());\r
225     PathStripPathA(filename);\r
226 \r
227     if (lstMonitoredProcesses.findString(std::string(filename)) == LB_ERR)\r
228       lstMonitoredProcesses.addString(std::string(filename));\r
229 \r
230     delete[] filename;\r
231   });\r
232   btnStartMonitoringPath.onClick([&]() {\r
233     int sel = lstActiveProcesses.getSelectedIndex();\r
234     if (sel < 0) return;\r
235     std::string selStr = lstActiveProcesses.getText(sel);\r
236     if (lstMonitoredProcesses.findString(selStr) == LB_ERR)\r
237     lstMonitoredProcesses.addString(selStr);\r
238   });\r
239   btnStopMonitoring.onClick([&]() {\r
240     int sel = lstMonitoredProcesses.getSelectedIndex();\r
241     if (sel < 0) return;\r
242     lstMonitoredProcesses.remove(sel);\r
243   });\r
244 \r
245   window.show();\r
246   window.setDefaultFont();\r
247 \r
248   ws::onConnect = [&]() {\r
249     changeIcon(window.hwnd, hInstance, IDI_ICON_RED);\r
250   };\r
251   ws::init();\r
252 \r
253   SetTimer(window.hwnd, 10123, 100, [](HWND, UINT, UINT_PTR, DWORD) {\r
254     if (!recording) {\r
255       if (checkForegroundProcess("League of Legends.exe")) {\r
256         recording = true;\r
257         process = getHwndProcess(GetForegroundWindow());\r
258         startRecording();\r
259       }\r
260     } else {\r
261       if (!checkProcessRunning(process)) {\r
262         recording = false;\r
263         process = NULL;\r
264         stopRecording();\r
265       }\r
266     }\r
267   });\r
268 \r
269   while (window.update()) {\r
270     ws::update();\r
271   }\r
272 \r
273   return 0;\r
274 }\r