Compare commits

...

8 Commits

Author SHA1 Message Date
0bf5a76da5 add app screen capture 2024-10-08 19:30:14 +08:00
d784fc6570 修改日志格式 2024-10-08 16:17:26 +08:00
8e1a01215d add perf 2024-09-30 18:21:09 +08:00
5c8f902c11 add namespace 2024-09-29 10:18:35 +08:00
ccf642ef92 修复构建 改为源码依赖 2024-09-27 19:03:10 +08:00
fde177894a 需要先构建WinDevice 在查找 lib 2024-09-27 15:32:00 +08:00
b01ab5a972 增加构建配置 2024-09-27 14:38:53 +08:00
c72ef9cb47 优化构建 2024-09-26 20:06:56 +08:00
34 changed files with 867 additions and 247 deletions

21
CppProperties.json Normal file
View File

@@ -0,0 +1,21 @@
{
"configurations": [
{
"inheritEnvironments": [
"msvc_x86"
],
"name": "x86-Debug",
"includePath": [
"${env.INCLUDE}",
"${workspaceRoot}\\**"
],
"defines": [
"WIN32",
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"intelliSenseMode": "windows-msvc-x86"
}
]
}

View File

@@ -12,6 +12,44 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置源代码文件编码为UTF-8 # 设置源代码文件编码为UTF-8
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8>") add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8>")
# option(IS_DEBUG "Enable debug mode" OFF)
# if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# set(IS_DEBUG ON)
# else()
# set(IS_DEBUG OFF)
# endif()
# set(WinDevice_OUTPUT "../WinDevice/output")
# message("WinDevice_OUTPUT: ${WinDevice_OUTPUT}")
# # 获取架构信息
# if(CMAKE_SIZEOF_VOID_P EQUAL 8)
# set(ARCH_DIR "x64")
# else()
# set(ARCH_DIR "x86")
# endif()
# set(WinDevice_INCLUDE_DIR "${WinDevice_OUTPUT}/include/")
# message("WinDevice_INCLUDE_DIR: ${WinDevice_INCLUDE_DIR}")
# set(WinDevice_THIRD_INCLUDE_DIR "${WinDevice_OUTPUT}/third_lib/")
# message("WinDevice_THIRD_INCLUDE_DIR: ${WinDevice_THIRD_INCLUDE_DIR}")
# if (IS_DEBUG)
# set(WinDevice_LIB_DIR "${WinDevice_OUTPUT}/${ARCH_DIR}/debug/")
# else()
# set(WinDevice_LIB_DIR "${WinDevice_OUTPUT}/${ARCH_DIR}/release/")
# endif()
# message("WinDevice_LIB_DIR: ${WinDevice_LIB_DIR}")
# message("build WinDecie in: ${CMAKE_BUILD_TYPE} mode")
# add_custom_target(BuildWinDevice ALL
# COMMAND ${CMAKE_COMMAND} -E echo "Starting to build WinDevice project..."
# COMMAND ${CMAKE_COMMAND} -S ../WinDevice -B ../WinDevice/build -G "Visual Studio 17 2022" -A ${ARCH_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
# COMMAND ${CMAKE_COMMAND} --build ../WinDevice/build --config ${CMAKE_BUILD_TYPE}
# COMMENT "Building WinDevice project in ${CMAKE_BUILD_TYPE} mode"
# )
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
@@ -47,44 +85,14 @@ else()
endif() endif()
endif() endif()
# 添加 WinDevice 子目录
add_subdirectory(../WinDevice ${CMAKE_BINARY_DIR}/WinDevice)
# 链接 WinDevice 库
target_link_libraries(DeviceManager PRIVATE WinDevice) # 假设 WinDevice 是在 WinDevice CMakeLists.txt 中创建的目标
target_link_libraries(DeviceManager PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) target_link_libraries(DeviceManager PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
set(WinDevice_INCLUDE_DIR "../WinDevice/output/include/")
set(WinDevice_THIRD_INCLUDE_DIR "../WinDevice/output/third_lib/")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(WinDevice_LIB_DIR "../WinDevice/output/debug/")
else()
set(WinDevice_LIB_DIR "../WinDevice/output/release/")
endif()
# 使用 find_library 查找动态库文件
find_library(WinDevice_LIB
NAMES WinDevice
HINTS ${WinDevice_LIB_DIR}
)
# 添加头文件目录
include_directories(${WinDevice_INCLUDE_DIR} ${WinDevice_THIRD_INCLUDE_DIR})
# 将找到的库链接到你的目标
target_link_libraries(DeviceManager PRIVATE ${WinDevice_LIB})
# if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# # Debug 模式下,添加 WinDevice 项目作为子项目
# add_subdirectory(../WinDevice WinDevice)
# # 链接WinDevice项目
# target_include_directories(DeviceManager PRIVATE
# ../WinDevice/src
# include/third_lib
# )
# target_link_libraries(DeviceManager PRIVATE WinDevice)
# else()
# # Release 模式下,链接 WinDevice 生成的库文件
# target_link_libraries(DeviceManager PRIVATE WinDevice)
# # 在 Release 模式下,添加 WinDevice 的头文件路径
# target_include_directories(DeviceManager PRIVATE
# ../WinDevice/lib
# )
# endif()
set_target_properties(DeviceManager PROPERTIES set_target_properties(DeviceManager PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}

View File

@@ -6,11 +6,31 @@
"configurationType": "Debug", "configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}", "buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}", "installRoot": "${projectDir}\\out\\install\\${name}",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ]
},
{
"name": "x86-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "", "cmakeCommandArgs": "",
"buildCommandArgs": "", "buildCommandArgs": "",
"ctestCommandArgs": "", "ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ], "inheritEnvironments": [ "msvc_x86" ]
"variables": [] },
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ]
} }
] ]
} }

View File

@@ -1,12 +1,38 @@
// //
// Created by zyz on 2023/10/17. // Created by zyz on 2023/10/17.
// //
#ifdef WIN32
#include "windows.h"
#endif
#include "LogManager.h" #include "LogManager.h"
void LogManager::CustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) void LogManager::CustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
QByteArray localMsg = msg.toUtf8(); QByteArray localMsg = msg.toUtf8();
#ifdef WIN32
QString outputMsg;
switch (type) {
case QtDebugMsg:
outputMsg = QString("Debug: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;
case QtInfoMsg:
outputMsg = QString("Info: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;
case QtWarningMsg:
outputMsg = QString("Warning: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;
case QtCriticalMsg:
outputMsg = QString("Critical: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;
case QtFatalMsg:
outputMsg = QString("Fatal: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
abort();
}
// 使用 OutputDebugStringA 输出消息
::OutputDebugStringA(qUtf8Printable(outputMsg + "\n"));
#else
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
@@ -24,4 +50,5 @@ void LogManager::CustomMessageHandler(QtMsgType type, const QMessageLogContext &
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort(); abort();
} }
#endif
} }

33
DeviceManager/build.bat Normal file
View File

@@ -0,0 +1,33 @@
@echo on
chcp 65001
setlocal enabledelayedexpansion
set arch=x64
set build_type=Debug
rem 如果参数1不为空设置架构
if not "%~1" == "" (
set arch=%~1
)
rem 如果参数2不为空设置构建类型
if not "%~2" == "" (
set build_type=%~2
)
rem 删除旧的构建目录
if exist "build" (
rmdir "build" /s /q
)
rem 创建新的构建目录并进入
mkdir "build"
cd build
rem 运行 CMake 配置命令
cmake .. -G "Visual Studio 17 2022" -A %arch% -DCMAKE_BUILD_TYPE=%build_type%
rem 执行构建
cmake --build . --config %build_type%
endlocal

View File

@@ -2,26 +2,27 @@
#include <QApplication> #include <QApplication>
#include "Utils/LogManager.h" #include "Utils/LogManager.h"
#include "Video/ScreenManager.h" #include "../WinDevice/src/Video/ScreenManager.h"
#include "../WinDevice/src/WinDeviceManager.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
qInstallMessageHandler(LogManager::CustomMessageHandler); qInstallMessageHandler(LogManager::CustomMessageHandler);
WinDevice::WinDeviceManager::Init();
ScreenManager screenManager; WinDevice::ScreenManager screenManager;
screenManager.UpdateDisplayInfo(); screenManager.UpdateDisplayInfo();
HRESULT hr = S_OK; qDebug("Adapter Count: %d", screenManager._displayDeviceList.size());
for (size_t i = 0; i < screenManager._displayAdapterList.size(); i++) { for (size_t i = 0; i < screenManager._displayDeviceList.size(); i++) {
DXGI_ADAPTER_DESC adapterDesc; qDebug("Adapter: %s", screenManager._displayDeviceList[i].DeviceName);
hr = screenManager._displayAdapterList[i]->GetDesc(&adapterDesc);
if (SUCCEEDED(hr)) {
qDebug("Adapter: %s", adapterDesc.Description);
}
} }
MainWindow w; MainWindow w;
w.show(); w.show();
return a.exec(); return a.exec();
} }

View File

@@ -15,10 +15,10 @@ set(CMAKE_GENERATOR_TOOLSET "v143")
if (NOT DEFINED CMAKE_GENERATOR_PLATFORM) if (NOT DEFINED CMAKE_GENERATOR_PLATFORM)
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_GENERATOR_PLATFORM x64) set(CMAKE_GENERATOR_PLATFORM x64)
else() else ()
set(CMAKE_GENERATOR_PLATFORM x86) set(CMAKE_GENERATOR_PLATFORM x86)
endif() endif ()
endif() endif ()
# 设置C++标准 # 设置C++标准
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
@@ -37,8 +37,8 @@ if (ENABLE_UTF8_SOURCE)
elseif (CMAKE_COMPILER_IS_GNUCXX) elseif (CMAKE_COMPILER_IS_GNUCXX)
# 设置MinGW编译器的UTF-8源码编码选项 # 设置MinGW编译器的UTF-8源码编码选项
add_compile_options("-fexec-charset=UTF-8" "-finput-charset=UTF-8") add_compile_options("-fexec-charset=UTF-8" "-finput-charset=UTF-8")
endif() endif ()
endif() endif ()
# DirectX目录 # DirectX目录
set(Windows_Kits_DIR "C:\\Program Files (x86)\\Windows Kits\\10") set(Windows_Kits_DIR "C:\\Program Files (x86)\\Windows Kits\\10")
@@ -46,98 +46,99 @@ set(Windows_Kits_Version "10.0.19041.0")
set(Windows_Kits_UM_DIR "${Windows_Kits_DIR}\\Include\\${Windows_Kits_Version}\\um") set(Windows_Kits_UM_DIR "${Windows_Kits_DIR}\\Include\\${Windows_Kits_Version}\\um")
set(Windows_Kits_SHARED_DIR "${Windows_Kits_DIR}\\Include\\${Windows_Kits_Version}\\shared") set(Windows_Kits_SHARED_DIR "${Windows_Kits_DIR}\\Include\\${Windows_Kits_Version}\\shared")
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit 架构 # 64-bit 架构
set(CMAKE_LIBRARY_ARCHITECTURE x64) set(CMAKE_LIBRARY_ARCHITECTURE x64)
set(DirectX_SDK_LIB_DIR "${Windows_Kits_DIR}\\Lib\\${Windows_Kits_Version}\\um\\x64") set(DirectX_SDK_LIB_DIR "${Windows_Kits_DIR}\\Lib\\${Windows_Kits_Version}\\um\\x64")
else() else ()
# 32-bit 架构 # 32-bit 架构
set(CMAKE_LIBRARY_ARCHITECTURE x86) set(CMAKE_LIBRARY_ARCHITECTURE x86)
set(DirectX_SDK_LIB_DIR "${Windows_Kits_DIR}\\Lib\\${Windows_Kits_Version}\\um\\x86") set(DirectX_SDK_LIB_DIR "${Windows_Kits_DIR}\\Lib\\${Windows_Kits_Version}\\um\\x86")
endif() endif ()
# 获取所有 DirectX 相关的库文件 # 获取所有 DirectX 相关的库文件
file(GLOB DirectX_LIBS file(GLOB DirectX_LIBS
"${DirectX_SDK_LIB_DIR}/d3d9.lib" "${DirectX_SDK_LIB_DIR}/d3d9.lib"
"${DirectX_SDK_LIB_DIR}/d3d10.lib" "${DirectX_SDK_LIB_DIR}/d3d10.lib"
"${DirectX_SDK_LIB_DIR}/d3d11.lib" "${DirectX_SDK_LIB_DIR}/d3d11.lib"
"${DirectX_SDK_LIB_DIR}/d3d12.lib" "${DirectX_SDK_LIB_DIR}/d3d12.lib"
"${DirectX_SDK_LIB_DIR}/dxgi.lib" "${DirectX_SDK_LIB_DIR}/dxgi.lib"
"${DirectX_SDK_LIB_DIR}/ddraw.lib" "${DirectX_SDK_LIB_DIR}/ddraw.lib"
) )
# 使用通配符自动列举源文件 # 使用通配符自动列举源文件
file(GLOB_RECURSE SOURCE_FILES "./src/*") file(GLOB_RECURSE SOURCE_FILES "./src/*")
set(Third_Include_DIR "include/third_lib/") set(Third_Include_DIR "include/third_lib/")
# 添加功能模块的源文件 # 添加功能模块的源文件
add_library(WinDevice SHARED add_library(WinDevice SHARED
${SOURCE_FILES} ${SOURCE_FILES}
) )
# 设置WinDevice库的包含目录 # 设置WinDevice库的包含目录
target_include_directories(WinDevice target_include_directories(WinDevice
PUBLIC PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src> $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>
PRIVATE PRIVATE
${Windows_Kits_UM_DIR} ${Windows_Kits_UM_DIR}
${Windows_Kits_SHARED_DIR} ${Windows_Kits_SHARED_DIR}
${Third_Include_DIR} ${Third_Include_DIR}
) )
# 链接 d3d 的 lib # 链接 d3d 的 lib
target_link_libraries(WinDevice PRIVATE ${DirectX_LIBS}) target_link_libraries(WinDevice PRIVATE ${DirectX_LIBS})
# 创建 output 目录 # 创建 output 目录
set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/output) set(OUTPUT_DIR ${CMAKE_SOURCE_DIR}/output)
# 获取架构信息 # 获取架构信息
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ARCH_DIR "x64") set(ARCH_DIR "x64")
else() else ()
set(ARCH_DIR "x86") set(ARCH_DIR "x86")
endif() endif ()
# 创建架构特定的输出目录 # 创建架构特定的输出目录
file(MAKE_DIRECTORY ${OUTPUT_DIR}/${ARCH_DIR}) file(MAKE_DIRECTORY ${OUTPUT_DIR}/${ARCH_DIR})
set_target_properties(WinDevice PROPERTIES set_target_properties(WinDevice PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug" ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug" LIBRARY_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release" ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release" LIBRARY_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release" RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/${ARCH_DIR}/release")
)
if (CMAKE_BUILD_TYPE STREQUAL "Debug") if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# Debug 模式下的配置 # Debug 模式下的配置
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG")
set(LIBRARY_OUTPUT_PATH "${OUTPUT_DIR}/debug") set(LIBRARY_OUTPUT_PATH "${OUTPUT_DIR}/debug")
# 添加测试 # 添加测试
add_executable(WinDeviceTest "src/main.cpp" ${SOURCE_FILES}) add_executable(WinDeviceTest WIN32 "src/main.cpp" ${SOURCE_FILES})
target_include_directories(WinDeviceTest target_include_directories(WinDeviceTest
PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src> PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>
PRIVATE ${Third_Include_DIR} ${Windows_Kits_UM_DIR} ${Windows_Kits_SHARED_DIR}) PRIVATE ${Third_Include_DIR} ${Windows_Kits_UM_DIR} ${Windows_Kits_SHARED_DIR})
target_link_libraries(WinDeviceTest PRIVATE ${DirectX_LIBS}) target_link_libraries(WinDeviceTest PRIVATE ${DirectX_LIBS} user32 gdi32)
set_target_properties(WinDeviceTest PROPERTIES set_target_properties(WinDeviceTest PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/debug" ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/debug" LIBRARY_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/debug" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}/${ARCH_DIR}/debug")
else ()
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/release"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/release"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}/release"
)
else()
# Release 模式下的配置 # Release 模式下的配置
set(LIBRARY_OUTPUT_PATH "${OUTPUT_DIR}/release") set(LIBRARY_OUTPUT_PATH "${OUTPUT_DIR}/release")
endif() endif ()
# 拷贝头文件到构建目录的 include 文件夹下 # 拷贝头文件到构建目录的 include 文件夹下
file(GLOB_RECURSE EXPORTED_HEADERS ${CMAKE_SOURCE_DIR}/src/*.h) file(GLOB_RECURSE EXPORTED_HEADERS ${CMAKE_SOURCE_DIR}/src/*.h)
foreach(HEADER ${EXPORTED_HEADERS}) foreach (HEADER ${EXPORTED_HEADERS})
get_filename_component(HEADER_DIR ${HEADER} DIRECTORY) get_filename_component(HEADER_DIR ${HEADER} DIRECTORY)
get_filename_component(HEADER_NAME ${HEADER} NAME) get_filename_component(HEADER_NAME ${HEADER} NAME)
string(REPLACE "${CMAKE_SOURCE_DIR}/src/" "" HEADER_RELATIVE_PATH ${HEADER_DIR}) # 检查 HEADER_DIR 是否包含 "/src/"
string(FIND ${HEADER_DIR} "/src/" SRC_DIR_INDEX)
# 判断是否找到
if (SRC_DIR_INDEX GREATER -1)
string(REPLACE "${CMAKE_SOURCE_DIR}/src/" "" HEADER_RELATIVE_PATH ${HEADER_DIR})
else()
string(REPLACE "${CMAKE_SOURCE_DIR}/src" "" HEADER_RELATIVE_PATH ${HEADER_DIR})
endif()
file(COPY ${HEADER} DESTINATION ${OUTPUT_DIR}/include/${HEADER_RELATIVE_PATH}) file(COPY ${HEADER} DESTINATION ${OUTPUT_DIR}/include/${HEADER_RELATIVE_PATH})
endforeach() endforeach ()
# 创建 output/third_lib 目录 # 创建 output/third_lib 目录
set(OUTPUT_THIRD_LIB_DIR ${OUTPUT_DIR}/third_lib) set(OUTPUT_THIRD_LIB_DIR ${OUTPUT_DIR}/third_lib)

33
WinDevice/build.bat Normal file
View File

@@ -0,0 +1,33 @@
@echo on
chcp 65001
setlocal enabledelayedexpansion
set arch=x64
set build_type=Debug
rem 如果参数1不为空设置架构
if not "%~1" == "" (
set arch=%~1
)
rem 如果参数2不为空设置构建类型
if not "%~2" == "" (
set build_type=%~2
)
rem 删除旧的构建目录
if exist "build" (
rmdir "build" /s /q
)
rem 创建新的构建目录并进入
mkdir "build"
cd build
rem 运行 CMake 配置命令
cmake .. -G "Visual Studio 17 2022" -A %arch% -DCMAKE_BUILD_TYPE=%build_type%
rem 执行构建
cmake --build . --config %build_type%
endlocal

View File

@@ -1,7 +1,9 @@
#pragma once #pragma once
enum AudioDeviceType namespace WinDevice {
{ enum AudioDeviceType
Render, {
Capture Render,
}; Capture
};
}

View File

@@ -2,16 +2,16 @@
#include <iostream> #include <iostream>
AudioManager::AudioManager() WinDevice::AudioManager::AudioManager()
{ {
// 创建设备枚举器 // 创建设备枚举器
} }
AudioManager::~AudioManager() WinDevice::AudioManager::~AudioManager()
{ {
} }
HRESULT AudioManager::Init() HRESULT WinDevice::AudioManager::Init()
{ {
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&pEnumerator)); HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&pEnumerator));
if (FAILED(hr)) if (FAILED(hr))
@@ -31,7 +31,7 @@ HRESULT AudioManager::Init()
return hr; return hr;
} }
HRESULT AudioManager::Uninit() HRESULT WinDevice::AudioManager::Uninit()
{ {
pEnumerator = nullptr; pEnumerator = nullptr;
pCaptureCollection = nullptr; pCaptureCollection = nullptr;
@@ -41,7 +41,7 @@ HRESULT AudioManager::Uninit()
return S_OK; return S_OK;
} }
IMMDeviceCollection* AudioManager::GetDeviceList(EDataFlow flow) IMMDeviceCollection* WinDevice::AudioManager::GetDeviceList(EDataFlow flow)
{ {
if (flow == eCapture) if (flow == eCapture)
{ {
@@ -66,7 +66,7 @@ IMMDeviceCollection* AudioManager::GetDeviceList(EDataFlow flow)
return nullptr; return nullptr;
} }
IMMDevice* AudioManager::GetDefaultDevice(EDataFlow flow) IMMDevice* WinDevice::AudioManager::GetDefaultDevice(EDataFlow flow)
{ {
if (flow == eCapture) if (flow == eCapture)
{ {
@@ -79,7 +79,7 @@ IMMDevice* AudioManager::GetDefaultDevice(EDataFlow flow)
return nullptr; return nullptr;
} }
HRESULT AudioManager::_UpdateDeviceList(EDataFlow flow) HRESULT WinDevice::AudioManager::_UpdateDeviceList(EDataFlow flow)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (flow == eCapture) if (flow == eCapture)
@@ -93,7 +93,7 @@ HRESULT AudioManager::_UpdateDeviceList(EDataFlow flow)
return hr; return hr;
} }
HRESULT AudioManager::_UpdateDefaultDevice(EDataFlow flow) HRESULT WinDevice::AudioManager::_UpdateDefaultDevice(EDataFlow flow)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (flow == eCapture) if (flow == eCapture)

View File

@@ -2,25 +2,27 @@
#include <Mmdeviceapi.h> #include <Mmdeviceapi.h>
class AudioManager namespace WinDevice {
{ class AudioManager
public: {
AudioManager(); public:
~AudioManager(); AudioManager();
~AudioManager();
HRESULT Init(); HRESULT Init();
HRESULT Uninit(); HRESULT Uninit();
IMMDeviceCollection* GetDeviceList(EDataFlow flow); IMMDeviceCollection* GetDeviceList(EDataFlow flow);
IMMDevice* GetDefaultDevice(EDataFlow flow); IMMDevice* GetDefaultDevice(EDataFlow flow);
private: private:
IMMDeviceEnumerator* pEnumerator = NULL; IMMDeviceEnumerator* pEnumerator = NULL;
IMMDeviceCollection* pRenderCollection = NULL; IMMDeviceCollection* pRenderCollection = NULL;
IMMDeviceCollection* pCaptureCollection = NULL; IMMDeviceCollection* pCaptureCollection = NULL;
IMMDevice* pDefaultRenderEndpoint = NULL; IMMDevice* pDefaultRenderEndpoint = NULL;
IMMDevice* pDefaultCaptureEndpoint = NULL; IMMDevice* pDefaultCaptureEndpoint = NULL;
HRESULT _UpdateDeviceList(EDataFlow flow); HRESULT _UpdateDeviceList(EDataFlow flow);
HRESULT _UpdateDefaultDevice(EDataFlow flow); HRESULT _UpdateDefaultDevice(EDataFlow flow);
}; };
}

View File

@@ -7,7 +7,7 @@
using namespace std; using namespace std;
std::string CmdUtil::ExecuteCommand(const std::string& command) std::string WinDevice::CmdUtil::ExecuteCommand(const std::string& command)
{ {
spdlog::info("ExecuteCommand command:{0}", command); spdlog::info("ExecuteCommand command:{0}", command);
auto cmd_result = std::string(); auto cmd_result = std::string();

View File

@@ -1,8 +1,11 @@
#pragma once #pragma once
#include <string> #include <string>
class CmdUtil
{ namespace WinDevice {
public: class CmdUtil
static std::string ExecuteCommand(const std::string& command); {
}; public:
static std::string ExecuteCommand(const std::string& command);
};
}

View File

@@ -1,17 +1,75 @@
#include "Log.h" #include "Log.h"
#include "spdlog/spdlog.h" #include <spdlog/logger.h>
#include <spdlog/sinks/stdout_color_sinks.h>
void Log::Init(LogLevel level, std::string fileName) std::shared_ptr<spdlog::logger> WinDevice::Log::logger = nullptr;
void WinDevice::Log::Init(LogLevel level, std::string fileName)
{ {
spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v"); logger = spdlog::stdout_color_mt("console");
logger->set_level(static_cast<spdlog::level::level_enum>(level));
logger->set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
// spdlog::set_level(static_cast<spdlog::level::level_enum>(level)); // 设置日志级别为 debug
// spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
} }
void Log::Info(std::string format, std::string args...) void WinDevice::Log::debug(std::string format)
{ {
logger->debug(format);
} }
void Log::WInfo(std::wstring format, std::wstring args...) void WinDevice::Log::debug(std::string format, std::string args...)
{ {
logger->debug(format, args);
}
void WinDevice::Log::debugW(std::wstring format, std::wstring args...)
{
logger->debug(format, args);
}
void WinDevice::Log::info(std::string format)
{
logger->info(format);
}
void WinDevice::Log::info(std::string format, std::string args...)
{
logger->info(format, args);
}
void WinDevice::Log::infoW(std::wstring format, std::wstring args...)
{
logger->info(format, args);
}
void WinDevice::Log::warn(std::string format)
{
logger->warn(format);
}
void WinDevice::Log::warn(std::string format, std::string args...)
{
logger->warn(format, args);
}
void WinDevice::Log::warnW(std::wstring format, std::wstring args...)
{
logger->warn(format, args);
}
void WinDevice::Log::error(std::string format)
{
logger->error(format);
}
void WinDevice::Log::error(std::string format, std::string args...)
{
logger->error(format, args);
}
void WinDevice::Log::errorW(std::wstring format, std::wstring args...)
{
logger->error(format, args);
} }

View File

@@ -1,20 +1,42 @@
#pragma once #pragma once
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_sinks.h"
#include <spdlog/sinks/stdout_color_sinks.h>
#define LOG_FUNC_START() spdlog::info("=====> {0} start <=====", __FUNCTION__) #define LOG_FUNC_START() spdlog::info("=====> {0} start <=====", __FUNCTION__)
#define LOG_FUNC_END() spdlog::info("=====> {0} end <=====", __FUNCTION__) #define LOG_FUNC_END() spdlog::info("=====> {0} end <=====", __FUNCTION__)
enum LogLevel : int namespace WinDevice {
{ enum LogLevel : int
Debug = spdlog::level::debug, {
Info = spdlog::level::info, Debug = spdlog::level::debug,
}; Info = spdlog::level::info,
};
class Log class Log
{ {
public: public:
static void Init(LogLevel level, std::string fileName); static void Init(LogLevel level, std::string fileName);
static void debug(std::string format);
static void debug(std::string format, std::string args...);
static void debugW(std::wstring format, std::wstring args...);
static void info(std::string format);
static void info(std::string format, std::string args...);
static void infoW(std::wstring format, std::wstring args...);
static void warn(std::string format);
static void warn(std::string format, std::string args...);
static void warnW(std::wstring format, std::wstring args...);
static void error(std::string format);
static void error(std::string format, std::string args...);
static void errorW(std::wstring format, std::wstring args...);
private:
static std::shared_ptr<spdlog::logger> logger;
};
}
static void Info(std::string format, std::string args...);
static void WInfo(std::wstring format, std::wstring args...);
};

View File

@@ -0,0 +1,175 @@
//
// Created by zyz on 2024/9/30.
//
#include "PerformanceTool.h"
#include "../Utils/StringUtil.h"
#include <Psapi.h>
#include <TlHelp32.h>
#include <Windows.h>
#include <powersetting.h>
#include <tchar.h>
#include <numeric>
#include <vector>
#include <thread>
#include <string>
#include <windows.h>
#include <psapi.h>
#include <string>
#include <tchar.h>
#include <iostream>
#pragma comment(lib, "PowrProf.lib")
#pragma comment(lib, "pdh.lib")
WinDevice::PerformanceTool::PerformanceTool() {
}
WinDevice::PerformanceTool::~PerformanceTool() {
}
float WinDevice::PerformanceTool::GetAppCpuUsage(DWORD processId) {
return _GetAppCpuUsage(processId, _GetProcessName(processId));
}
float WinDevice::PerformanceTool::GetAppCpuUsage(const std::wstring &processName) {
return _GetAppCpuUsage(_GetProcessId(processName), processName);
}
float WinDevice::PerformanceTool::_GetAppCpuUsage(DWORD processId, const std::wstring &processName) {
HQUERY query;
PDH_HCOUNTER cpuCounter;
PDH_FMT_COUNTERVALUE counterVal;
TCHAR szCounterPath[MAX_PATH];
// 初始化PDH
if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS) {
return 1;
}
// 构造CPU计数器路径
_stprintf_s(szCounterPath, MAX_PATH, TEXT("\\Process V2(%s:%d)\\%% Processor Time"), WinDevice::Wstring2String(processName).c_str(), processId);
if (PdhAddCounter(query, szCounterPath, 0, &cpuCounter) != ERROR_SUCCESS) {
PdhCloseQuery(query);
return 1;
}
PdhCollectQueryData(query);
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 等待以获取更新数据
// 再次收集数据
PdhCollectQueryData(query);
// 读取计数器值
auto cpuUsage = 0.0;
auto result = PdhGetFormattedCounterValue(cpuCounter, PDH_FMT_DOUBLE, NULL, &counterVal);
if (result == ERROR_SUCCESS) {
cpuUsage = counterVal.doubleValue;
}
// 清理
// 关闭句柄
PdhRemoveCounter(cpuCounter);
PdhCloseQuery(query);
return cpuUsage;
}
float WinDevice::PerformanceTool::GetAppMemoryUsage(const std::wstring &processName) {
return _GetAppMemoryUsage(processName);
}
float WinDevice::PerformanceTool::GetAppMemoryUsage(DWORD processId) {
return _GetAppMemoryUsage(_GetProcessName(processId));
}
float WinDevice::PerformanceTool::_GetAppMemoryUsage(const std::wstring &processName) {
HQUERY query;
PDH_HCOUNTER memCounter;
PDH_FMT_COUNTERVALUE counterVal;
TCHAR szCounterPath[MAX_PATH];
// 初始化PDH
if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS) {
return 1;
}
// 构造内存计数器路径
_stprintf_s(szCounterPath, MAX_PATH, TEXT("\\Process(%s)\\%s"), processName.c_str(), TEXT("Working Set - Private"));
if (PdhAddCounter(query, szCounterPath, 0, &memCounter) != ERROR_SUCCESS) {
PdhCloseQuery(query);
return 1;
}
PdhCollectQueryData(query);
auto memoryUsage = 0.0;
auto result = PdhGetFormattedCounterValue(memCounter, PDH_FMT_DOUBLE, NULL, &counterVal);
if (result == ERROR_SUCCESS) {
memoryUsage = counterVal.doubleValue / 1024.0 / 1024.0;
}
// 清理
// 关闭句柄
PdhRemoveCounter(memCounter);
PdhCloseQuery(query);
return memoryUsage;
}
std::wstring WinDevice::PerformanceTool::_GetProcessName(DWORD processId) {
std::wstring processName = L"<unknown>"; // 使用 std::wstring
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
if (hProcess != nullptr) {
HMODULE hMod;
DWORD cbNeeded;
// 获取进程中的模块句柄
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
// 获取模块的可执行文件名
TCHAR name[MAX_PATH];
GetModuleBaseName(hProcess, hMod, name, sizeof(name) / sizeof(TCHAR));
// 去掉 .exe 后缀
TCHAR* dot = _tcsrchr(name, '.');
if (dot != nullptr && _tcscmp(dot, TEXT(".exe")) == 0) {
*dot = '\0'; // 将 '.' 及其后面的字符替换为 '\0'
}
processName = WinDevice::TCHARArrayToWString(name); // 转换为 std::wstring
}
CloseHandle(hProcess); // 确保在这里关闭句柄
}
// 打印进程名称
std::wcout << L"Current process name: " << processName << std::endl;
return processName; // 返回 std::wstring
}
DWORD WinDevice::PerformanceTool::_GetProcessId(const std::wstring &processName) {
DWORD processId = 0;
//创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return 0;
}
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
// 遍历所有进程
if (Process32First(hSnapshot, &pe))
{
do
{
// 将进程名与目标进程名进行比较
if (_tcscmp(pe.szExeFile, WinDevice::Wstring2String(processName).c_str()) == 0)
{
processId = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe));
}
return processId;
}

View File

@@ -0,0 +1,47 @@
//
// Created by zyz on 2024/9/30.
//
#include <WTypesbase.h>
#include <Pdh.h>
#include <PdhMsg.h>
#include <vector>
#include <string>
#ifndef WINDEVICE_PERFORMANCETOOL_H
#define WINDEVICE_PERFORMANCETOOL_H
namespace WinDevice {
struct AppUsageInfo {
DWORD processId;
std::string processName;
float cpuUsage;
float memoryUsage;
};
class PerformanceTool {
public:
PerformanceTool();
~PerformanceTool();
float GetAppCpuUsage(DWORD processId);
float GetAppCpuUsage(const std::wstring& processName);
float GetAppMemoryUsage(DWORD processId);
float GetAppMemoryUsage(const std::wstring& processName);
// float GetCurrentAppCpuUsage();
// float GetCurrentAppMemoryUsage();
// WinDevice::AppUsageInfo GetCurrentAppUsage();
// WinDevice::AppUsageInfo GetAppUsage(DWORD processId);
// WinDevice::AppUsageInfo GetAppUsage(const std::wstring& processName);
// std::vector<WinDevice::AppUsageInfo> GetTopAppUsageInfo(int topCount);
// float GetTotalCpuUsage() const;
// float GetTotalMemoryUsage() const;
private:
float _GetAppCpuUsage(DWORD processId, const std::wstring &processName);
float _GetAppMemoryUsage(const std::wstring &processName);
std::wstring _GetProcessName(DWORD processId);
DWORD _GetProcessId(const std::wstring &processName);
};
}
#endif //WINDEVICE_PERFORMANCETOOL_H

View File

@@ -0,0 +1,70 @@
//
// Created by zyz on 2024/9/30.
//
#ifndef WINDEVICE_STRINGUTIL_CPP_H
#define WINDEVICE_STRINGUTIL_CPP_H
#include "StringUtil.h"
#include <windows.h>
#include <string>
#include <locale>
#include <codecvt>
template<typename To, typename From>
To Convert(const From &input) {
std::wstring_convert<std::codecvt_utf8<typename From::value_type>, typename From::value_type> converter;
try {
return converter.to_bytes(input);
} catch (...) {
return To(); // 返回空对象
}
}
std::string WinDevice::Wstring2String(const std::wstring &input) {
return Convert<std::string>(input);
}
std::string WinDevice::Wchar2String(const WCHAR *input) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
try {
return converter.to_bytes(input);
} catch (...) {
return ""; // 返回空字符串表示失败
}
}
std::wstring WinDevice::String2Wstring(const std::string &input) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
try {
return converter.from_bytes(input);
} catch (...) {
return L""; // 返回空宽字符串表示失败
}
}
wchar_t *WinDevice::String2Wchar(const std::string &input) {
std::wstring wstr = String2Wstring(input);
if (wstr.empty()) {
return nullptr; // 转换失败时返回 nullptr
}
wchar_t *wcharStr = new wchar_t[wstr.length() + 1];
std::wcscpy(wcharStr, wstr.c_str());
return wcharStr; // 返回动态分配的 wchar_t*
}
// 通用转换函数
std::wstring WinDevice::TCHARArrayToWString(const TCHAR *tcharArray) {
#ifdef UNICODE
return std::wstring(tcharArray); // 如果是 Unicode直接返回
#else
// 如果是 ANSI进行转换
int size_needed = MultiByteToWideChar(CP_ACP, 0, tcharArray, -1, nullptr, 0);
std::wstring wstrName(size_needed, L'\0'); // 创建足够大小的 std::wstring
MultiByteToWideChar(CP_ACP, 0, tcharArray, -1, &wstrName[0], size_needed);
return wstrName;
#endif
}
#endif //WINDEVICE_STRINGUTIL_CPP_H

View File

@@ -1,18 +1,13 @@
#include <string> #pragma once
#include <locale> #include <windows.h>
#include <codecvt> #include <string>
template<typename To, typename From> namespace WinDevice {
To Convert(const From& input) {
std::wstring_convert<std::codecvt_utf8<typename From::value_type>, typename From::value_type> converter; std::string Wstring2String(const std::wstring& input);
return converter.to_bytes(input); std::string Wchar2String(const WCHAR* input);
} std::wstring String2Wstring(const std::string& input);
wchar_t* String2Wchar(const std::string& input);
std::wstring TCHARArrayToWString(const TCHAR* tcharArray);
std::string Wstring2String(const std::wstring& input) {
return Convert<std::string>(input);
}
std::string Wchar2String(const WCHAR* input) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.to_bytes(input);
} }

View File

@@ -1,9 +1,8 @@
#include "TimeUtil.h" #include "TimeUtil.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
template <typename Func> template <typename Func>
void TimeUtil<Func>::CalExecuteTime(Func func) void WinDevice::TimeUtil<Func>::CalExecuteTime(Func func)
{ {
// 测量函数调用的耗时 // 测量函数调用的耗时
const auto start = std::chrono::high_resolution_clock::now(); const auto start = std::chrono::high_resolution_clock::now();
@@ -11,4 +10,4 @@ void TimeUtil<Func>::CalExecuteTime(Func func)
const auto end = std::chrono::high_resolution_clock::now(); const auto end = std::chrono::high_resolution_clock::now();
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
spdlog::info("Function call duration: {0} ms", duration.count()); spdlog::info("Function call duration: {0} ms", duration.count());
} }

View File

@@ -1,8 +1,11 @@
#pragma once #pragma once
template <typename Func>
class TimeUtil namespace WinDevice {
{ template <typename Func>
public: class TimeUtil
static void CalExecuteTime(Func func); {
}; public:
static void CalExecuteTime(Func func);
};
}

View File

@@ -0,0 +1,5 @@
//
// Created by zyz on 2024/10/8.
//
#include "AppWindowCapture.h"

View File

@@ -0,0 +1,20 @@
//
// Created by zyz on 2024/10/8.
//
#ifndef WINDEVICE_APPWINDOWCAPTURE_H
#define WINDEVICE_APPWINDOWCAPTURE_H
namespace WinDevice {
class AppWindowCapture {
public:
AppWindowCapture();
~AppWindowCapture();
void UpdateAppThumbnail();
private:
};
}
#endif //WINDEVICE_APPWINDOWCAPTURE_H

View File

@@ -0,0 +1,5 @@
//
// Created by zyz on 2024/10/8.
//
#include "ScreenCapture.h"

View File

@@ -0,0 +1,14 @@
//
// Created by zyz on 2024/10/8.
//
#ifndef WINDEVICE_SCREENCAPTURE_H
#define WINDEVICE_SCREENCAPTURE_H
namespace WinDevice {
class ScreenCapture {
};
}
#endif //WINDEVICE_SCREENCAPTURE_H

View File

@@ -1,27 +1,29 @@
#include "ScreenManager.h" #include "ScreenManager.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "Utils/StringUtil.h" #include "../Utils/StringUtil.h"
#include "Utils/Log.h" #include "../Utils/Log.h"
#include <dxgi.h> #include <dxgi.h>
ScreenManager::ScreenManager() using namespace WinDevice;
WinDevice::ScreenManager::ScreenManager()
{ {
} }
ScreenManager::~ScreenManager() WinDevice::ScreenManager::~ScreenManager()
{ {
} }
void ScreenManager::UpdateDisplayInfo() void WinDevice::ScreenManager::UpdateDisplayInfo()
{ {
_UpdateDisplayDeviceList(); _UpdateDisplayDeviceList();
_UpdateMonitorInfoMap(); _UpdateMonitorInfoMap();
_UpdateDisplayAdapterList(); _UpdateDisplayAdapterList();
} }
void ScreenManager::_UpdateDisplayDeviceList() void WinDevice::ScreenManager::_UpdateDisplayDeviceList()
{ {
spdlog::info("=====GetInfoByEnumDisplayDevices start====="); spdlog::info("=====GetInfoByEnumDisplayDevices start=====");
DISPLAY_DEVICE displayDevice; DISPLAY_DEVICE displayDevice;
@@ -39,7 +41,7 @@ void ScreenManager::_UpdateDisplayDeviceList()
spdlog::info("=====GetInfoByEnumDisplayDevices end====="); spdlog::info("=====GetInfoByEnumDisplayDevices end=====");
} }
void ScreenManager::_UpdateDisplayAdapterList() void WinDevice::ScreenManager::_UpdateDisplayAdapterList()
{ {
LOG_FUNC_START(); LOG_FUNC_START();
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -56,8 +58,8 @@ void ScreenManager::_UpdateDisplayAdapterList()
DXGI_ADAPTER_DESC adapterDesc; DXGI_ADAPTER_DESC adapterDesc;
pAdapter->GetDesc(&adapterDesc); pAdapter->GetDesc(&adapterDesc);
spdlog::info("Adapter Index:{0}, Description:{1}, DeviceId:{2}, VendorId:{3}, SubSysId:{4}, Revision:{5}, AdapterLuid(H-L):{6}-{7} ", spdlog::info("Adapter Index:{0}, Description:{1}, DeviceId:{2}, VendorId:{3}, SubSysId:{4}, Revision:{5}, AdapterLuid(H-L):{6}-{7} ",
adapterIndex, Wchar2String(adapterDesc.Description), adapterDesc.DeviceId, adapterDesc.VendorId, adapterDesc.SubSysId, adapterIndex, WinDevice::Wchar2String(adapterDesc.Description), adapterDesc.DeviceId, adapterDesc.VendorId, adapterDesc.SubSysId,
adapterDesc.Revision, adapterDesc.AdapterLuid.HighPart, adapterDesc.AdapterLuid.LowPart); adapterDesc.Revision, adapterDesc.AdapterLuid.HighPart, adapterDesc.AdapterLuid.LowPart);
// print adapter output info // print adapter output info
IDXGIOutput* pOutput; IDXGIOutput* pOutput;
@@ -72,7 +74,7 @@ void ScreenManager::_UpdateDisplayAdapterList()
{ {
// 输出友好名称 // 输出友好名称
spdlog::info("Adapter Output Index:{0}, DeviceName:{1}, szDevice:{2}, right:{3}, bottom:{4}", spdlog::info("Adapter Output Index:{0}, DeviceName:{1}, szDevice:{2}, right:{3}, bottom:{4}",
j, Wchar2String(outputDesc.DeviceName), monitorInfo.szDevice, monitorInfo.rcMonitor.right, monitorInfo.rcMonitor.bottom); j, WinDevice::Wchar2String(outputDesc.DeviceName), monitorInfo.szDevice, monitorInfo.rcMonitor.right, monitorInfo.rcMonitor.bottom);
} }
} }
} }
@@ -80,9 +82,10 @@ void ScreenManager::_UpdateDisplayAdapterList()
LOG_FUNC_END(); LOG_FUNC_END();
} }
BOOL ScreenManager::_EnumMonitorProc(HMONITOR hMonitor) BOOL WinDevice::ScreenManager::_EnumMonitorProc(HMONITOR hMonitor)
{ {
MONITORINFOEX monitorInfo; HRESULT result;
MONITORINFOEX monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFOEX); monitorInfo.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, &monitorInfo)) if (GetMonitorInfo(hMonitor, &monitorInfo))
{ {
@@ -107,38 +110,38 @@ BOOL ScreenManager::_EnumMonitorProc(HMONITOR hMonitor)
targetDeviceName.header.size = sizeof(targetDeviceName); targetDeviceName.header.size = sizeof(targetDeviceName);
// 获取指定 HMONITOR 的目标设备名称信息 // 获取指定 HMONITOR 的目标设备名称信息
if (DisplayConfigGetDeviceInfo(&targetDeviceName.header) == ERROR_SUCCESS) result = DisplayConfigGetDeviceInfo(&targetDeviceName.header);
if (result == ERROR_SUCCESS)
{ {
spdlog::info("_UpdateMonitorInfoMap, monitorDevicePath:{0}, monitorFriendlyDeviceName:{1}", spdlog::info("_UpdateMonitorInfoMap, monitorDevicePath:{0}, monitorFriendlyDeviceName:{1}",
Wchar2String(targetDeviceName.monitorDevicePath), Wchar2String(targetDeviceName.monitorFriendlyDeviceName)); WinDevice::Wchar2String(targetDeviceName.monitorDevicePath), WinDevice::Wchar2String(targetDeviceName.monitorFriendlyDeviceName));
// 获取指定 HMONITOR 的分辨率信息 // 获取指定 HMONITOR 的分辨率信息
DEVMODE dm; DEVMODE dm;
dm.dmSize = sizeof(DEVMODE); dm.dmSize = sizeof(DEVMODE);
dm.dmDriverExtra = 0; dm.dmDriverExtra = 0;
if (EnumDisplaySettingsA((LPCSTR)targetDeviceName.monitorDevicePath, ENUM_CURRENT_SETTINGS, &dm))
if (EnumDisplaySettingsA((LPCSTR)targetDeviceName.monitorDevicePath, ENUM_CURRENT_SETTINGS, &dm) != 0)
{ {
spdlog::info("Resolution:{0}x{1}", dm.dmPelsWidth, dm.dmPelsHeight); spdlog::info("Resolution:{0}x{1}", dm.dmPelsWidth, dm.dmPelsHeight);
} }
else else
{ {
spdlog::info("Failed to get display resolution."); Log::error("Failed to get display resolution");
} }
} }
else else
{ {
spdlog::info("Failed to get display device info."); spdlog::error("Failed to get display device info, error:{0}", result);
} }
return TRUE; return TRUE;
} }
BOOL CALLBACK ScreenManager::EnumMonitorsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) BOOL CALLBACK WinDevice::ScreenManager::EnumMonitorsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{ {
return ((ScreenManager*)dwData)->_EnumMonitorProc(hMonitor); return ((ScreenManager*)dwData)->_EnumMonitorProc(hMonitor);
} }
void ScreenManager::_UpdateMonitorInfoMap() void WinDevice::ScreenManager::_UpdateMonitorInfoMap()
{ {
spdlog::info("=====GetInfoByEnumDisplayMonitors start====="); spdlog::info("=====GetInfoByEnumDisplayMonitors start=====");
// 枚举显示器 // 枚举显示器

View File

@@ -3,21 +3,23 @@
#include <map> #include <map>
#include <dxgi.h> #include <dxgi.h>
class ScreenManager namespace WinDevice {
{ class ScreenManager
public: {
ScreenManager(); public:
~ScreenManager(); ScreenManager();
void UpdateDisplayInfo(); ~ScreenManager();
void UpdateDisplayInfo();
std::vector<DISPLAY_DEVICE> _displayDeviceList; std::vector<DISPLAY_DEVICE> _displayDeviceList;
std::map<HMONITOR, MONITORINFOEX> _hMonitorInfoMap; std::map<HMONITOR, MONITORINFOEX> _hMonitorInfoMap;
std::vector<IDXGIAdapter*> _displayAdapterList; std::vector<IDXGIAdapter*> _displayAdapterList;
private: private:
void _UpdateDisplayDeviceList(); void _UpdateDisplayDeviceList();
void _UpdateMonitorInfoMap(); void _UpdateMonitorInfoMap();
void _UpdateDisplayAdapterList(); void _UpdateDisplayAdapterList();
static BOOL CALLBACK EnumMonitorsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); static BOOL CALLBACK EnumMonitorsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
BOOL _EnumMonitorProc(HMONITOR hMonitor); BOOL _EnumMonitorProc(HMONITOR hMonitor);
}; };
}

View File

@@ -0,0 +1,5 @@
//
// Created by zyz on 2024/10/8.
//
#include "VideoManager.h"

View File

@@ -0,0 +1,24 @@
//
// Created by zyz on 2024/10/8.
//
#ifndef WINDEVICE_VIDEOMANAGER_H
#define WINDEVICE_VIDEOMANAGER_H
#include <minwindef.h>
#include <windef.h>
namespace WinDevice {
class VideoManager {
public:
VideoManager();
~VideoManager();
private:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
void _UpdateAppThumnbail();
};
}
#endif //WINDEVICE_VIDEOMANAGER_H

View File

@@ -0,0 +1,15 @@
#include "WinDeviceManager.h"
#include "Utils/Log.h"
WinDevice::WinDeviceManager::WinDeviceManager() {
}
WinDevice::WinDeviceManager::~WinDeviceManager() {
}
void WinDevice::WinDeviceManager::Init() {
Log::Init(LogLevel::Debug, "WinDevice.log");
}

View File

@@ -0,0 +1,16 @@
#ifndef WINDEVICEMANAGER_H
#define WINDEVICEMANAGER_H
#endif // WINDEVICEMANAGER_H
namespace WinDevice {
class WinDeviceManager
{
public:
WinDeviceManager();
~WinDeviceManager();
static void Init();
};
}

View File

@@ -2,11 +2,32 @@
// Created by zyz on 2023/12/20. // Created by zyz on 2023/12/20.
// //
#include <iostream> #include <iostream>
#include <thread>
#include "Video/ScreenManager.h" #include "Video/ScreenManager.h"
#include "Utils/PerformanceTool.h"
#include "Utils/Log.h"
void getInfo() {
WinDevice::PerformanceTool performanceTool;
while (true) {
std::cout << "App CPU Usage: " << performanceTool.GetAppCpuUsage(L"XYWinQT.pak") << "%" << std::endl;
// 每隔一秒采样一次(如果需要的话)
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() { int main() {
ScreenManager screenManager; WinDevice::Log::Init(WinDevice::LogLevel::Debug, "");
WinDevice::ScreenManager screenManager;
screenManager.UpdateDisplayInfo(); screenManager.UpdateDisplayInfo();
// getInfo();
std::cout << "Press Enter to exit..." << std::endl; // 输出提示信息 std::cout << "Press Enter to exit..." << std::endl; // 输出提示信息
std::cin.get(); // 等待用户输入 std::cin.get(); // 等待用户输入
return 0; return 0;
} }

View File

@@ -1,22 +0,0 @@
// WinDeviceDemo.cpp: 定义应用程序的入口点。
//
#include "WinDeviceDemo.h"
#include "Video/ScreenManager.h"
using namespace std;
int main()
{
HRESULT hr = S_OK;
hr = CoInitialize(nullptr);
if (FAILED(hr)) {
return 0;
}
cout << "Hello CMake." << endl;
ScreenManager screenManager;
screenManager.UpdateDisplayInfo();
CoUninitialize();
return 0;
}

View File

@@ -1,8 +0,0 @@
// WinDeviceDemo.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。
#pragma once
#include <iostream>
// TODO: 在此处引用程序需要的其他标头。