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