// Copyright (c) 2021 - present, Liu Xu // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "pch.h" #include "App.h" #include "Utils.h" #include "StrUtils.h" #include "Logger.h" #define API_DECLSPEC extern "C" __declspec(dllexport) static HINSTANCE hInst = NULL; // DLL 入口 BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hInst = hModule; break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } // 日志级别: // 0:TRACE,1:DEBUG,...,6:OFF API_DECLSPEC void WINAPI SetLogLevel(UINT logLevel) { Logger::Get().SetLevel((spdlog::level::level_enum)logLevel); } API_DECLSPEC BOOL WINAPI Initialize( UINT logLevel, const char* logFileName, int logArchiveAboveSize, int logMaxArchiveFiles ) { // 初始化日志 if (!Logger::Get().Initialize(logLevel, logFileName, logArchiveAboveSize, logMaxArchiveFiles)) { return FALSE; } // 初始化 App if (!App::Get().Initialize(hInst)) { return FALSE; } // 初始化 Hasher if (!Utils::Hasher::Get().Initialize()) { return FALSE; } return TRUE; } API_DECLSPEC const char* WINAPI Run( HWND hwndSrc, const char* effectsJson, UINT flags, UINT captureMode, float cursorZoomFactor, // 负数和 0:和源窗口相同,正数:缩放比例 UINT cursorInterpolationMode, // 0:最近邻,1:双线性 int adapterIdx, UINT multiMonitorUsage, // 0:最近 1:相交 2:所有 UINT cropLeft, UINT cropTop, UINT cropRight, UINT cropBottom ) { Logger& logger = Logger::Get(); if (!hwndSrc || !IsWindow(hwndSrc)) { logger.Critical("非法的源窗口句柄"); return ErrorMessages::GENERIC; } const auto& version = Utils::GetOSVersion(); logger.Info(fmt::format("OS 版本:{}.{}.{}", version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber)); int len = GetWindowTextLength(hwndSrc); if (len <= 0) { logger.Info("源窗口无标题"); } else { std::wstring title(len, 0); if (!GetWindowText(hwndSrc, &title[0], int(title.size() + 1))) { Logger::Get().Error("获取源窗口标题失败"); } else { Logger::Get().Info("源窗口标题:" + StrUtils::UTF16ToUTF8(title)); } } App& app = App::Get(); if (!app.Run(hwndSrc, effectsJson, captureMode, cursorZoomFactor, cursorInterpolationMode, adapterIdx, multiMonitorUsage, RECT{(LONG)cropLeft, (LONG)cropTop, (LONG)cropRight, (LONG)cropBottom}, flags) ) { // 初始化失败 Logger::Get().Info("App.Run 失败"); return app.GetErrorMsg(); } logger.Info("即将退出"); logger.Flush(); return nullptr; } // ---------------------------------------------------------------------------------------- // 以下函数在用户界面的主线程上调用 API_DECLSPEC const char* WINAPI GetAllGraphicsAdapters(const char* delimiter) { static std::string result; result.clear(); winrt::com_ptr dxgiFactory; HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); if (FAILED(hr)) { return ""; } winrt::com_ptr adapter; for (UINT adapterIndex = 0; SUCCEEDED(dxgiFactory->EnumAdapters1(adapterIndex,adapter.put())); ++adapterIndex ) { if (adapterIndex > 0) { result += delimiter; } DXGI_ADAPTER_DESC1 desc; HRESULT hr = adapter->GetDesc1(&desc); if (SUCCEEDED(hr)) { result += StrUtils::UTF16ToUTF8(desc.Description); } else { result += "???"; } } return result.c_str(); }