diff --git a/Redcraft.FocusIME/Source/Private/Defines.h b/Redcraft.FocusIME/Source/Private/Defines.h new file mode 100644 index 0000000..77aa6a5 --- /dev/null +++ b/Redcraft.FocusIME/Source/Private/Defines.h @@ -0,0 +1,129 @@ +#pragma once + +// Platform information macro + +#ifndef PLATFORM_NAME +# error "PLATFORM_NAME must be defined." +#endif + +#ifndef PLATFORM_WINDOWS +# define PLATFORM_WINDOWS 0 +#endif + +#ifndef PLATFORM_LINUX +# define PLATFORM_LINUX 0 +#endif + +#ifndef PLATFORM_UNKNOWN +# define PLATFORM_UNKNOWN 0 +#endif + +// Build information macro + +#ifndef BUILD_TYPE +# error "BUILD_TYPE must be defined." +#endif + +#ifndef BUILD_DEBUG +# define BUILD_DEBUG 0 +#endif + +#ifndef BUILD_DEVELOPMENT +# define BUILD_DEVELOPMENT 0 +#endif + +#ifndef BUILD_RELEASE +# define BUILD_RELEASE 0 +#endif + +#ifndef BUILD_UNKNOWN +# define BUILD_UNKNOWN 0 +#endif + +// Compiler information macro + +#ifndef PLATFORM_COMPILER_NAME +# error "COMPILER_NAME must be defined." +#endif + +#ifndef PLATFORM_COMPILER_MSVC +# define PLATFORM_COMPILER_MSVC 0 +#endif + +#ifndef PLATFORM_COMPILER_CLANG +# define PLATFORM_COMPILER_CLANG 0 +#endif + +#ifndef PLATFORM_COMPILER_GCC +# define PLATFORM_COMPILER_GCC 0 +#endif + +#ifndef PLATFORM_COMPILER_UNKNOWN +# define PLATFORM_COMPILER_UNKNOWN 0 +#endif + +// Architecture information macro + +#ifndef PLATFORM_CPU_X86_FAMILY +# if (defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__)) +# define PLATFORM_CPU_X86_FAMILY 1 +# else +# define PLATFORM_CPU_X86_FAMILY 0 +# endif +#endif + +#ifndef PLATFORM_CPU_ARM_FAMILY +# if (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || defined(_M_ARM64)) +# define PLATFORM_CPU_ARM_FAMILY 1 +# else +# define PLATFORM_CPU_ARM_FAMILY 0 +# endif +#endif + +#ifndef PLATFORM_CPU_UNKNOWN_FAMILY +# define PLATFORM_CPU_UNKNOWN_FAMILY (!(PLATFORM_CPU_X86_FAMILY || PLATFORM_CPU_ARM_FAMILY)) +#endif + +// CPU bits information macro + +#ifndef PLATFORM_CPU_BITS +# if (defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64)) +# define PLATFORM_CPU_BITS 64 +# elif (defined(_M_IX86) || defined(__i386__) || defined(__arm__) || defined(_M_ARM)) +# define PLATFORM_CPU_BITS 32 +# else +# define PLATFORM_CPU_BITS 0 +# endif +#endif + +// Endian information macro + +#if !defined(PLATFORM_LITTLE_ENDIAN) && !defined(PLATFORM_BIG_ENDIAN) +# if PLATFORM_COMPILER_MSVC +# define PLATFORM_LITTLE_ENDIAN 1 +# define PLATFORM_BIG_ENDIAN 0 +# elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define PLATFORM_LITTLE_ENDIAN 1 +# define PLATFORM_BIG_ENDIAN 0 +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define PLATFORM_LITTLE_ENDIAN 0 +# define PLATFORM_BIG_ENDIAN 1 +# else +# define PLATFORM_LITTLE_ENDIAN 0 +# define PLATFORM_BIG_ENDIAN 0 +# endif +# endif +#endif + +#ifndef PLATFORM_LITTLE_ENDIAN +# define PLATFORM_LITTLE_ENDIAN 0 +#endif + +#ifndef PLATFORM_BIG_ENDIAN +# define PLATFORM_BIG_ENDIAN 0 +#endif + +#ifndef PLATFORM_MIXED_ENDIAN +# define PLATFORM_MIXED_ENDIAN (!(PLATFORM_LITTLE_ENDIAN || PLATFORM_BIG_ENDIAN)) +#endif diff --git a/Redcraft.FocusIME/Source/Private/Main.cpp b/Redcraft.FocusIME/Source/Private/Main.cpp index c44d85e..b08604e 100644 --- a/Redcraft.FocusIME/Source/Private/Main.cpp +++ b/Redcraft.FocusIME/Source/Private/Main.cpp @@ -1,28 +1,104 @@ -#include +#include "Defines.h" + +#include #include +#include #include #include +#include +#include +#include +#include +#include #pragma warning(disable: 4996) // ReSharper disable CppDeprecatedEntity // ReSharper disable CppClangTidyCertErr33C +std::ofstream GLogFile; + +void PrintLog(const std::string& Text) +{ + const auto Now = std::chrono::system_clock::now(); + const auto Time = std::chrono::system_clock::to_time_t(Now); + + const long long Milliseconds = (std::chrono::duration_cast(Now.time_since_epoch()) % 1000).count(); + + static std::mutex Mutex; std::lock_guard Lock(Mutex); + + const std::tm* LocalTime = std::localtime(&Time); // NOLINT(concurrency-mt-unsafe) + + char Buffer[] = "[2025-06-21 20:05:04.305]: "; + + std::strftime(&Buffer[1], 20, "%Y-%m-%d %H:%M:%S", LocalTime); + + Buffer[20] = '.'; + + constexpr char Digits[] = "0123456789"; + + Buffer[21] = Digits[Milliseconds / 100 % 10]; + Buffer[22] = Digits[Milliseconds / 10 % 10]; + Buffer[23] = Digits[Milliseconds / 1 % 10]; + + GLogFile << Buffer << Text << std::endl; +} + int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { using namespace std::chrono_literals; - AllocConsole(); + const HANDLE Mutex = CreateMutex(nullptr, TRUE, "FocusIME_SingleInstance_Mutex"); - freopen("CONOUT$", "w", stdout); + if (Mutex == nullptr) + { + MessageBox(nullptr, "Failed to create mutex.", "FocusIME", MB_OK | MB_ICONERROR); - SetConsoleTitle("FocusIME"); + return 1; + } - std::cout << "Hello, FocusIME!" << std::endl; + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + MessageBox(nullptr, "FocusIME is already running.", "FocusIME", MB_OK | MB_ICONINFORMATION); - std::this_thread::sleep_for(3s); + CloseHandle(Mutex); - FreeConsole(); + return 0; + } + + GLogFile.open("Log.txt", std::ios::out | std::ios::app); + + if (!GLogFile.is_open()) + { + MessageBox(nullptr, "Failed to open log file.", "FocusIME", MB_OK | MB_ICONERROR); + + CloseHandle(Mutex); + + return 1; + } + + PrintLog("FocusIME started successfully"); + + MSG Message = { }; + + while (true) + { + BOOL bResult = GetMessage(&Message, nullptr, 0, 0); + + if (bResult > 0) + { + TranslateMessage(&Message); + DispatchMessage (&Message); + } + + else break; + } + + PrintLog("FocusIME is shutting down..."); + + GLogFile.close(); + + CloseHandle(Mutex); return 0; }