Compare commits
	
		
			No commits in common. "1b2ef4240d01839d4fc9e4232bf5294baaae0f80" and "c076fd969ef45a47852b3d0c0394e553e46bdc8b" have entirely different histories.
		
	
	
		
			1b2ef4240d
			...
			c076fd969e
		
	
		
| @ -1,5 +1,5 @@ | |||||||
| # Mainspring app CMakeLists.txt | # Mainspring app CMakeLists.txt | ||||||
| add_executable(Mainspring WIN32 "src/main.cpp" "src/pch.h" "src/Application.h" "src/Application.cpp" "resource.rc" "src/resources.h" "src/utility.h" "src/utility.cpp") | add_executable(Mainspring WIN32 "src/main.cpp" "src/pch.h" "src/Application.h" "src/Application.cpp" "resource.rc" "src/resources.h") | ||||||
| 
 | 
 | ||||||
| set_property(TARGET Mainspring PROPERTY CXX_STANDARD 20) | set_property(TARGET Mainspring PROPERTY CXX_STANDARD 20) | ||||||
| 
 | 
 | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 6.0 KiB | 
| @ -2,61 +2,12 @@ | |||||||
| #include "windows.h" | #include "windows.h" | ||||||
| #include "winres.h" | #include "winres.h" | ||||||
| #include "src/resources.h" | #include "src/resources.h" | ||||||
| #include "version.h" |  | ||||||
| 
 | 
 | ||||||
| IDI_ICONMAIN ICON "res/mainspring.ico" | IDD_DIALOGMAIN DIALOGEX 0, 0, 175, 75 | ||||||
| 
 |  | ||||||
| IDR_MENUMAIN MENU |  | ||||||
| BEGIN |  | ||||||
|     POPUP "&File" |  | ||||||
|     BEGIN |  | ||||||
|         MENUITEM "&Reset\tCtrl+R" ID_FILE_RESET |  | ||||||
|         MENUITEM "&Save Time\tCtrl+S" ID_FILE_SAVE |  | ||||||
|         MENUITEM "Save Time &As...\tCtrl+Shift+S" ID_FILE_SAVEAS |  | ||||||
|         MENUITEM "&Open Time\tCtrl+O" ID_FILE_OPEN |  | ||||||
|         MENUITEM SEPARATOR |  | ||||||
|         MENUITEM "&Exit\tAlt+F4" ID_FILE_EXIT |  | ||||||
|     END |  | ||||||
| 
 |  | ||||||
|     POPUP "&Help" |  | ||||||
|     BEGIN |  | ||||||
|         MENUITEM "&About" ID_HELP_ABOUT |  | ||||||
|     END |  | ||||||
| END |  | ||||||
| 
 |  | ||||||
| IDD_DIALOGMAIN DIALOGEX 0, 0, 200, 70 |  | ||||||
| STYLE WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT | STYLE WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| MENU IDR_MENUMAIN |  | ||||||
| BEGIN | BEGIN | ||||||
|     CTEXT "APPNAME", IDC_STATICTITLE, 0, 0, 200, 20, SS_CENTERIMAGE |     CTEXT "APPNAME", IDC_STATICTITLE, 30, 5, 115, 20, SS_CENTERIMAGE | ||||||
|     CTEXT "TIME", IDC_STATICTIME, 8, 20, 184, 28, SS_CENTERIMAGE | SS_SUNKEN |     CTEXT "TIME", IDC_STATICTIME, 10, 25, 155, 25, SS_CENTERIMAGE | ||||||
|     DEFPUSHBUTTON "STARTPAUSE" IDC_BUTTONSTARTPAUSE, 75, 53, 50, 15 |     DEFPUSHBUTTON "STARTPAUSE" IDC_BUTTONSTARTPAUSE, 63, 55, 50, 15 | ||||||
| END |  | ||||||
| 
 |  | ||||||
| IDA_ACCELMAIN ACCELERATORS |  | ||||||
| BEGIN |  | ||||||
|     "R",    ID_FILE_RESET,    CONTROL, VIRTKEY |  | ||||||
|     "S",    ID_FILE_SAVE,   CONTROL, VIRTKEY |  | ||||||
|     "S",    ID_FILE_SAVEAS, CONTROL, SHIFT, VIRTKEY |  | ||||||
|     "O",    ID_FILE_OPEN,   CONTROL, VIRTKEY |  | ||||||
| END |  | ||||||
| 
 |  | ||||||
| VS_VERSION_INFO VERSIONINFO |  | ||||||
| BEGIN |  | ||||||
|     BLOCK "StringFileInfo" |  | ||||||
|     BEGIN |  | ||||||
|         BLOCK "040904b0" |  | ||||||
|         BEGIN |  | ||||||
|             VALUE "CompanyName", "Grayson Riffe" |  | ||||||
|             VALUE "FileDescription", "Mainspring" |  | ||||||
|             VALUE "ProductName", "Mainspring - A simple timekeeper" |  | ||||||
|             VALUE "ProductVersion", APPVERSION |  | ||||||
|             VALUE "LegalCopyright", "Copyright (C) 2025" |  | ||||||
|         END |  | ||||||
|     END |  | ||||||
|     BLOCK "VarFileInfo" |  | ||||||
|     BEGIN |  | ||||||
|         VALUE "Translation", 0x409, 1200 |  | ||||||
|     END |  | ||||||
| END | END | ||||||
| @ -2,14 +2,6 @@ | |||||||
| #include "pch.h" | #include "pch.h" | ||||||
| #include "Application.h" | #include "Application.h" | ||||||
| #include "resources.h" | #include "resources.h" | ||||||
| #include "utility.h" |  | ||||||
| 
 |  | ||||||
| // Define timer IDs
 |  | ||||||
| #define IDT_UPDATEAPP 1 |  | ||||||
| #define IDT_SAVEDTEXT 2 |  | ||||||
| 
 |  | ||||||
| // Define window message to update the timer display
 |  | ||||||
| #define WM_UPDATEAPP WM_USER + 1 |  | ||||||
| 
 | 
 | ||||||
| // Enable visual styles
 | // Enable visual styles
 | ||||||
| #pragma comment(linker, "\"/manifestdependency:type='win32' \ | #pragma comment(linker, "\"/manifestdependency:type='win32' \ | ||||||
| @ -20,31 +12,12 @@ namespace mainspring { | |||||||
|     Application::Application(const char* appName, const char* appVersion) |     Application::Application(const char* appName, const char* appVersion) | ||||||
|         : m_appName(appName) |         : m_appName(appName) | ||||||
|         , m_appVersion(appVersion) |         , m_appVersion(appVersion) | ||||||
|         , m_dlg() |  | ||||||
|         , m_timing(false) |  | ||||||
|         , m_startpauseButtonPressed(false) |  | ||||||
|         , m_elapsedSaved() |  | ||||||
|         , m_startTime() |  | ||||||
|         , m_file() |  | ||||||
|         , m_showSavedText(false) |  | ||||||
|     { |     { | ||||||
|         std::cout << std::format("{} {}\n", m_appName, m_appVersion); |         std::cout << std::format("{} {}\n", m_appName, m_appVersion); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void Application::run() { |     void Application::run() { | ||||||
|         std::string configPath = getConfigPath(); |         DialogBoxParam(nullptr, MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, reinterpret_cast<DLGPROC>(mainDlgProc), reinterpret_cast<LPARAM>(this)); | ||||||
|         std::string recentFile; |  | ||||||
|         if (readFile(configPath.c_str(), recentFile) && !recentFile.empty()) |  | ||||||
|             open(recentFile); |  | ||||||
| 
 |  | ||||||
|         m_dlg = CreateDialogParam(nullptr, MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, reinterpret_cast<DLGPROC>(mainDlgProc), reinterpret_cast<LPARAM>(this)); |  | ||||||
| 
 |  | ||||||
|         HACCEL hAccel = LoadAccelerators(GetModuleHandle(NULL), MAKEINTRESOURCE(IDA_ACCELMAIN)); |  | ||||||
|         MSG msg = {}; |  | ||||||
|         ShowWindow(m_dlg, SW_SHOW); |  | ||||||
|         while (GetMessage(&msg, nullptr, 0, 0)) |  | ||||||
|             if (!TranslateAccelerator(m_dlg, hAccel, &msg)) |  | ||||||
|                 IsDialogMessage(m_dlg, &msg); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { |     BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { | ||||||
| @ -55,7 +28,6 @@ namespace mainspring { | |||||||
|                 app = reinterpret_cast<Application*>(lParam); |                 app = reinterpret_cast<Application*>(lParam); | ||||||
| 
 | 
 | ||||||
|                 SetWindowText(dlg, app->m_appName); |                 SetWindowText(dlg, app->m_appName); | ||||||
|                 SendMessage(dlg, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICONMAIN)))); |  | ||||||
| 
 | 
 | ||||||
|                 POINT cursor = {}; |                 POINT cursor = {}; | ||||||
|                 GetCursorPos(&cursor); |                 GetCursorPos(&cursor); | ||||||
| @ -64,206 +36,30 @@ namespace mainspring { | |||||||
|                 GetMonitorInfo(MonitorFromPoint(cursor, MONITOR_DEFAULTTONEAREST), &mi); |                 GetMonitorInfo(MonitorFromPoint(cursor, MONITOR_DEFAULTTONEAREST), &mi); | ||||||
|                 SetWindowPos(dlg, nullptr, mi.rcMonitor.left + 100, mi.rcMonitor.top + 100, 0, 0, SWP_NOZORDER | SWP_NOSIZE); |                 SetWindowPos(dlg, nullptr, mi.rcMonitor.left + 100, mi.rcMonitor.top + 100, 0, 0, SWP_NOZORDER | SWP_NOSIZE); | ||||||
| 
 | 
 | ||||||
|  |                 SetDlgItemText(dlg, IDC_STATICTITLE, app->m_appName); | ||||||
|                 LOGFONT lFont = {}; |                 LOGFONT lFont = {}; | ||||||
|                 lFont.lfHeight = 30; |                 lFont.lfHeight = 30; | ||||||
|                 HFONT titleFont = CreateFontIndirect(&lFont); |                 HFONT titleFont = CreateFontIndirect(&lFont); | ||||||
|                 SendMessage(GetDlgItem(dlg, IDC_STATICTITLE), WM_SETFONT, reinterpret_cast<WPARAM>(titleFont), NULL); |                 SendMessage(GetDlgItem(dlg, IDC_STATICTITLE), WM_SETFONT, reinterpret_cast<WPARAM>(titleFont), NULL); | ||||||
| 
 | 
 | ||||||
|                 std::memcpy(lFont.lfFaceName, "Consolas", 9); |                 lFont.lfHeight = 40; | ||||||
|                 lFont.lfHeight = 60; |  | ||||||
|                 HFONT timeFont = CreateFontIndirect(&lFont); |                 HFONT timeFont = CreateFontIndirect(&lFont); | ||||||
|                 SendMessage(GetDlgItem(dlg, IDC_STATICTIME), WM_SETFONT, reinterpret_cast<WPARAM>(timeFont), NULL); |                 SendMessage(GetDlgItem(dlg, IDC_STATICTIME), WM_SETFONT, reinterpret_cast<WPARAM>(timeFont), NULL); | ||||||
| 
 | 
 | ||||||
|                 SendMessage(dlg, WM_UPDATEAPP, NULL, NULL); |                 SetDlgItemText(dlg, IDC_BUTTONSTARTPAUSE, "Start"); | ||||||
|                 SetTimer(dlg, IDT_UPDATEAPP, 50, nullptr); |  | ||||||
| 
 | 
 | ||||||
|                 return TRUE; |                 return TRUE; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             case WM_COMMAND: |             case WM_CLOSE: | ||||||
|                 switch (LOWORD(wParam)) { |                 EndDialog(dlg, 0); | ||||||
|                     case IDC_BUTTONSTARTPAUSE: |  | ||||||
|                         app->m_startpauseButtonPressed = true; |  | ||||||
|                         return TRUE; |  | ||||||
| 
 |  | ||||||
|                     case ID_FILE_RESET: { |  | ||||||
|                         if (!app->m_file.empty()) |  | ||||||
|                             app->save(); |  | ||||||
| 
 |  | ||||||
|                         app->reset(); |  | ||||||
|                         return TRUE; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     case ID_FILE_SAVE: { |  | ||||||
|                         app->save(); |  | ||||||
|                         return TRUE; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     case ID_FILE_SAVEAS: { |  | ||||||
|                         app->save(true); |  | ||||||
|                         return TRUE; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     case ID_FILE_OPEN: { |  | ||||||
|                         if (!app->m_file.empty()) |  | ||||||
|                             app->save(); |  | ||||||
| 
 |  | ||||||
|                         app->open(); |  | ||||||
|                         return TRUE; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     case ID_FILE_EXIT: { |  | ||||||
|                         SendMessage(dlg, WM_CLOSE, NULL, NULL); |  | ||||||
|                         return TRUE; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     case ID_HELP_ABOUT: |  | ||||||
|                         MessageBox(dlg, std::format("{} {}\nCopyright Grayson Riffe 2025\ngraysonriffe.com\n\n" |  | ||||||
|                             "\tMainspring is a simple timekeeper. It can be used as a simple stopwatch for short-term activities, or " |  | ||||||
|                             "it can log hours on a longer-term project. Times can be saved to a file, and any subsequent uses will autosave to that file. The most recent " |  | ||||||
|                             "time will be loaded when Mainspring starts.", app->m_appName, app->m_appVersion).c_str(), std::format("About {}", app->m_appName).c_str(), MB_OK); |  | ||||||
|                         return TRUE; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 return FALSE; |  | ||||||
| 
 |  | ||||||
|             case WM_TIMER: |  | ||||||
|                 switch (wParam) { |  | ||||||
|                     case IDT_UPDATEAPP: |  | ||||||
|                         SendMessage(dlg, WM_UPDATEAPP, NULL, NULL); |  | ||||||
|                         return TRUE; |  | ||||||
| 
 |  | ||||||
|                     case IDT_SAVEDTEXT: |  | ||||||
|                         app->m_showSavedText = false; |  | ||||||
|                         return TRUE; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 return FALSE; |  | ||||||
| 
 |  | ||||||
|                 return TRUE; |  | ||||||
| 
 |  | ||||||
|             case WM_UPDATEAPP: { |  | ||||||
|                 if (app->m_startpauseButtonPressed) { |  | ||||||
|                     app->m_startpauseButtonPressed = false; |  | ||||||
| 
 |  | ||||||
|                     if (!app->m_timing) |  | ||||||
|                         app->m_startTime = Clock::now(); |  | ||||||
|                     else |  | ||||||
|                         app->m_elapsedSaved += app->getElapsed(); |  | ||||||
| 
 |  | ||||||
|                     app->m_timing = !app->m_timing; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (app->m_showSavedText) |  | ||||||
|                     SetDlgItemText(dlg, IDC_STATICTITLE, "Saved!"); |  | ||||||
| 
 |  | ||||||
|                 else if (!app->m_file.empty()) { |  | ||||||
|                     std::string filename = app->m_file.substr(app->m_file.find_last_of('\\') + 1); |  | ||||||
|                     SetDlgItemText(dlg, IDC_STATICTITLE, filename.c_str()); |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                     SetDlgItemText(dlg, IDC_STATICTITLE, app->m_appName); |  | ||||||
| 
 |  | ||||||
|                 if (app->m_timing) |  | ||||||
|                     SetDlgItemText(dlg, IDC_BUTTONSTARTPAUSE, "Pause"); |  | ||||||
|                 else |  | ||||||
|                     SetDlgItemText(dlg, IDC_BUTTONSTARTPAUSE, !app->m_elapsedSaved ? "Start" : "Resume"); |  | ||||||
| 
 |  | ||||||
|                 Seconds totalTime = app->m_elapsedSaved + app->getElapsed(); |  | ||||||
| 
 |  | ||||||
|                 uint32_t hr = totalTime / (3600), min = totalTime % (3600) / 60, sec = totalTime % 60; |  | ||||||
|                 SetDlgItemText(dlg, IDC_STATICTIME, std::format("{:03}:{:02}:{:02}", hr, min, sec).c_str()); |  | ||||||
| 
 |  | ||||||
|                 return TRUE; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             case WM_CLOSE: { |  | ||||||
|                 if (!app->m_file.empty()) |  | ||||||
|                     app->save(); |  | ||||||
| 
 |  | ||||||
|                 std::string configPath = app->getConfigPath(); |  | ||||||
|                 writeFile(configPath.c_str(), app->m_file); |  | ||||||
| 
 |  | ||||||
|                 KillTimer(dlg, 1); |  | ||||||
|                 DestroyWindow(dlg); |  | ||||||
|                 return TRUE; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             case WM_DESTROY: |  | ||||||
|                 PostQuitMessage(0); |  | ||||||
|                 return TRUE; |                 return TRUE; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return FALSE; |         return FALSE; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::string Application::getConfigPath() { |     Application::~Application() { | ||||||
|         char appDataPath[MAX_PATH] = {}; |  | ||||||
|         SHGetFolderPath(nullptr, CSIDL_APPDATA, nullptr, NULL, appDataPath); |  | ||||||
|         return std::string(appDataPath) + "\\" + m_appName + "\\last"; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     Seconds Application::getElapsed() { |  | ||||||
|         if (m_timing) |  | ||||||
|             return Duration(Clock::now() - m_startTime).count(); |  | ||||||
|         else |  | ||||||
|             return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void Application::reset() { |  | ||||||
|         m_timing = false; |  | ||||||
|         m_elapsedSaved = 0; |  | ||||||
|         m_file.clear(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void Application::save(bool saveas) { |  | ||||||
|         if (m_file.empty() || saveas) { |  | ||||||
|             OPENFILENAME ofn = {}; |  | ||||||
|             ofn.lStructSize = sizeof(ofn); |  | ||||||
|             ofn.hwndOwner = m_dlg; |  | ||||||
|             ofn.lpstrFilter = "Mainspring Time File (*.mspring)\0*.mspring\0\0"; |  | ||||||
|             ofn.lpstrDefExt = "mspring"; |  | ||||||
|             char fileBuf[MAX_PATH] = {}; |  | ||||||
|             ofn.lpstrFile = fileBuf; |  | ||||||
|             ofn.nMaxFile = MAX_PATH; |  | ||||||
|             ofn.Flags = OFN_OVERWRITEPROMPT; |  | ||||||
| 
 |  | ||||||
|             if (GetSaveFileName(&ofn)) |  | ||||||
|                 m_file = fileBuf; |  | ||||||
|             else |  | ||||||
|                 return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Seconds totalTime = m_elapsedSaved + getElapsed(); |  | ||||||
|         std::string saveData = std::to_string(totalTime); |  | ||||||
|         writeFile(m_file.c_str(), saveData); |  | ||||||
|         m_showSavedText = true; |  | ||||||
|         SetTimer(m_dlg, IDT_SAVEDTEXT, 3000, nullptr); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void Application::open(std::string path) { |  | ||||||
|         if (path.empty()) { |  | ||||||
|             OPENFILENAME ofn = {}; |  | ||||||
|             ofn.lStructSize = sizeof(ofn); |  | ||||||
|             ofn.hwndOwner = m_dlg; |  | ||||||
|             ofn.lpstrFilter = "Mainspring Time File (*.mspring)\0*.mspring\0\0"; |  | ||||||
|             ofn.lpstrDefExt = "mspring"; |  | ||||||
|             char fileBuf[MAX_PATH] = {}; |  | ||||||
|             ofn.lpstrFile = fileBuf; |  | ||||||
|             ofn.nMaxFile = MAX_PATH; |  | ||||||
|             ofn.Flags = OFN_FILEMUSTEXIST; |  | ||||||
| 
 |  | ||||||
|             if (GetOpenFileName(&ofn)) |  | ||||||
|                 m_file = fileBuf; |  | ||||||
|             else |  | ||||||
|                 return; |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|             m_file = path; |  | ||||||
| 
 |  | ||||||
|         std::string openData; |  | ||||||
|         if (readFile(m_file.c_str(), openData)) |  | ||||||
|             // Update status text;
 |  | ||||||
|             m_elapsedSaved = std::stoull(openData); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,39 +1,17 @@ | |||||||
| // Application class header
 | // Application class header
 | ||||||
| 
 | 
 | ||||||
| namespace mainspring { | namespace mainspring { | ||||||
|     using Clock = std::chrono::high_resolution_clock; |  | ||||||
|     using TimePoint = std::chrono::time_point<Clock>; |  | ||||||
|     using Duration = std::chrono::duration<double, std::ratio<1, 1>>; |  | ||||||
| 
 |  | ||||||
|     using Seconds = uint64_t; |  | ||||||
| 
 |  | ||||||
|     class Application { |     class Application { | ||||||
|     public: |     public: | ||||||
|         Application(const char* appName, const char* appVersion); |         Application(const char* appName, const char* appVersion); | ||||||
| 
 | 
 | ||||||
|         void run(); |         void run(); | ||||||
|  | 
 | ||||||
|  |         ~Application(); | ||||||
|     private: |     private: | ||||||
|         static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); |         static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); | ||||||
| 
 | 
 | ||||||
|         std::string getConfigPath(); |  | ||||||
| 
 |  | ||||||
|         Seconds getElapsed(); // Gets the current timing session time
 |  | ||||||
| 
 |  | ||||||
|         void reset(); |  | ||||||
|         void save(bool saveas = false); |  | ||||||
|         void open(std::string path = ""); |  | ||||||
| 
 |  | ||||||
|         const char* m_appName; |         const char* m_appName; | ||||||
|         const char* m_appVersion; |         const char* m_appVersion; | ||||||
| 
 |  | ||||||
|         HWND m_dlg; |  | ||||||
| 
 |  | ||||||
|         // Current state of the app
 |  | ||||||
|         bool m_timing; // Currently timing?
 |  | ||||||
|         bool m_startpauseButtonPressed; // Was the start / pause button pressed?
 |  | ||||||
|         Seconds m_elapsedSaved; // Time saved
 |  | ||||||
|         TimePoint m_startTime; // When the current timing session was started
 |  | ||||||
|         std::string m_file; // Current time file path
 |  | ||||||
|         bool m_showSavedText; // Save confirmation
 |  | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| @ -3,7 +3,6 @@ | |||||||
| // IO and strings
 | // IO and strings
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <filesystem> |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <format> | #include <format> | ||||||
| 
 | 
 | ||||||
| @ -12,6 +11,4 @@ | |||||||
| 
 | 
 | ||||||
| // Windows
 | // Windows
 | ||||||
| #define WIN32_LEAN_AND_MEAN | #define WIN32_LEAN_AND_MEAN | ||||||
| #include <Windows.h> | #include <Windows.h> | ||||||
| #include <commdlg.h> |  | ||||||
| #include <ShlObj.h> |  | ||||||
| @ -1,26 +1,6 @@ | |||||||
| // Win32 resources
 | // Win32 resources
 | ||||||
|  | #define IDD_DIALOGMAIN 101 | ||||||
| 
 | 
 | ||||||
| // Icon
 | #define IDC_BUTTONSTARTPAUSE 1001 | ||||||
| #define IDI_ICONMAIN 101 | #define IDC_STATICTITLE 1002 | ||||||
| 
 | #define IDC_STATICTIME 1003 | ||||||
| // Dialog
 |  | ||||||
| #define IDD_DIALOGMAIN  201 |  | ||||||
| 
 |  | ||||||
| // Menu
 |  | ||||||
| #define IDR_MENUMAIN    301 |  | ||||||
| #define ID_FILE_RESET     302 |  | ||||||
| #define ID_FILE_SAVE    303 |  | ||||||
| #define ID_FILE_SAVEAS  304 |  | ||||||
| #define ID_FILE_OPEN    305 |  | ||||||
| #define ID_FILE_EXIT    306 |  | ||||||
| 
 |  | ||||||
| #define ID_HELP_ABOUT   311 |  | ||||||
| 
 |  | ||||||
| // Accelerators
 |  | ||||||
| #define IDA_ACCELMAIN 401 |  | ||||||
| 
 |  | ||||||
| // Controls (text and buttons)
 |  | ||||||
| #define IDC_BUTTONSTARTPAUSE    1001 |  | ||||||
| #define IDC_STATICTITLE         1002 |  | ||||||
| #define IDC_STATICTIME          1003 |  | ||||||
| #define IDC_STATICICON          1004 |  | ||||||
|  | |||||||
| @ -1,30 +0,0 @@ | |||||||
| // Utility implementation
 |  | ||||||
| #include "pch.h" |  | ||||||
| #include "utility.h" |  | ||||||
| 
 |  | ||||||
| namespace mainspring { |  | ||||||
|     bool readFile(const char* filename, std::string& out) { |  | ||||||
|         std::ifstream fileStream(filename, std::ios::binary | std::ios::ate); |  | ||||||
|         if (!fileStream.is_open()) |  | ||||||
|             return false; |  | ||||||
| 
 |  | ||||||
|         size_t fileSize = fileStream.tellg(); |  | ||||||
|         fileStream.seekg(0); |  | ||||||
|         out.resize(fileSize); |  | ||||||
|         fileStream.read(out.data(), fileSize); |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     bool writeFile(const char* filename, const std::string& in) { |  | ||||||
|         std::string folder = filename; |  | ||||||
|         folder.resize(folder.find_last_of('\\')); |  | ||||||
|         if (!std::filesystem::exists(folder)) |  | ||||||
|             std::filesystem::create_directories(folder); |  | ||||||
|         std::ofstream fileStream(filename, std::ios::binary | std::ios::trunc); |  | ||||||
|         if (!fileStream.is_open()) |  | ||||||
|             return false; |  | ||||||
| 
 |  | ||||||
|         fileStream << in; |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| // Utility header
 |  | ||||||
| 
 |  | ||||||
| namespace mainspring { |  | ||||||
|     bool readFile(const char* filename, std::string& out); |  | ||||||
|     bool writeFile(const char* filename, const std::string& in); |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user