// wCenterWindow // CLogger.cpp #include "CLogger.h" #include #include #include // Convert a wide Unicode string to an UTF8 string std::string CLogger::ConvU16U8(const std::wstring& wstr) { if (wstr.empty()) return std::string(); int size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); std::string str_out(size, 0); WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str_out[0], size, NULL, NULL); return str_out; } inline wchar_t* CLogger::GetTimeStamp() { GetLocalTime(<); StringCchPrintfW(logTimeBuffer, _countof(logTimeBuffer), L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds); return logTimeBuffer; } void CLogger::Out(const wchar_t* fmt, ...) { if (fsLogFile.is_open()) { va_list args; va_start(args, fmt); EnterCriticalSection(&cs); StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args); va_end(args); fsLogFile << ConvU16U8(GetTimeStamp()) << ConvU16U8(logBuffer) << std::endl; LeaveCriticalSection(&cs); } } void CLogger::Init() { wchar_t szPath[MAX_PATH] = { 0 }; DWORD dwPathLength = GetModuleFileNameW(NULL, szPath, MAX_PATH); DWORD dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) { MessageBoxW(NULL, L"Warning!\nPath to log file is too long! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); return; } if (NULL == dwPathLength) { MessageBoxW(NULL, L"Warning!\nCan't get application's filename! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); return; } std::filesystem::path log_path = szPath; log_path.replace_extension(L".log"); std::filesystem::path bak_path = log_path; bak_path.replace_extension(L".bak"); if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path); #ifdef _DEBUG log_path = L"test.log"; #endif fsLogFile.open(log_path, std::ios::trunc); if (fsLogFile.is_open()) { InitializeCriticalSection(&cs); fsLogFile << "\xEF\xBB\xBF"; // (0xEF, 0xBB, 0xBF) - UTF-8 BOM fsLogFile.imbue(std::locale(".UTF-8")); fsLogFile << ConvU16U8(GetTimeStamp()) << "[ " << ConvU16U8(szAppTitleVer).c_str() << " ] Start log." << std::endl; fsLogFile << ConvU16U8(GetTimeStamp()) << "Logfile: \"" << ConvU16U8(log_path.native()) << "\"" << std::endl; } else { MessageBoxW(NULL, L"Warning!\nCan't create log file! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); } } CLogger::CLogger(const wchar_t* _appTitle) { szAppTitle = _appTitle; szAppTitleVer = _appTitle; Init(); } CLogger::~CLogger() { if (fsLogFile) { fsLogFile << ConvU16U8(GetTimeStamp()) << "Stop log." << std::endl; fsLogFile.close(); DeleteCriticalSection(&cs); } }