X-Git-Url: https://gitweb.ps.run/autorec/blobdiff_plain/8d2244aefe172b5b1e15a32ad23991945d128f3a..0c40371e1f68c7e7020867b25c85521d947b3f47:/src/main.cpp diff --git a/src/main.cpp b/src/main.cpp index f4a47f3..5e6eba3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,11 +5,13 @@ #include "win.h" #include "ws.h" -#include "../res/resource.h" - #define LAY_IMPLEMENTATION #include "layout.h" +#include +#include +#include + #include #include #include @@ -17,16 +19,53 @@ #include #include +bool recording = false; +HANDLE process = NULL; +HWND hwnd; +HINSTANCE hInstance; +HICON icon_white, icon_green, icon_red; + +std::vector gameExes; + + +NOTIFYICONDATAA niData = { 0 }; +const UINT ICON_MSG = WM_APP+1; +void +ShowNotificationIcon() +{ + Shell_NotifyIconA(NIM_ADD, &niData); + Shell_NotifyIconA(NIM_SETVERSION, &niData); +} + +void +HideNotificationIcon() +{ + Shell_NotifyIconA(NIM_DELETE, &niData); +} + +void changeIcon(HWND hwnd, HICON icon) +{ + niData.hIcon = icon; + if (! IsWindowVisible(hwnd)) + Shell_NotifyIconA(NIM_MODIFY, &niData); + SendMessage(hwnd, WM_SETICON, 0, (LPARAM)icon); + SendMessage(hwnd, WM_SETICON, 1, (LPARAM)icon); +} + + + void startRecording() { - MessageBoxA(NULL, "Start", "Start Start", MB_OK); + ws::sendRequest("StartRecord"); + changeIcon(hwnd, icon_green); } void stopRecording() { - MessageBoxA(NULL, "Stop", "Stop Stop", MB_OK); + ws::sendRequest("StopRecord"); + changeIcon(hwnd, icon_red); } bool @@ -74,78 +113,186 @@ checkFullscreenWindow() } bool -checkNotepadWindow() +checkForegroundProcess(std::string exeName) { HWND fgHwnd = GetForegroundWindow(); HANDLE fgHandle = getHwndProcess(fgHwnd); - char filename[1024]; - int len = GetModuleFileNameExA(fgHandle, NULL, filename, 1024); + char filename[MAX_PATH]; + int len = GetModuleFileNameExA(fgHandle, NULL, filename, MAX_PATH); + + if (strcmp(filename, exeName.c_str()) == 0) + return true; + + PathStripPathA(filename); + + return strcmp(filename, exeName.c_str()) == 0; +} + +void ReadGameExes() +{ + std::ifstream ifs("games.txt"); + + gameExes.clear(); + + while (ifs) { + std::string str; + std::getline(ifs, str); + if (! str.empty()) + gameExes.push_back(str); + } + + ifs.close(); +} + +void WriteGameExes() +{ + std::ofstream ofs("games.txt", std::ios::trunc); + + for (const auto &exe : gameExes) + { + ofs.write(exe.c_str(), exe.size()); + ofs.write("\n", 1); + } + + ofs.close(); +} + +PROCESS_INFORMATION StartOBS() +{ + // delete .sentinel folder to stop obs from displaying + // error message on startup + system("del %appdata%\\obs-studio\\.sentinel /Q"); + + PROCESS_INFORMATION pi; + STARTUPINFOA sui; + GetStartupInfoA(&sui); + CreateProcessA(nullptr, "C:\\Program Files\\obs-studio\\bin\\64bit\\obs64.exe", + nullptr, nullptr, false, NORMAL_PRIORITY_CLASS, nullptr, "C:\\Program Files\\obs-studio\\bin\\64bit", &sui, &pi); + return pi; +} + +void StopOBS(PROCESS_INFORMATION &pi) +{ + EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL { + PROCESS_INFORMATION *pi = (PROCESS_INFORMATION*)lParam; + + DWORD pid, tid; + tid = GetWindowThreadProcessId(hwnd, &pid); + if (tid == pi->dwThreadId && pid == pi->dwProcessId) { + + char title[1024]; GetWindowTextA(hwnd, title, 1024); - return strcmp(filename, "C:\\Windows\\System32\\notepad.exe") == 0; + if (strncmp(title, "OBS", 3) == 0) { + PostMessage(hwnd, WM_CLOSE, 0, 0); + return FALSE; + } + } + return TRUE; + }, (LPARAM)&pi); } +/* +TODO: + - Disconnect while recording +*/ + + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +//int main(int argc, char **argv) { - bool recording = false; - HANDLE process = NULL; - - HWND window = win::Window("Title", "MyWindowClass", hInstance); - - lay_id row1 = lay_item(&win::_::ctx); - lay_insert(&win::_::ctx, win::_::root, row1); - lay_set_size_xy(&win::_::ctx, row1, 0, 25); - lay_set_behave(&win::_::ctx, row1, LAY_LEFT); - lay_set_contain(&win::_::ctx, row1, LAY_ROW); - lay_set_margins_ltrb(&win::_::ctx, row1, 5, 5, 5, 5); - lay_id row2 = lay_item(&win::_::ctx); - lay_insert(&win::_::ctx, win::_::root, row2); - lay_set_size_xy(&win::_::ctx, row2, 0, 0); - lay_set_behave(&win::_::ctx, row2, LAY_FILL); - lay_set_contain(&win::_::ctx, row2, LAY_ROW); - lay_id col1 = lay_item(&win::_::ctx); - lay_set_size_xy(&win::_::ctx, col1, 80, 0); - lay_set_behave(&win::_::ctx, col1, LAY_VCENTER); - lay_set_contain(&win::_::ctx, col1, LAY_COLUMN); - lay_set_margins_ltrb(&win::_::ctx, col1, 5, 0, 5, 0); - - HWND cbWindowTitle = win::CheckBox(window, "Window Title", row1, 100, 25, 0, 0); - HWND cbFullscreenWindow = win::CheckBox(window, "Any Fullscreen Application", row1, 200, 25, 0, 0); - - HWND btnConnect = win::Button(window, "Connect", row1, 100, 25, 0, 0); - win::Callback(btnConnect, BN_CLICKED, [&]() { - ws::connect("ws://127.0.0.1:4444"); + hInstance = GetModuleHandle(0); + + icon_white = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_WHITE)); + icon_green = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_GREEN)); + icon_red = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_RED)); + + win::Window window("Title", "MyWindowClass", hInstance); + hwnd = window.hwnd; + + niData.cbSize = sizeof(niData); + niData.uID = 12345; + niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + niData.hIcon = icon_white; + niData.hWnd = window.hwnd; + niData.uCallbackMessage = ICON_MSG; + niData.uVersion = NOTIFYICON_VERSION_4; + + PROCESS_INFORMATION pi_obs = StartOBS(); + + window.handlers[WM_SIZE].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (wParam == SIZE_MINIMIZED) { + ShowNotificationIcon(); + ShowWindow(hwnd, false); + } }); - - HWND btnIdentify = win::Button(window, "Identify", row1, 100, 25, 0, 0); - win::Callback(btnIdentify, BN_CLICKED, [&]() { - ws::identify(); + window.handlers[WM_DESTROY].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + HideNotificationIcon(); + }); + window.handlers[ICON_MSG].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (LOWORD(lParam) == NIN_SELECT) { + HideNotificationIcon(); + ShowWindow(hwnd, true); + SetForegroundWindow(hwnd); + SetActiveWindow(hwnd); + } }); - - win::Callback(cbWindowTitle, BN_CLICKED, [&]() { - SendMessageA(cbWindowTitle, BM_SETCHECK, SendMessageA(cbWindowTitle, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0); + window.handlers[WM_GETMINMAXINFO].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + MINMAXINFO *mmInfo = (MINMAXINFO*)lParam; + mmInfo->ptMinTrackSize.x = 400; + mmInfo->ptMinTrackSize.y = 200; }); - win::Callback(cbFullscreenWindow, BN_CLICKED, [&]() { - SendMessageA(cbFullscreenWindow, BM_SETCHECK, SendMessageA(cbFullscreenWindow, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0); + window.handlers[WM_QUERYENDSESSION].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + StopOBS(pi_obs); + }); window.handlers[WM_ENDSESSION].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + StopOBS(pi_obs); + }); + window.handlers[WM_CLOSE].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + StopOBS(pi_obs); + }); + + lay_context *ctx = &window.ctx; + lay_id root = window.lId; + + lay_id row1 = win::createLayId(&window.ctx, window.lId, 0, 25, LAY_ROW, LAY_LEFT); + lay_set_margins_ltrb(ctx, row1, 5, 5, 5, 5); + lay_id row2 = win::createLayId(&window.ctx, window.lId, 0, 0, LAY_ROW, LAY_FILL); + lay_set_margins_ltrb(ctx, row2, 5, 5, 5, 5); + + win::CheckBox cbWindowTitle(&window, "Window Title", row1, 100, 25, 0, 0); + win::CheckBox cbFullscreenWindow(&window, "Any Fullscreen Application", row1, 200, 25, 0, 0); + + win::Button btnConnect(&window, "Connect", row1, 100, 25, 0, 0); + btnConnect.onClick([&]() { + if (! ws::isConnected) + ws::connect("ws://127.0.0.1:4455"); }); - HWND lstActiveProcesses = win::ListBox(window, row2, 0, 0, 0, LAY_FILL); - lay_insert(&win::_::ctx, row2, col1); - HWND lstMonitoredProcesses = win::ListBox(window, row2, 0, 0, 0, LAY_FILL); - win::AddStyle(lstActiveProcesses, WS_VSCROLL); - win::AddStyle(lstMonitoredProcesses, WS_VSCROLL); - - HWND btnUpdateWindows = win::Button(window, "Update", col1, 85, 25, 0, 0); - HWND btnStartMonitoringName = win::Button(window, "Exe name >>", col1, 85, 25, 0, 0); - HWND btnStartMonitoringPath = win::Button(window, "Full path >>", col1, 85, 25, 0, 0); - HWND btnStopMonitoring = win::Button(window, "Remove", col1, 85, 25, 0, 0); - win::Callback(btnUpdateWindows, BN_CLICKED, [&]() { - win::ListClear(lstActiveProcesses); + win::ListBox lstActiveProcesses(&window, row2, 0, 0, 0, LAY_FILL); + + lay_id col1 = win::createLayId(&window.ctx, row2, 80, 0, LAY_COLUMN, LAY_VCENTER); + lstActiveProcesses.addStyle(WS_VSCROLL); + + lay_set_margins_ltrb(ctx, col1, 5, 0, 5, 0); + + win::ListBox lstMonitoredProcesses(&window, row2, 0, 0, 0, LAY_FILL); + lstMonitoredProcesses.addStyle(WS_VSCROLL); + + ReadGameExes(); + for (const auto &exe : gameExes) + lstMonitoredProcesses.addString(exe); + + win::Button btnUpdateWindows(&window, "Update", col1, 85, 25, 0, 0); + win::Button btnStartMonitoringName(&window, "Exe name >>", col1, 85, 25, 0, 0); + win::Button btnStartMonitoringPath(&window, "Full path >>", col1, 85, 25, 0, 0); + win::Button btnStopMonitoring(&window, "Remove", col1, 85, 25, 0, 0); + btnUpdateWindows.onClick([&]() { + lstActiveProcesses.clear(); for (HWND hwnd = GetTopWindow(NULL); hwnd != nullptr; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) { if (!IsWindowVisible(hwnd)) @@ -156,61 +303,92 @@ WinMain(HINSTANCE hInstance, char str[1024]; if (GetModuleFileNameExA(getHwndProcess(hwnd), 0, str, 1024) != 0 && - win::ListFindString(lstActiveProcesses, str) == LB_ERR) { - win::ListAddString(lstActiveProcesses, str); + lstActiveProcesses.findString(str) == LB_ERR) { + lstActiveProcesses.addString(str); } } }); - win::Callback(btnStartMonitoringName, BN_CLICKED, [&]() { - int sel = win::ListGetSelectedIndex(lstActiveProcesses); + btnStartMonitoringName.onClick([&]() { + int sel = lstActiveProcesses.getSelectedIndex(); if (sel < 0) return; - std::string selStr = win::ListGetText(lstActiveProcesses, sel); + std::string selStr = lstActiveProcesses.getText(sel); - char *filename = new char[selStr.size()]; + char *filename = new char[selStr.size()+1]; std::memcpy(filename, selStr.c_str(), selStr.size()); + filename[selStr.size()] = '\0'; PathStripPathA(filename); - if (win::ListFindString(lstMonitoredProcesses, std::string(filename)) == LB_ERR) - win::ListAddString(lstMonitoredProcesses, std::string(filename)); + std::string filenameStr(filename); + + if (lstMonitoredProcesses.findString(filenameStr) == LB_ERR) + { + lstMonitoredProcesses.addString(filenameStr); + gameExes.push_back(filenameStr); + WriteGameExes(); + } delete[] filename; }); - win::Callback(btnStartMonitoringPath, BN_CLICKED, [&]() { - int sel = win::ListGetSelectedIndex(lstActiveProcesses); + btnStartMonitoringPath.onClick([&]() { + int sel = lstActiveProcesses.getSelectedIndex(); if (sel < 0) return; - std::string selStr = win::ListGetText(lstActiveProcesses, sel); - if (win::ListFindString(lstMonitoredProcesses, selStr) == LB_ERR) - win::ListAddString(lstMonitoredProcesses, selStr); + std::string selStr = lstActiveProcesses.getText(sel); + if (lstMonitoredProcesses.findString(selStr) == LB_ERR) + { + lstMonitoredProcesses.addString(selStr); + gameExes.push_back(selStr); + WriteGameExes(); + } }); - win::Callback(btnStopMonitoring, BN_CLICKED, [&]() { - int sel = win::ListGetSelectedIndex(lstMonitoredProcesses); + btnStopMonitoring.onClick([&]() { + int sel = lstMonitoredProcesses.getSelectedIndex(); if (sel < 0) return; - win::ListRemove(lstMonitoredProcesses, sel); + lstMonitoredProcesses.remove(sel); + gameExes.erase(gameExes.begin() + sel); + WriteGameExes(); }); - - win::ShowNotificationIcon(hInstance, window); - - win::ShowWindow(window); - + window.show(); + window.setDefaultFont(); + + ws::onConnect = [&]() { + changeIcon(window.hwnd, icon_red); + btnConnect.setActive(false); + }; + ws::onClose = [&]() { + changeIcon(window.hwnd, icon_white); + btnConnect.setActive(true); + }; + ws::onError = ws::onClose; ws::init(); - while (win::UpdateWindow(window)) { - ws::update(); + window.setTimer(1000, [&btnConnect]() { + if (! ws::isConnected) + ws::connect("ws://127.0.0.1:4455"); + }); + window.setTimer(100, []() { if (!recording) { - if (checkNotepadWindow()) { - process = getHwndProcess(GetForegroundWindow()); - startRecording(); - recording = true; + for (auto exe : gameExes) { + if (checkForegroundProcess(exe)) { + recording = true; + process = getHwndProcess(GetForegroundWindow()); + startRecording(); + } } } else { if (!checkProcessRunning(process)) { + recording = false; process = NULL; stopRecording(); - recording = false; } } + }); + + while (window.update()) { + ws::update(); } + + return 0; }