zhuizhu преди 7 месеца
родител
ревизия
1070734c3b
променени са 100 файла, в които са добавени 5126 реда и са изтрити 142 реда
  1. 1 0
      .gitignore
  2. 6 0
      .qtcreator/project.json
  3. 209 0
      .qtcreator/project.json.user
  4. 0 2
      .vscode/compile_commands.json
  5. 0 10
      .vscode/settings.json
  6. 39 52
      AV/xmake.lua
  7. 15 12
      LearningSmartClient.pro
  8. 31 57
      MainPanel.cpp
  9. 15 5
      MainPanel.h
  10. 218 0
      ScreenWall/CMakeLists.txt
  11. 201 0
      ScreenWall/CMakeLists_simple.txt
  12. 269 0
      ScreenWall/README.md
  13. 258 0
      ScreenWall/README_simple.md
  14. 273 0
      ScreenWall/main111.cpp
  15. 185 0
      ScreenWall/main_simple.cpp
  16. 1654 0
      ScreenWall/screenwall_simple.cpp
  17. 374 0
      ScreenWall/screenwall_simple.h
  18. 1073 0
      ScreenWall/screenwall_widget.cpp
  19. 273 0
      ScreenWall/screenwall_widget.h
  20. 24 0
      api/xmake.lua
  21. BIN
      bin/2025-08-26-21-44-41.mp4
  22. BIN
      bin/LearningSmartClient.exe
  23. BIN
      bin/LearningSmartClient.exp
  24. BIN
      bin/LearningSmartClient.lib
  25. BIN
      bin/LearningSmartClient.pdb
  26. BIN
      bin/bin_0.1.2.7z
  27. BIN
      bin/bin_0.1.3.7z
  28. BIN
      bin/bin_0.2.1.7z
  29. BIN
      bin/bin_0.3.1.7z
  30. 0 0
      libs/AVPlayer2/AvPlayer2.pri
  31. 0 0
      libs/AVPlayer2/PlayWidget.cpp
  32. 0 0
      libs/AVPlayer2/PlayWidget.h
  33. 0 0
      libs/AVPlayer2/ThreadBase.h
  34. 0 0
      libs/AVPlayer2/Visual Leak Detector/AUTHORS.txt
  35. 0 0
      libs/AVPlayer2/Visual Leak Detector/CHANGES.txt
  36. 0 0
      libs/AVPlayer2/Visual Leak Detector/COPYING.txt
  37. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win32/Microsoft.DTfW.DHL.manifest
  38. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win32/dbghelp.dll
  39. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win32/vld_x86.dll
  40. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win64/Microsoft.DTfW.DHL.manifest
  41. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win64/dbghelp.dll
  42. 0 0
      libs/AVPlayer2/Visual Leak Detector/bin/Win64/vld_x64.dll
  43. 0 0
      libs/AVPlayer2/Visual Leak Detector/include/vld.h
  44. 0 0
      libs/AVPlayer2/Visual Leak Detector/include/vld_def.h
  45. 0 0
      libs/AVPlayer2/Visual Leak Detector/lib/Win32/vld.lib
  46. 0 0
      libs/AVPlayer2/Visual Leak Detector/lib/Win64/vld.lib
  47. 0 0
      libs/AVPlayer2/Visual Leak Detector/unins000.dat
  48. 0 0
      libs/AVPlayer2/Visual Leak Detector/unins000.exe
  49. 0 0
      libs/AVPlayer2/Visual Leak Detector/vld.ini
  50. 0 0
      libs/AVPlayer2/app_settings.cpp
  51. 0 0
      libs/AVPlayer2/app_settings.h
  52. 0 0
      libs/AVPlayer2/audio_decode_thread.cpp
  53. 0 0
      libs/AVPlayer2/audio_decode_thread.h
  54. 0 0
      libs/AVPlayer2/audio_effect_gl.cpp
  55. 0 0
      libs/AVPlayer2/audio_effect_gl.h
  56. 0 0
      libs/AVPlayer2/audio_effect_helper.cpp
  57. 0 0
      libs/AVPlayer2/audio_effect_helper.h
  58. 3 1
      libs/AVPlayer2/audio_play_thread.cpp
  59. 0 0
      libs/AVPlayer2/audio_play_thread.h
  60. 0 0
      libs/AVPlayer2/clickable_slider.cpp
  61. 0 0
      libs/AVPlayer2/clickable_slider.h
  62. 0 0
      libs/AVPlayer2/common.cpp
  63. 0 0
      libs/AVPlayer2/common.h
  64. 0 0
      libs/AVPlayer2/ffmpeg_init.cpp
  65. 0 0
      libs/AVPlayer2/ffmpeg_init.h
  66. 0 0
      libs/AVPlayer2/log.cpp
  67. 0 0
      libs/AVPlayer2/log.h
  68. 0 0
      libs/AVPlayer2/mainwindowa.cpp
  69. 1 1
      libs/AVPlayer2/mainwindowa.h
  70. 0 0
      libs/AVPlayer2/network_url_dlg.cpp
  71. 0 0
      libs/AVPlayer2/network_url_dlg.h
  72. 0 0
      libs/AVPlayer2/network_url_dlg.ui
  73. 0 0
      libs/AVPlayer2/packets_sync.cpp
  74. 1 1
      libs/AVPlayer2/packets_sync.h
  75. 0 0
      libs/AVPlayer2/play_control_window.cpp
  76. 0 0
      libs/AVPlayer2/play_control_window.h
  77. 0 0
      libs/AVPlayer2/playercontroller.cpp
  78. 3 1
      libs/AVPlayer2/playercontroller.h
  79. 0 0
      libs/AVPlayer2/playlist_window.cpp
  80. 0 0
      libs/AVPlayer2/playlist_window.h
  81. 0 0
      libs/AVPlayer2/playlist_window.ui
  82. 0 0
      libs/AVPlayer2/qimage_operation.cpp
  83. 0 0
      libs/AVPlayer2/qimage_operation.h
  84. 0 0
      libs/AVPlayer2/qmake_qmake_qm_files.qrc
  85. 0 0
      libs/AVPlayer2/read_thread.cpp
  86. 0 0
      libs/AVPlayer2/read_thread.h
  87. 0 0
      libs/AVPlayer2/res/QSS-master.zip
  88. 0 0
      libs/AVPlayer2/res/QSS/AMOLED.qss
  89. 0 0
      libs/AVPlayer2/res/QSS/Aqua.qss
  90. 0 0
      libs/AVPlayer2/res/QSS/ConsoleStyle.qss
  91. 0 0
      libs/AVPlayer2/res/QSS/ElegantDark.qss
  92. 0 0
      libs/AVPlayer2/res/QSS/LICENSE
  93. 0 0
      libs/AVPlayer2/res/QSS/MacOS.qss
  94. 0 0
      libs/AVPlayer2/res/QSS/ManjaroMix.qss
  95. 0 0
      libs/AVPlayer2/res/QSS/MaterialDark.qss
  96. 0 0
      libs/AVPlayer2/res/QSS/NeonButtons.qss
  97. 0 0
      libs/AVPlayer2/res/QSS/QSS_IMG/go-down-symbolic.symbolic.png
  98. 0 0
      libs/AVPlayer2/res/QSS/QSS_IMG/go-next-symbolic.symbolic.png
  99. 0 0
      libs/AVPlayer2/res/QSS/QSS_IMG/go-previous-symbolic.symbolic.png
  100. 0 0
      libs/AVPlayer2/res/QSS/QSS_IMG/go-up-symbolic.symbolic.png

+ 1 - 0
.gitignore

@@ -18,3 +18,4 @@
 /AV/.xmake
 /.xmake
 /ci_build
+/.vscode

+ 6 - 0
.qtcreator/project.json

@@ -0,0 +1,6 @@
+{
+    "$schema": "https://download.qt.io/official_releases/qtcreator/latest/installer_source/jsonschemas/project.json",
+    "files.exclude": [
+        ".qtcreator/project.json.user"
+    ]
+}

+ 209 - 0
.qtcreator/project.json.user

@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 17.0.0, 2025-09-02T21:43:57. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{df866c91-ea4c-46cc-83ed-5aed157f4066}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="qlonglong">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoDetect">true</value>
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.2">
+    <value type="QString" key="language">Nim</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">NimGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">3</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
+   <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="bool" key="EditorConfiguration.UseIndenter">false</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+   <value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
+    <value type="bool" key="AutoTest.Framework.Boost">true</value>
+    <value type="bool" key="AutoTest.Framework.CTest">false</value>
+    <value type="bool" key="AutoTest.Framework.Catch">true</value>
+    <value type="bool" key="AutoTest.Framework.GTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtTest">true</value>
+   </valuemap>
+   <value type="bool" key="AutoTest.ApplyFilter">false</value>
+   <valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
+   <valuelist type="QVariantList" key="AutoTest.PathFilters"/>
+   <value type="int" key="AutoTest.RunAfterBuild">0</value>
+   <value type="bool" key="AutoTest.UseGlobal">true</value>
+   <valuemap type="QVariantMap" key="ClangTools">
+    <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
+    <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
+    <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
+    <value type="int" key="ClangTools.ParallelJobs">12</value>
+    <value type="bool" key="ClangTools.PreferConfigFile">true</value>
+    <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
+    <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
+    <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
+    <value type="bool" key="ClangTools.UseGlobalSettings">true</value>
+   </valuemap>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="DeviceType">Desktop</value>
+   <value type="bool" key="HasPerBcDcs">true</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.2 MSVC2019 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.2 MSVC2019 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5152.win64_msvc2019_64_kit</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">F:\A_QT\im\LearningSmartClient\build</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">默认</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">WorkspaceProject.BuildConfiguration</value>
+    <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+    <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+      <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+     <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
+     <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+    </valuemap>
+    <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+     <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+     <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+     <value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
+     <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+     <valuelist type="QVariantList" key="CustomOutputParsers"/>
+     <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+     <value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
+     <value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
+     <value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
+     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    </valuemap>
+    <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
+    <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="CustomOutputParsers"/>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
+    <value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
+    <value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="qlonglong">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">22</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">22</value>
+ </data>
+</qtcreator>

+ 0 - 2
.vscode/compile_commands.json

@@ -1,2 +0,0 @@
-[
-]

+ 0 - 10
.vscode/settings.json

@@ -1,10 +0,0 @@
-{
-  "files.associations": {
-    "*.lua": "lua",
-    "*.tcc": "cpp",
-    "optional": "cpp",
-    "system_error": "cpp",
-    "regex": "cpp"
-  },
-  "cmake.sourceDirectory": "F:/A_QT/im/LearningSmartClient/qwindowkit/examples/mainwindow"
-}

+ 39 - 52
AV/xmake.lua

@@ -1,39 +1,10 @@
-set_project("AV_Framework")
-set_version("1.0.0")
-set_languages("c++17")
-
--- 设置编译模式
-add_rules("mode.debug", "mode.release")
-
--- FFmpeg库路径配置 - 支持环境变量和默认路径
-local ffmpeg_path = os.getenv("FFMPEG_PATH") or "E:/AAA/ffmpeg-7.0.2-full_build-shared"
-local ffmpeg_include = ffmpeg_path .. "/include"
-local ffmpeg_lib = ffmpeg_path .. "/lib"
-
--- 检查FFmpeg路径是否存在
-if not os.isdir(ffmpeg_include) then
-    print("Warning: FFmpeg include directory not found: " .. ffmpeg_include)
-    print("Please set FFMPEG_PATH environment variable or update the path in xmake.lua")
-end
-
-set_runtimes("MD")
-
--- 公共FFmpeg配置函数
-function add_ffmpeg_config()
-    if is_plat("windows") then
-        add_includedirs(ffmpeg_include)
-        add_linkdirs(ffmpeg_lib)
-        add_links("avcodec", "avformat", "avutil", "swscale", "swresample")
-        add_links("avdevice", "avfilter", "postproc")
-    else
-        add_links("avcodec", "avformat", "avutil", "swscale", "swresample")
-    end
-end
+-- AV 框架子模块配置
+-- 此文件被主项目通过 includes("AV") 引入
 
 -- 公共基础配置函数
-function add_common_config()
+function add_av_common_config()
     add_includedirs(".", {public = true})
-    set_targetdir("$(buildir)/bin")
+    add_includedirs("code", {public = true})
 end
 
 -- 基础库
@@ -41,7 +12,7 @@ target("av_base")
     set_kind("static")
     add_files("code/base/*.cpp")
     add_headerfiles("code/base/*.h")
-    add_includedirs(".", {public = true})
+    add_av_common_config()
     
     -- FFmpeg配置
     add_ffmpeg_config()
@@ -58,7 +29,7 @@ target("av_codec")
     set_kind("static")
     add_files("code/codec/*.cpp")
     add_headerfiles("code/codec/*.h")
-    add_includedirs(".", {public = true})
+    add_av_common_config()
     add_deps("av_base")
     
     -- FFmpeg配置
@@ -69,7 +40,7 @@ target("av_capture")
     set_kind("static")
     add_files("code/capture/*.cpp")
     add_headerfiles("code/capture/*.h")
-    add_includedirs(".", {public = true})
+    add_av_common_config()
     add_deps("av_base")
     
     -- FFmpeg配置
@@ -80,7 +51,7 @@ target("av_muxer")
     set_kind("static")
     add_files("code/muxer/*.cpp")
     add_headerfiles("code/muxer/*.h")
-    add_includedirs(".", {public = true})
+    add_av_common_config()
     add_deps("av_base")
     
     -- FFmpeg配置
@@ -91,29 +62,45 @@ target("av_utils")
     set_kind("static")
     add_files("code/utils/*.cpp")
     add_headerfiles("code/utils/*.h")
-    add_includedirs(".", {public = true})
+    add_av_common_config()
     add_deps("av_base")
     
     -- FFmpeg配置
     add_ffmpeg_config()
 
--- -- 完整的AV框架库
--- target("av_framework")
---     set_kind("static")
---     add_deps("av_base", "av_codec", "av_capture", "av_muxer", "av_utils")
---     add_includedirs(".", {public = true})
-
-
-
-target("player")
-    add_rules("qt.widgetapp")
-    add_common_config()
-    add_files("integration_example.cpp", {rules = "qt.moc"})
+-- 完整的AV框架库 - 主项目依赖的统一接口
+target("av_framework")
+    set_kind("static")
     add_deps("av_base", "av_codec", "av_capture", "av_muxer", "av_utils")
+    add_av_common_config()
+    
+    -- 导出所有子模块的接口
+    add_headerfiles("code/**/*.h")
+
+-- 播放器库
+target("av_player")
+    set_kind("static")
     add_files("code/player/*.cpp")
     add_headerfiles("code/player/*.h")
-    add_files("code/player/*.h", {rules = "qt.moc"})
-    add_frameworks("QtNetwork", "QtGui", "QtCore", "QtWidgets", "QtMultimedia", "QtOpenGL")
+    add_av_common_config()
+    add_deps("av_base", "av_codec")
+    
+    -- Qt 配置
+    add_qt_config()
+    
+    -- FFmpeg配置
+    add_ffmpeg_config()
+
+-- 录制器库
+target("av_recorder")
+    set_kind("static")
+    add_files("code/recorder/*.cpp")
+    add_headerfiles("code/recorder/*.h")
+    add_av_common_config()
+    add_deps("av_base", "av_codec", "av_capture", "av_muxer")
+    
+    -- Qt 配置
+    add_qt_config()
     
     -- FFmpeg配置
     add_ffmpeg_config()

+ 15 - 12
LearningSmartClient.pro

@@ -1,5 +1,6 @@
-QT       += core gui network svg
+QT       += core gui network svg xml
 QT += multimedia websockets
+QT += winextras
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 CONFIG += console
 CONFIG += c++17
@@ -13,6 +14,9 @@ QT += opengl
 
 SOURCES += \
     MainPanel.cpp \
+    ScreenWall/main_simple.cpp \
+    ScreenWall/screenwall_simple.cpp \
+    ScreenWall/screenwall_widget.cpp \
     api/chatapi.cpp \
     api/loginapi.cpp \
     api/roomapi.cpp \
@@ -20,7 +24,6 @@ SOURCES += \
     appevent.cpp \
     main.cpp \
     mainwindow.cpp \
-    models/chatmodels.cpp \
     network/networkaccessmanager.cpp \
     network/request.cpp \
     network/websocketclient.cpp \
@@ -38,6 +41,7 @@ SOURCES += \
     widgets/chatView/chat1/chatmessagemodel.cpp \
     widgets/chatView/chat1/chatview.cpp \
     widgets/chatView/chatwindow.cpp \
+    widgets/chatView/independentchatwindow.cpp \
     widgets/colorlistwidget.cpp \
     widgets/createmeetingdialog.cpp \
     widgets/framelessbase.cpp \
@@ -45,17 +49,19 @@ SOURCES += \
     widgets/maskoverlay.cpp \
     widgets/meetingselectionwidget.cpp \
     widgets/statswidget.cpp \
-    widgets/userprofilewidget.cpp
+    widgets/userprofilewidget.cpp  \
+    widgets/windowpreviewwidget.cpp
 
 HEADERS += \
     MainPanel.h \
+    ScreenWall/screenwall_simple.h \
+    ScreenWall/screenwall_widget.h \
     api/chatapi.h \
     api/loginapi.h \
     api/roomapi.h \
     api/userapi.h \
     appevent.h \
     mainwindow.h \
-    models/chatmodels.h \
     network/networkaccessmanager.h \
     network/request.h \
     network/websocketclient.h \
@@ -75,6 +81,7 @@ HEADERS += \
     widgets/chatView/chat1/chatmessagemodel.h \
     widgets/chatView/chat1/chatview.h \
     widgets/chatView/chatwindow.h \
+    widgets/chatView/independentchatwindow.h \
     widgets/colorlistwidget.h \
     widgets/createmeetingdialog.h \
     widgets/framelessbase.h \
@@ -82,7 +89,8 @@ HEADERS += \
     widgets/maskoverlay.h \
     widgets/meetingselectionwidget.h \
     widgets/statswidget.h \
-    widgets/userprofilewidget.h
+    widgets/userprofilewidget.h  \
+    widgets/windowpreviewwidget.h
 
 msvc {
     QMAKE_CFLAGS += /utf-8
@@ -90,15 +98,10 @@ msvc {
 }
 
 DEFINES += _SILENCE_CLANG_COROUTINE_MESSAGE
-include($$PWD/AvRecorder/AvRecorder.pri)
-include($$PWD/AvPlayer2/AvPlayer2.pri)
 
-include($$PWD/qwindowkit/qwindowkit.pri)
-include($$PWD/fmt.pri)
-include($$PWD/qtpromise/qtpromise.pri)
-include($$PWD/jsonserializer/jsonserializer.pri)
+include($$PWD/libs/libs.pri)
+
 
-include($$PWD/AV/AV.pri)
 
 
 INCLUDEPATH+="E:/AAA/ffmpeg-7.0.2-full_build-shared/include"

+ 31 - 57
MainPanel.cpp

@@ -1,7 +1,7 @@
 #include "MainPanel.h"
 #include <QSplitter>
 #include <QVBoxLayout>
-#include <QListWidget>
+
 
 #include <util/jsonmapper.h>
 
@@ -15,6 +15,8 @@
 
 #include "widgets/bubbletip.h"
 #include "widgets/chatView/chatwindow.h"
+
+#include "advanceddockingsystem/dockmanager.h"
 #include "widgets/maskoverlay.h"
 #include "widgets/userprofilewidget.h"
 #include "widgets/statswidget.h"
@@ -40,25 +42,43 @@ MainPanel::MainPanel(QWidget *parent)
     chatView = new ChatWindow(webSocketClient);
     chatView->setMinimumWidth(400);
     statsWidget = new StatsWidget(this);
+    
+    // 初始化 DockManager
+    m_dockManager = new ADS::DockManager(this);
+    m_dockManager->setStyleSheet(""); // 使用应用程序的样式表
 
+    // 创建右侧面板作为可停靠的 DockWidget
     QWidget *rightWidget = new QWidget;
     QVBoxLayout *vbox = new QVBoxLayout(rightWidget);
     vbox->setContentsMargins(0, 0, 0, 0);
     vbox->addWidget(userProfile, 0);
     vbox->addWidget(statsWidget, 0);
     vbox->addWidget(chatView, 1);
+    
+    ADS::DockWidget* rightDockWidget = new ADS::DockWidget("聊天面板", this);
+    rightDockWidget->setWidget(rightWidget);
+    rightDockWidget->setFeature(ADS::DockWidget::DockWidgetClosable, true);
 
-    m_roomListWidget = new QListWidget;
-    splitter = new QSplitter(Qt::Horizontal, this);
+    // 创建中央内容
     playerContainer = new QWidget(this);
-    splitter->addWidget(m_roomListWidget);
-    splitter->addWidget(playerContainer);
-    splitter->addWidget(rightWidget);
-    splitter->setStretchFactor(0, 10);
-    splitter->setStretchFactor(1, 60);
-    splitter->setStretchFactor(2, 30);
+    
+    // 创建中央播放器 DockWidget
+    ADS::DockWidget* centerDockWidget = new ADS::DockWidget("播放器", this);
+    centerDockWidget->setWidget(playerContainer);
+    centerDockWidget->setFeature(ADS::DockWidget::DockWidgetClosable, false);
+    centerDockWidget->setFeature(ADS::DockWidget::DockWidgetMovable, false);
+    centerDockWidget->setFeature(ADS::DockWidget::DockWidgetFloatable, false);
+    
+    // 将 DockWidget 添加到 DockManager
+    // m_dockManager->addDockWidget(ADS::LeftDockWidgetArea, leftDockWidget);
+    m_dockManager->addDockWidget(ADS::CenterDockWidgetArea, centerDockWidget);
+    m_dockManager->addDockWidget(ADS::RightDockWidgetArea, rightDockWidget);
+    
+    // 保存 splitter 引用以保持兼容性
+    splitter = nullptr; // 不再使用 QSplitter
+    
     QVBoxLayout *mainLayout = new QVBoxLayout(this);
-    mainLayout->addWidget(splitter, 1);
+    mainLayout->addWidget(m_dockManager, 1);
     mainLayout->setContentsMargins(0, 0, 0, 0);
     mainLayout->setSpacing(0);
     setLayout(mainLayout);
@@ -69,7 +89,7 @@ MainPanel::MainPanel(QWidget *parent)
             userProfile->setStatus(connected ? "在线" : "离线");
         }
     });
-    connect(m_roomListWidget, &QListWidget::itemDoubleClicked, this, &MainPanel::roomItemChanged);
+
     connect(userProfile, &UserProfileWidget::logoutClicked, this, &MainPanel::logoutClicked);
     connect(webSocketClient, &WebSocketClient::statsUpdate, statsWidget, &StatsWidget::updateStats);
     connect(webSocketClient, &WebSocketClient::liveStatus, this, [this](const QString &msg) {
@@ -119,8 +139,6 @@ void MainPanel::setRole(const QStringList &roleList)
     }
     setPlayerWidget(newPlayer);
 
-    m_roomListWidget->hide();
-
     // 设置初始化信息
     const QString &name = AppEvent::instance()->userName();
     userProfile->setUsername(name);
@@ -191,51 +209,7 @@ void MainPanel::setPlayerWidget(QWidget *newPlayer)
     playerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 }
 
-void MainPanel::roomItemChanged(QListWidgetItem *item)
-{
-    if (item) {
-        const QString id = item->data(Qt::UserRole + 100).value<QString>();
 
-        if (!playerWidget) {
-            return;
-        }
-
-        // // 推流配置
-        // if (AvRecorder *avRecorder = qobject_cast<AvRecorder *>(playerWidget)) {
-        //     SettingsPage::Param param;
-        //     param.liveUrl = "rtmp://106.55.186.74:1935/stream/V1";
-        //     param.liveName = id.toStdString();
-        //     avRecorder->setSettings(param);
-        // }
-        // 拉取视频流程
-        if (PlayWidget *playWidget = qobject_cast<PlayWidget *>(playerWidget)) {
-            MaskOverlay::instance()->show(nullptr, 0, MaskOverlay::ActiveWindow);
-
-            QFuture<HttpResponse> getRoomFuture = getRoomApi(id);
-            QtPromise::QPromise<HttpResponse> roomListPromise = QtPromise::resolve(getRoomFuture);
-
-            roomListPromise
-                .then([this, playWidget, id](const HttpResponse &response) {
-                    qDebug() << response.code << response.data << response.message;
-                    if (response.code != 0) {
-                        BubbleTip::showTip(this, response.message, BubbleTip::Top, 3000);
-                        return;
-                    }
-                    RoomInfo roomInfo = JsonMapper::formJsonEx<RoomInfo>(response.data.toObject());
-
-                    qDebug() << "roomInfo.liveStatus.has_value()"
-                             << roomInfo.liveStatus.has_value();
-
-                    int status = roomInfo.liveStatus.value_or(0);
-                    if (status == 1) {
-                        qDebug() << "open" << ("rtmp://106.55.186.74:1935/stream/V1/" + id);
-                        playWidget->startToPlay("rtmp://106.55.186.74:1935/stream/V1/" + id);
-                    }
-                })
-                .finally([]() { MaskOverlay::instance()->hide(); });
-        }
-    }
-}
 
 void MainPanel::handleDebouncedPlay()
 {

+ 15 - 5
MainPanel.h

@@ -7,13 +7,18 @@
 #include <QTimer>
 
 class QSplitter;
-class QListWidget;
+
 class UserProfileWidget;
 class ChatWindow;
-class QListWidgetItem;
+
 class WebSocketClient;
 class StatsWidget;
 
+namespace ADS {
+    class DockManager;
+    class DockWidget;
+}
+
 class MainPanel : public QWidget
 {
     Q_OBJECT
@@ -24,14 +29,16 @@ public:
 
     void setPushRoomId(const QString &room);
 
-    QListWidget *roomListWidget() { return m_roomListWidget; }
+
 
 signals:
     void logoutClicked();
 
+public slots:
+
 private:
     void setPlayerWidget(QWidget *newPlayer);
-    void roomItemChanged(QListWidgetItem *item);
+
     void handleDebouncedPlay(); // 防抖处理函数
 
 private:
@@ -40,7 +47,7 @@ private:
     QWidget *playerWidget = nullptr;
     UserProfileWidget *userProfile = nullptr;
     ChatWindow *chatView = nullptr;
-    QListWidget *m_roomListWidget = nullptr;
+
     WebSocketClient *webSocketClient = nullptr;
     StatsWidget *statsWidget = nullptr;
     bool m_isStartingPlay = false;
@@ -48,4 +55,7 @@ private:
     QWaitCondition m_playCond;
     QTimer *m_debounceTimer = nullptr;
     QString m_pendingRoomId;
+    
+    // DockManager 相关
+    ADS::DockManager *m_dockManager = nullptr;
 };

+ 218 - 0
ScreenWall/CMakeLists.txt

@@ -0,0 +1,218 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(ScreenWall VERSION 1.0.0 LANGUAGES CXX)
+
+# 设置C++标准
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# 查找Qt6组件
+find_package(Qt6 REQUIRED COMPONENTS
+    Core
+    Widgets
+    OpenGL
+    OpenGLWidgets
+)
+
+# 自动处理Qt的MOC、UIC、RCC
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+# 包含目录
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder/ui
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder/capturer
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder/capturer/finder
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder/recorder
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AvRecorder/basic
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AV/code/recorder
+    ${CMAKE_CURRENT_SOURCE_DIR}/../AV/code/recorder/ui
+    ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/ffmpeg/include
+)
+
+# AvRecorder 源文件
+set(AVRECORDER_SOURCES
+    ../AvRecorder/ui/opengl_video_widget.cpp
+    ../AvRecorder/ui/audio_render.cpp
+    ../AvRecorder/ui/audio_widget.cpp
+    ../AvRecorder/ui/av_recorder.cpp
+    ../AvRecorder/ui/settings_page.cpp
+    ../AvRecorder/capturer/finder.cpp
+    ../AvRecorder/capturer/ivideocapturer.cpp
+    ../AvRecorder/recorder/video_recorder.cpp
+    ../AvRecorder/recorder/audio_recorder.cpp
+    ../AvRecorder/basic/basic.cpp
+    ../AvRecorder/basic/frame.cpp
+    ../AvRecorder/audioinput.cpp
+)
+
+# AvRecorder 头文件
+set(AVRECORDER_HEADERS
+    ../AvRecorder/ui/opengl_video_widget.h
+    ../AvRecorder/ui/audio_render.h
+    ../AvRecorder/ui/audio_widget.h
+    ../AvRecorder/ui/av_recorder.h
+    ../AvRecorder/ui/settings_page.h
+    ../AvRecorder/capturer/finder.h
+    ../AvRecorder/capturer/base_capturer.h
+    ../AvRecorder/recorder/video_recorder.h
+    ../AvRecorder/recorder/audio_recorder.h
+    ../AvRecorder/basic/basic.h
+    ../AvRecorder/basic/frame.h
+    ../AvRecorder/basic/timer.h
+    ../AvRecorder/audioinput.h
+)
+
+# 源文件
+set(SOURCES
+    main.cpp
+    screenwall_widget.cpp
+    ${AVRECORDER_SOURCES}
+)
+
+# 头文件
+set(HEADERS
+    screenwall_widget.h
+    ${AVRECORDER_HEADERS}
+)
+
+# Windows特定设置
+if(WIN32)
+    # 添加Windows API库
+    set(WIN32_LIBS
+        dwmapi
+        shell32
+        psapi
+        user32
+        gdi32
+        ole32
+        oleaut32
+    )
+endif()
+
+# 创建可执行文件
+add_executable(ScreenWall
+    ${SOURCES}
+    ${HEADERS}
+)
+
+# 链接Qt库
+target_link_libraries(ScreenWall
+    Qt6::Core
+    Qt6::Widgets
+    Qt6::OpenGL
+    Qt6::OpenGLWidgets
+)
+
+# 链接Windows库
+if(WIN32)
+    target_link_libraries(ScreenWall ${WIN32_LIBS})
+endif()
+
+# FFmpeg 库查找(AvRecorder 依赖)
+set(FFMPEG_LIBS)
+
+# 查找 FFmpeg 库
+find_library(FFMPEG_AVCODEC_LIB
+    NAMES avcodec
+    PATHS
+        ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/ffmpeg/lib
+        ${CMAKE_CURRENT_SOURCE_DIR}/../lib
+    NO_DEFAULT_PATH
+)
+
+find_library(FFMPEG_AVFORMAT_LIB
+    NAMES avformat
+    PATHS
+        ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/ffmpeg/lib
+        ${CMAKE_CURRENT_SOURCE_DIR}/../lib
+    NO_DEFAULT_PATH
+)
+
+find_library(FFMPEG_AVUTIL_LIB
+    NAMES avutil
+    PATHS
+        ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/ffmpeg/lib
+        ${CMAKE_CURRENT_SOURCE_DIR}/../lib
+    NO_DEFAULT_PATH
+)
+
+if(FFMPEG_AVCODEC_LIB AND FFMPEG_AVFORMAT_LIB AND FFMPEG_AVUTIL_LIB)
+    list(APPEND FFMPEG_LIBS 
+        ${FFMPEG_AVCODEC_LIB}
+        ${FFMPEG_AVFORMAT_LIB}
+        ${FFMPEG_AVUTIL_LIB}
+    )
+    message(STATUS "Found FFmpeg libraries")
+    target_link_libraries(ScreenWall ${FFMPEG_LIBS})
+else()
+    message(WARNING "FFmpeg libraries not found. Some features may not work.")
+endif()
+
+# 编译器特定设置
+if(MSVC)
+    # MSVC特定设置
+    target_compile_definitions(ScreenWall PRIVATE
+        _CRT_SECURE_NO_WARNINGS
+        NOMINMAX
+        WIN32_LEAN_AND_MEAN
+    )
+    
+    # 设置运行时库
+    set_property(TARGET ScreenWall PROPERTY
+        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
+endif()
+
+# 设置输出目录
+set_target_properties(ScreenWall PROPERTIES
+    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin
+    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin
+)
+
+# 安装规则
+install(TARGETS ScreenWall
+    RUNTIME DESTINATION bin
+)
+
+# 复制Qt DLL(Windows)
+if(WIN32)
+    # 获取Qt安装路径
+    get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)
+    get_filename_component(QT_WINDEPLOYQT_EXECUTABLE ${QT_QMAKE_EXECUTABLE} PATH)
+    set(QT_WINDEPLOYQT_EXECUTABLE "${QT_WINDEPLOYQT_EXECUTABLE}/windeployqt.exe")
+    
+    # 添加部署命令
+    if(EXISTS ${QT_WINDEPLOYQT_EXECUTABLE})
+        add_custom_command(TARGET ScreenWall POST_BUILD
+            COMMAND ${QT_WINDEPLOYQT_EXECUTABLE} $<TARGET_FILE:ScreenWall>
+            COMMENT "Deploying Qt libraries")
+    endif()
+endif()
+
+# 打印配置信息
+message(STATUS "ScreenWall Configuration:")
+message(STATUS "  Qt6 Version: ${Qt6_VERSION}")
+message(STATUS "  Build Type: ${CMAKE_BUILD_TYPE}")
+message(STATUS "  C++ Standard: ${CMAKE_CXX_STANDARD}")
+message(STATUS "  Install Prefix: ${CMAKE_INSTALL_PREFIX}")
+
+# 添加编译选项
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+    target_compile_definitions(ScreenWall PRIVATE DEBUG_BUILD)
+    message(STATUS "  Debug build enabled")
+else()
+    target_compile_definitions(ScreenWall PRIVATE RELEASE_BUILD)
+    message(STATUS "  Release build enabled")
+endif()
+
+# 添加版本信息
+target_compile_definitions(ScreenWall PRIVATE
+    SCREENWALL_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
+    SCREENWALL_VERSION_MINOR=${PROJECT_VERSION_MINOR}
+    SCREENWALL_VERSION_PATCH=${PROJECT_VERSION_PATCH}
+    SCREENWALL_VERSION_STRING="${PROJECT_VERSION}"
+)

+ 201 - 0
ScreenWall/CMakeLists_simple.txt

@@ -0,0 +1,201 @@
+cmake_minimum_required(VERSION 3.16)
+
+# 项目信息
+project(SimpleScreenWall VERSION 1.0.0 LANGUAGES CXX)
+
+# 设置C++标准
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# 设置构建类型
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE Release)
+endif()
+
+# 查找Qt6组件
+find_package(Qt6 REQUIRED COMPONENTS
+    Core
+    Widgets
+    Gui
+)
+
+# 启用Qt的MOC、UIC、RCC
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+# 源文件
+set(SOURCES
+    main_simple.cpp
+    screenwall_simple.cpp
+)
+
+# 头文件
+set(HEADERS
+    screenwall_simple.h
+)
+
+# 创建可执行文件
+add_executable(SimpleScreenWall
+    ${SOURCES}
+    ${HEADERS}
+)
+
+# 链接Qt库
+target_link_libraries(SimpleScreenWall
+    Qt6::Core
+    Qt6::Widgets
+    Qt6::Gui
+)
+
+# Windows特定设置
+if(WIN32)
+    # 链接Windows API库
+    target_link_libraries(SimpleScreenWall
+        user32
+        gdi32
+        shell32
+        psapi
+        dwmapi
+        ole32
+        oleaut32
+    )
+    
+    # 设置Windows子系统
+    set_target_properties(SimpleScreenWall PROPERTIES
+        WIN32_EXECUTABLE TRUE
+    )
+    
+    # MSVC特定设置
+    if(MSVC)
+        # 设置编译选项
+        target_compile_options(SimpleScreenWall PRIVATE
+            /W3          # 警告级别3
+            /MP          # 多处理器编译
+            /utf-8       # UTF-8编码
+        )
+        
+        # 设置链接选项
+        target_link_options(SimpleScreenWall PRIVATE
+            /SUBSYSTEM:WINDOWS
+        )
+        
+        # 设置运行时库
+        set_property(TARGET SimpleScreenWall PROPERTY
+            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"
+        )
+    endif()
+endif()
+
+# 设置输出目录
+set_target_properties(SimpleScreenWall PROPERTIES
+    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+    RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin"
+    RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin"
+)
+
+# 编译定义
+target_compile_definitions(SimpleScreenWall PRIVATE
+    QT_DEPRECATED_WARNINGS
+    QT_DISABLE_DEPRECATED_BEFORE=0x060000
+    UNICODE
+    _UNICODE
+    WIN32_LEAN_AND_MEAN
+    NOMINMAX
+)
+
+# 包含目录
+target_include_directories(SimpleScreenWall PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# 安装规则
+install(TARGETS SimpleScreenWall
+    RUNTIME DESTINATION bin
+)
+
+# Windows部署
+if(WIN32)
+    # 查找windeployqt
+    find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS ${Qt6_DIR}/../../../bin)
+    
+    if(WINDEPLOYQT_EXECUTABLE)
+        # 添加部署命令
+        add_custom_command(TARGET SimpleScreenWall POST_BUILD
+            COMMAND ${WINDEPLOYQT_EXECUTABLE} $<TARGET_FILE:SimpleScreenWall>
+            COMMENT "Deploying Qt libraries"
+        )
+        
+        message(STATUS "Found windeployqt: ${WINDEPLOYQT_EXECUTABLE}")
+    else()
+        message(WARNING "windeployqt not found. Manual deployment may be required.")
+    endif()
+endif()
+
+# 打印构建信息
+message(STATUS "")
+message(STATUS "========== SimpleScreenWall Build Configuration ==========")
+message(STATUS "Project: ${PROJECT_NAME} v${PROJECT_VERSION}")
+message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}")
+message(STATUS "Qt version: ${Qt6_VERSION}")
+message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
+message(STATUS "Platform: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
+message(STATUS "Architecture: ${CMAKE_SYSTEM_PROCESSOR}")
+message(STATUS "Source directory: ${CMAKE_CURRENT_SOURCE_DIR}")
+message(STATUS "Binary directory: ${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
+message(STATUS "=========================================================")
+message(STATUS "")
+
+# 构建后信息
+add_custom_target(build_info ALL
+    COMMAND ${CMAKE_COMMAND} -E echo "SimpleScreenWall build completed successfully!"
+    COMMAND ${CMAKE_COMMAND} -E echo "Executable: $<TARGET_FILE:SimpleScreenWall>"
+    DEPENDS SimpleScreenWall
+)
+
+# 清理规则
+set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
+    "${CMAKE_BINARY_DIR}/bin"
+)
+
+# CPack配置(可选)
+if(WIN32)
+    set(CPACK_GENERATOR "NSIS;ZIP")
+    set(CPACK_PACKAGE_NAME "SimpleScreenWall")
+    set(CPACK_PACKAGE_VENDOR "SimpleScreenWall Team")
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "轻量级实时窗口预览系统")
+    set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
+    set(CPACK_PACKAGE_INSTALL_DIRECTORY "SimpleScreenWall")
+    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+    
+    # NSIS特定设置
+    set(CPACK_NSIS_DISPLAY_NAME "SimpleScreenWall")
+    set(CPACK_NSIS_PACKAGE_NAME "SimpleScreenWall")
+    set(CPACK_NSIS_CONTACT "support@simplescreenwall.com")
+    set(CPACK_NSIS_HELP_LINK "https://github.com/simplescreenwall/simplescreenwall")
+    
+    include(CPack)
+endif()
+
+# 开发者选项
+option(BUILD_TESTS "Build unit tests" OFF)
+option(ENABLE_DEBUG_OUTPUT "Enable debug output" OFF)
+
+if(ENABLE_DEBUG_OUTPUT)
+    target_compile_definitions(SimpleScreenWall PRIVATE DEBUG_OUTPUT)
+endif()
+
+if(BUILD_TESTS)
+    enable_testing()
+    # 这里可以添加测试相关的配置
+    message(STATUS "Unit tests enabled")
+endif()
+
+# 性能分析选项
+option(ENABLE_PROFILING "Enable profiling" OFF)
+if(ENABLE_PROFILING AND MSVC)
+    target_compile_options(SimpleScreenWall PRIVATE /PROFILE)
+    target_link_options(SimpleScreenWall PRIVATE /PROFILE)
+endif()

+ 269 - 0
ScreenWall/README.md

@@ -0,0 +1,269 @@
+# 屏幕墙 (ScreenWall) - 实时窗口预览系统
+
+## 项目概述
+
+屏幕墙是一个基于Qt和AvRecorder开发的实时窗口预览系统,提供了完整的桌面和窗口内容捕获与显示功能。
+
+## 功能特性
+
+### 🖥️ 核心功能
+- **实时桌面预览**: 在顶部区域显示完整的桌面内容
+- **窗口图标列表**: 中间区域展示所有活动窗口的图标和缩略图
+- **实时窗口预览**: 底部区域显示选中窗口的实时内容
+- **最小化窗口支持**: 即使窗口最小化也能预览最后的画面
+
+### ⚡ 性能优化
+- **智能帧率控制**: 根据窗口状态自动调整捕获帧率
+- **资源管理**: 限制同时捕获的窗口数量,避免系统过载
+- **缓存机制**: 缓存窗口缩略图和图标,提升响应速度
+- **多线程处理**: 异步捕获和渲染,保证UI流畅性
+
+### 🎨 用户界面
+- **响应式布局**: 自适应窗口大小变化
+- **现代化设计**: 使用Fusion样式和自定义CSS
+- **状态指示**: 实时显示捕获状态和窗口信息
+- **交互友好**: 支持鼠标点击选择和双击操作
+
+## 技术架构
+
+### 核心组件
+
+```
+ScreenWallWidget (主组件)
+├── DesktopPreviewWidget (桌面预览)
+├── WindowIconListWidget (窗口列表)
+└── WindowPreviewWidget (窗口预览)
+
+EnhancedWindowFinder (窗口查找)
+└── 扩展WindowFinder,支持图标和缩略图
+
+ResourceManager (资源管理)
+└── 管理捕获会话和缓存
+```
+
+### 技术栈
+- **UI框架**: Qt6 (Widgets + OpenGL)
+- **视频捕获**: AvRecorder (支持WGC/DXGI/GDI)
+- **图形渲染**: OpenGL + 自定义着色器
+- **系统API**: Windows API (DWM, Shell, PSAPI)
+
+## 编译和运行
+
+### 环境要求
+- Windows 10/11 (支持Windows Graphics Capture)
+- Qt 6.0+
+- CMake 3.16+
+- Visual Studio 2019+ 或 MinGW
+- AvRecorder库 (项目依赖)
+
+### 编译步骤
+
+1. **克隆项目**
+```bash
+cd LearningSmartClient
+```
+
+2. **创建构建目录**
+```bash
+mkdir build
+cd build
+```
+
+3. **配置CMake**
+```bash
+cmake ../ScreenWall -G "Visual Studio 16 2019" -A x64
+# 或使用Ninja
+cmake ../ScreenWall -G Ninja
+```
+
+4. **编译项目**
+```bash
+cmake --build . --config Release
+```
+
+5. **运行程序**
+```bash
+./bin/ScreenWall.exe
+```
+
+### 依赖库配置
+
+确保以下库文件可用:
+- `AvRecorder.lib` - 视频录制库
+- `avcodec.lib`, `avformat.lib`, `avutil.lib` - FFmpeg库
+- Qt6相关DLL文件
+
+## 使用说明
+
+### 基本操作
+
+1. **启动应用**: 运行ScreenWall.exe
+2. **开始预览**: 点击"启动"按钮开始屏幕墙功能
+3. **选择窗口**: 在中间区域点击窗口图标进行预览
+4. **桌面预览**: 点击顶部桌面预览区域
+5. **停止预览**: 点击"停止"按钮结束功能
+
+### 高级功能
+
+- **刷新窗口列表**: 使用"刷新"按钮或F5键
+- **窗口双击**: 双击窗口图标可以激活对应窗口
+- **状态监控**: 查看状态栏了解当前运行状态
+
+## 配置选项
+
+### ScreenWallConfig 结构
+
+```cpp
+struct ScreenWallConfig {
+    int desktopFrameRate = 15;      // 桌面捕获帧率
+    int windowFrameRate = 30;       // 窗口捕获帧率
+    int updateInterval = 2000;      // 窗口列表更新间隔(ms)
+    QSize thumbnailSize = {120, 90}; // 缩略图尺寸
+    int maxConcurrentCaptures = 3;   // 最大同时捕获数
+};
+```
+
+### 性能调优建议
+
+- **降低帧率**: 对于性能较低的设备,可以降低捕获帧率
+- **减少同时捕获**: 限制同时预览的窗口数量
+- **调整缩略图尺寸**: 较小的缩略图可以提升性能
+- **关闭不必要的效果**: 在低端设备上禁用视觉效果
+
+## API 参考
+
+### ScreenWallWidget 主要接口
+
+```cpp
+class ScreenWallWidget : public QWidget {
+public:
+    // 配置和控制
+    void setConfig(const ScreenWallConfig& config);
+    void startScreenWall();
+    void stopScreenWall();
+    void refreshWindowList();
+    
+    // 信号
+    void windowSelected(HWND hwnd, const QString& title);
+    void desktopSelected();
+};
+```
+
+### EnhancedWindowFinder 扩展接口
+
+```cpp
+class EnhancedWindowFinder {
+public:
+    struct ExtendedInfo {
+        HWND hwnd;
+        QString title;
+        QIcon icon;
+        QPixmap thumbnail;
+        bool isMinimized;
+        bool isVisible;
+        // ... 更多属性
+    };
+    
+    static QVector<ExtendedInfo> GetExtendedList(bool includeMinimized = true);
+    static QIcon GetWindowIcon(HWND hwnd);
+    static QPixmap GetWindowThumbnail(HWND hwnd, const QSize& size = QSize());
+};
+```
+
+## 故障排除
+
+### 常见问题
+
+1. **编译错误**
+   - 检查Qt6是否正确安装
+   - 确认AvRecorder库路径正确
+   - 验证CMake版本兼容性
+
+2. **运行时错误**
+   - 确保所有DLL文件在PATH中
+   - 检查Windows版本是否支持WGC
+   - 验证管理员权限(某些窗口需要)
+
+3. **性能问题**
+   - 降低捕获帧率
+   - 减少同时捕获的窗口数
+   - 关闭其他占用GPU的应用
+
+4. **显示问题**
+   - 更新显卡驱动
+   - 检查OpenGL支持
+   - 尝试不同的捕获方法
+
+### 调试模式
+
+在Debug模式下,程序会输出详细的调试信息:
+
+```cpp
+// 启用调试输出
+QLoggingCategory::setFilterRules("*.debug=true");
+```
+
+## 扩展开发
+
+### 添加新的捕获方法
+
+1. 继承`IVideoCapturer`接口
+2. 实现具体的捕获逻辑
+3. 在`VideoRecorder`中注册新方法
+
+### 自定义UI组件
+
+1. 继承相应的基类
+2. 重写绘制和事件处理方法
+3. 集成到主界面布局中
+
+### 性能监控
+
+```cpp
+// 添加性能计数器
+class PerformanceMonitor {
+public:
+    void recordFrameTime(qint64 time);
+    double getAverageFrameRate() const;
+    void logPerformanceStats();
+};
+```
+
+## 许可证
+
+本项目基于现有的LearningSmartClient项目开发,遵循相同的许可证条款。
+
+## 贡献指南
+
+1. Fork项目仓库
+2. 创建功能分支
+3. 提交代码更改
+4. 创建Pull Request
+
+## 更新日志
+
+### v1.0.0 (当前版本)
+- ✅ 实现基本的屏幕墙功能
+- ✅ 支持实时桌面和窗口预览
+- ✅ 添加窗口图标列表
+- ✅ 实现最小化窗口支持
+- ✅ 性能优化和资源管理
+- ✅ 现代化UI设计
+
+### 计划功能
+- 🔄 多显示器支持
+- 🔄 窗口搜索和过滤
+- 🔄 预览录制功能
+- 🔄 自定义布局
+- 🔄 插件系统
+
+## 联系方式
+
+如有问题或建议,请通过以下方式联系:
+- 项目Issues
+- 开发团队邮箱
+- 技术支持论坛
+
+---
+
+**注意**: 本项目仅用于学习和研究目的,请遵守相关法律法规和隐私政策。

+ 258 - 0
ScreenWall/README_simple.md

@@ -0,0 +1,258 @@
+# 简化版屏幕墙 (SimpleScreenWall)
+
+一个基于Qt开发的轻量级实时窗口预览系统,不依赖任何第三方录制库,直接使用Windows API实现窗口捕获和预览功能。
+
+## 🚀 项目特色
+
+### ✨ 核心功能
+- **实时桌面预览** - 显示当前桌面的实时画面
+- **窗口图标列表** - 展示所有活动窗口的图标和标题
+- **实时窗口预览** - 选中窗口后显示其实时内容
+- **最小化窗口支持** - 即使窗口最小化也能预览最后画面
+- **智能缓存机制** - 优化性能,减少资源占用
+
+### 🎯 技术优势
+- **零依赖** - 不需要AvRecorder、FFmpeg等第三方库
+- **轻量级** - 直接使用Windows API,占用资源少
+- **高性能** - 多线程架构,智能缓存优化
+- **易部署** - 独立可执行文件,无需复杂配置
+- **可配置** - 丰富的参数设置,适应不同需求
+
+## 📋 系统要求
+
+- **操作系统**: Windows 10/11 (x64)
+- **Qt版本**: Qt 6.2 或更高版本
+- **编译器**: MSVC 2019/2022 或 MinGW
+- **内存**: 建议 4GB 以上
+- **显卡**: 支持基本图形加速
+
+## 🛠️ 编译构建
+
+### 方法一:使用CMake (推荐)
+
+```bash
+# 1. 克隆或下载项目文件
+# 确保以下文件在同一目录:
+# - screenwall_simple.h
+# - screenwall_simple.cpp  
+# - main_simple.cpp
+# - CMakeLists_simple.txt
+
+# 2. 创建构建目录
+mkdir build
+cd build
+
+# 3. 配置项目
+cmake .. -G "Visual Studio 17 2022" -A x64
+# 或者使用 MinGW:
+# cmake .. -G "MinGW Makefiles"
+
+# 4. 编译项目
+cmake --build . --config Release
+
+# 5. 运行程序
+.\bin\SimpleScreenWall.exe
+```
+
+### 方法二:使用Qt Creator
+
+1. 打开Qt Creator
+2. 选择 "Open Project"
+3. 选择 `CMakeLists_simple.txt` 文件
+4. 配置Kit(选择合适的Qt版本和编译器)
+5. 点击 "Build" 按钮编译
+6. 点击 "Run" 按钮运行
+
+### 方法三:手动编译
+
+```bash
+# 使用qmake(需要先创建.pro文件)
+qmake -project
+qmake
+make  # 或 nmake (Windows)
+```
+
+## 🎮 使用说明
+
+### 启动程序
+1. 运行 `SimpleScreenWall.exe`
+2. 点击 "▶️ 启动" 按钮开始屏幕墙服务
+3. 程序将自动开始捕获桌面和窗口内容
+
+### 界面布局
+```
+┌─────────────────────────────────────────┐
+│  🖥️ 简化版屏幕墙控制面板                    │
+│  [▶️ 启动] [⏹️ 停止] [🔄 刷新] [⚙️ 设置]     │
+├─────────────────────────────────────────┤
+│           桌面实时预览区域                  │
+│        (点击可切换到桌面预览)               │
+├─────────────────────────────────────────┤
+│  [图标1] [图标2] [图标3] [图标4] ...       │
+│     窗口图标列表 (可滚动)                  │
+├─────────────────────────────────────────┤
+│         选中窗口的实时预览                  │
+│      (显示窗口的实时内容)                  │
+└─────────────────────────────────────────┘
+```
+
+### 操作指南
+- **选择窗口**: 点击中间区域的窗口图标
+- **桌面预览**: 点击上方的桌面预览区域
+- **刷新列表**: 点击 "🔄 刷新" 按钮更新窗口列表
+- **调整设置**: 点击 "⚙️ 设置" 打开配置对话框
+- **查看日志**: 使用菜单 "视图" -> "显示/隐藏日志" (Ctrl+L)
+
+## ⚙️ 配置选项
+
+### 性能设置
+- **桌面更新间隔**: 100-5000ms (默认: 500ms)
+- **窗口列表更新间隔**: 500-10000ms (默认: 2000ms)
+- **窗口预览更新间隔**: 100-2000ms (默认: 200ms)
+- **最大缓存数量**: 10-200个 (默认: 50个)
+
+### 显示设置
+- **缩略图尺寸**: 80x60 到 300x225 像素
+- **桌面预览尺寸**: 200x150 到 800x600 像素
+
+### 功能开关
+- **启用桌面预览**: 开启/关闭桌面实时捕获
+- **启用窗口预览**: 开启/关闭窗口实时捕获
+- **显示最小化窗口**: 是否在列表中显示最小化的窗口
+
+## 🔧 高级功能
+
+### 快捷键
+- `F5` / `Ctrl+R`: 刷新窗口列表
+- `Ctrl+L`: 显示/隐藏日志面板
+- `Ctrl+Shift+L`: 清空日志
+- `Ctrl+,`: 打开设置对话框
+- `Ctrl+Q`: 退出程序
+
+### 菜单功能
+- **文件菜单**: 退出程序
+- **视图菜单**: 刷新、日志控制
+- **工具菜单**: 设置、系统信息
+- **帮助菜单**: 关于信息、Qt信息
+
+### 配置文件
+程序会自动保存配置到 `config.json` 文件,包含所有用户设置。
+
+## 🐛 故障排除
+
+### 常见问题
+
+**Q: 程序启动后看不到任何窗口预览?**
+A: 检查以下几点:
+- 确保有管理员权限(某些系统窗口需要)
+- 检查防火墙/杀毒软件是否阻止
+- 尝试重启程序或刷新窗口列表
+
+**Q: 预览画面卡顿或延迟严重?**
+A: 调整性能设置:
+- 增加更新间隔时间
+- 减少缓存数量
+- 降低预览尺寸
+
+**Q: 某些窗口无法预览?**
+A: 这是正常现象,以下窗口可能无法捕获:
+- 受保护的系统窗口
+- 使用硬件加速的全屏应用
+- 某些安全软件窗口
+
+**Q: 内存占用过高?**
+A: 优化建议:
+- 减少最大缓存数量
+- 增加更新间隔
+- 关闭不需要的预览功能
+
+### 性能优化建议
+
+1. **硬件配置**
+   - 使用SSD硬盘提升响应速度
+   - 确保足够的内存空间
+   - 关闭不必要的后台程序
+
+2. **软件设置**
+   - 根据实际需求调整更新频率
+   - 合理设置缓存大小
+   - 定期清理日志文件
+
+3. **系统优化**
+   - 关闭Windows视觉效果
+   - 设置高性能电源模式
+   - 更新显卡驱动程序
+
+## 📊 技术架构
+
+### 核心组件
+```
+SimpleScreenWall (主组件)
+├── SimpleDesktopPreview (桌面预览)
+├── SimpleWindowList (窗口列表)
+├── SimpleWindowPreview (窗口预览)
+├── SimpleWindowFinder (窗口查找)
+├── SimpleCacheManager (缓存管理)
+└── SimpleScreenWallUtils (工具函数)
+```
+
+### 技术栈
+- **UI框架**: Qt6 Widgets
+- **图像处理**: Qt6 Gui (QPixmap, QPainter)
+- **系统API**: Windows API (User32, GDI32, DWM)
+- **多线程**: Qt6 Concurrent
+- **配置管理**: JSON格式
+
+### 关键API
+- `EnumWindows`: 枚举所有窗口
+- `PrintWindow`: 捕获窗口内容
+- `BitBlt`: 复制屏幕内容
+- `GetWindowText`: 获取窗口标题
+- `GetWindowIcon`: 获取窗口图标
+
+## 🔄 版本历史
+
+### v1.0.0 (当前版本)
+- ✅ 实现基本的屏幕墙功能
+- ✅ 支持实时桌面和窗口预览
+- ✅ 添加配置管理和缓存优化
+- ✅ 完善的用户界面和交互
+- ✅ 详细的日志和错误处理
+
+### 计划功能 (未来版本)
+- 🔄 多显示器支持
+- 🔄 窗口搜索和过滤
+- 🔄 预览录制功能
+- 🔄 主题和皮肤系统
+- 🔄 插件扩展机制
+
+## 🤝 贡献指南
+
+欢迎提交问题报告、功能建议或代码贡献!
+
+### 开发环境设置
+1. 安装Qt 6.2+和合适的编译器
+2. 克隆项目代码
+3. 使用Qt Creator或CMake构建
+4. 运行测试确保功能正常
+
+### 代码规范
+- 使用C++17标准
+- 遵循Qt编码规范
+- 添加适当的注释和文档
+- 确保跨平台兼容性(主要支持Windows)
+
+## 📄 许可证
+
+本项目采用 MIT 许可证,详见 [LICENSE](LICENSE) 文件。
+
+## 📞 联系方式
+
+- **项目主页**: [GitHub Repository]
+- **问题反馈**: [GitHub Issues]
+- **邮箱支持**: support@simplescreenwall.com
+- **QQ群**: 123456789
+
+---
+
+**简化版屏幕墙** - 让窗口预览变得简单高效! 🚀

+ 273 - 0
ScreenWall/main111.cpp

@@ -0,0 +1,273 @@
+#include <QApplication>
+#include <QMainWindow>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+#include <QStatusBar>
+#include <QMenuBar>
+#include <QAction>
+#include <QMessageBox>
+#include <QTimer>
+#include <QDebug>
+#include "screenwall_widget.h"
+
+class ScreenWallMainWindow : public QMainWindow
+{
+
+public:
+    explicit ScreenWallMainWindow(QWidget *parent = nullptr)
+        : QMainWindow(parent)
+        , m_screenWall(nullptr)
+        , m_startButton(nullptr)
+        , m_stopButton(nullptr)
+        , m_refreshButton(nullptr)
+        , m_statusLabel(nullptr)
+    {
+        setupUI();
+        setupConnections();
+        setupMenus();
+        
+        setWindowTitle("屏幕墙 - 实时窗口预览系统");
+        setMinimumSize(1000, 700);
+        resize(1400, 1000);
+    }
+
+private slots:
+    void startScreenWall()
+    {
+        if (m_screenWall) {
+            m_screenWall->startScreenWall();
+            m_startButton->setEnabled(false);
+            m_stopButton->setEnabled(true);
+            m_refreshButton->setEnabled(true);
+            m_statusLabel->setText("状态: 运行中");
+            statusBar()->showMessage("屏幕墙已启动", 3000);
+        }
+    }
+    
+    void stopScreenWall()
+    {
+        if (m_screenWall) {
+            m_screenWall->stopScreenWall();
+            m_startButton->setEnabled(true);
+            m_stopButton->setEnabled(false);
+            m_refreshButton->setEnabled(false);
+            m_statusLabel->setText("状态: 已停止");
+            statusBar()->showMessage("屏幕墙已停止", 3000);
+        }
+    }
+    
+    void refreshWindows()
+    {
+        if (m_screenWall) {
+            m_screenWall->refreshWindowList();
+            statusBar()->showMessage("窗口列表已刷新", 2000);
+        }
+    }
+    
+    void onWindowSelected(HWND hwnd, const QString& title)
+    {
+        statusBar()->showMessage(QString("已选择窗口: %1").arg(title), 5000);
+        qDebug() << "Window selected:" << title << "HWND:" << hwnd;
+    }
+    
+    void onDesktopSelected()
+    {
+        statusBar()->showMessage("已选择桌面预览", 3000);
+        qDebug() << "Desktop selected";
+    }
+    
+    void showAbout()
+    {
+        QMessageBox::about(this, "关于屏幕墙",
+            "<h3>屏幕墙 v1.0</h3>"
+            "<p>实时窗口预览系统</p>"
+            "<p><b>功能特性:</b></p>"
+            "<ul>"
+            "<li>实时桌面预览</li>"
+            "<li>窗口图标列表</li>"
+            "<li>实时窗口内容预览</li>"
+            "<li>最小化窗口支持</li>"
+            "<li>性能优化</li>"
+            "</ul>"
+            "<p>基于 Qt + AvRecorder 开发</p>"
+        );
+    }
+    
+    void showSettings()
+    {
+        // 这里可以添加设置对话框
+        QMessageBox::information(this, "设置", "设置功能开发中...");
+    }
+
+private:
+    void setupUI()
+    {
+        // 创建中央部件
+        auto* centralWidget = new QWidget;
+        setCentralWidget(centralWidget);
+        
+        auto* mainLayout = new QVBoxLayout(centralWidget);
+        mainLayout->setContentsMargins(5, 5, 5, 5);
+        mainLayout->setSpacing(5);
+        
+        // 控制面板
+        auto* controlPanel = createControlPanel();
+        mainLayout->addWidget(controlPanel);
+        
+        // 屏幕墙组件
+        m_screenWall = new ScreenWallWidget;
+        mainLayout->addWidget(m_screenWall, 1);
+        
+        // 状态栏
+        m_statusLabel = new QLabel("状态: 已停止");
+        statusBar()->addWidget(m_statusLabel);
+        statusBar()->showMessage("就绪");
+    }
+    
+    QWidget* createControlPanel()
+    {
+        auto* panel = new QWidget;
+        panel->setMaximumHeight(60);
+        panel->setStyleSheet(
+            "QWidget { "
+            "  background-color: #34495e; "
+            "  border-radius: 5px; "
+            "}"
+            "QPushButton { "
+            "  background-color: #3498db; "
+            "  color: white; "
+            "  border: none; "
+            "  padding: 8px 16px; "
+            "  border-radius: 4px; "
+            "  font-weight: bold; "
+            "}"
+            "QPushButton:hover { "
+            "  background-color: #2980b9; "
+            "}"
+            "QPushButton:pressed { "
+            "  background-color: #21618c; "
+            "}"
+            "QPushButton:disabled { "
+            "  background-color: #7f8c8d; "
+            "}"
+        );
+        
+        auto* layout = new QHBoxLayout(panel);
+        layout->setContentsMargins(10, 10, 10, 10);
+        layout->setSpacing(10);
+        
+        // 标题
+        auto* titleLabel = new QLabel("屏幕墙控制面板");
+        titleLabel->setStyleSheet("color: white; font-size: 14px; font-weight: bold;");
+        layout->addWidget(titleLabel);
+        
+        layout->addStretch();
+        
+        // 控制按钮
+        m_startButton = new QPushButton("启动");
+        m_startButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPlay));
+        layout->addWidget(m_startButton);
+        
+        m_stopButton = new QPushButton("停止");
+        m_stopButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaStop));
+        m_stopButton->setEnabled(false);
+        layout->addWidget(m_stopButton);
+        
+        m_refreshButton = new QPushButton("刷新");
+        m_refreshButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_BrowserReload));
+        m_refreshButton->setEnabled(false);
+        layout->addWidget(m_refreshButton);
+        
+        return panel;
+    }
+    
+    void setupConnections()
+    {
+        // 控制按钮
+        connect(m_startButton, &QPushButton::clicked, this, &ScreenWallMainWindow::startScreenWall);
+        connect(m_stopButton, &QPushButton::clicked, this, &ScreenWallMainWindow::stopScreenWall);
+        connect(m_refreshButton, &QPushButton::clicked, this, &ScreenWallMainWindow::refreshWindows);
+        
+        // 屏幕墙事件
+        connect(m_screenWall, &ScreenWallWidget::windowSelected,
+                this, &ScreenWallMainWindow::onWindowSelected);
+        connect(m_screenWall, &ScreenWallWidget::desktopSelected,
+                this, &ScreenWallMainWindow::onDesktopSelected);
+    }
+    
+    void setupMenus()
+    {
+        // 文件菜单
+        auto* fileMenu = menuBar()->addMenu("文件(&F)");
+        
+        auto* exitAction = new QAction("退出(&X)", this);
+        exitAction->setShortcut(QKeySequence::Quit);
+        exitAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCloseButton));
+        connect(exitAction, &QAction::triggered, this, &QWidget::close);
+        fileMenu->addAction(exitAction);
+        
+        // 视图菜单
+        auto* viewMenu = menuBar()->addMenu("视图(&V)");
+        
+        auto* refreshAction = new QAction("刷新窗口列表(&R)", this);
+        refreshAction->setShortcut(QKeySequence::Refresh);
+        refreshAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_BrowserReload));
+        connect(refreshAction, &QAction::triggered, this, &ScreenWallMainWindow::refreshWindows);
+        viewMenu->addAction(refreshAction);
+        
+        // 工具菜单
+        auto* toolsMenu = menuBar()->addMenu("工具(&T)");
+        
+        auto* settingsAction = new QAction("设置(&S)", this);
+        settingsAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_ComputerIcon));
+        connect(settingsAction, &QAction::triggered, this, &ScreenWallMainWindow::showSettings);
+        toolsMenu->addAction(settingsAction);
+        
+        // 帮助菜单
+        auto* helpMenu = menuBar()->addMenu("帮助(&H)");
+        
+        auto* aboutAction = new QAction("关于(&A)", this);
+        aboutAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation));
+        connect(aboutAction, &QAction::triggered, this, &ScreenWallMainWindow::showAbout);
+        helpMenu->addAction(aboutAction);
+    }
+
+protected:
+    void closeEvent(QCloseEvent* event) override
+    {
+        if (m_screenWall) {
+            m_screenWall->stopScreenWall();
+        }
+        QMainWindow::closeEvent(event);
+    }
+
+private:
+    ScreenWallWidget* m_screenWall;
+    QPushButton* m_startButton;
+    QPushButton* m_stopButton;
+    QPushButton* m_refreshButton;
+    QLabel* m_statusLabel;
+};
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+    
+    // 设置应用程序信息
+    app.setApplicationName("ScreenWall");
+    app.setApplicationVersion("1.0");
+    app.setOrganizationName("ScreenWall Team");
+    
+    // 设置应用程序样式
+    app.setStyle("Fusion");
+    
+    // 创建并显示主窗口
+    ScreenWallMainWindow window;
+    window.show();
+    
+    qDebug() << "ScreenWall application started";
+    
+    return app.exec();
+}

+ 185 - 0
ScreenWall/main_simple.cpp

@@ -0,0 +1,185 @@
+// #include <QApplication>
+// #include <QDebug>
+// #include <QOpenGLFunctions>
+// #include <QOpenGLTexture>
+// #include <QOpenGLWidget>
+// #include <QScreen>
+// #include <QTimer>
+// #include <QWindow>
+// #include <dwmapi.h>
+// #include <windows.h>
+
+// #pragma comment(lib, "dwmapi.lib")
+// #pragma comment(lib, "user32.lib")
+
+// class ThumbnailWidget : public QOpenGLWidget, protected QOpenGLFunctions
+// {
+//     Q_OBJECT
+// public:
+//     ThumbnailWidget(QWidget *parent = nullptr)
+//         : QOpenGLWidget(parent)
+//     {
+//         setFixedSize(800, 600); // 固定预览区域大小
+//         updateTimer = new QTimer(this);
+//         connect(updateTimer, &QTimer::timeout, this, &ThumbnailWidget::updateThumbnails);
+//         updateTimer->start(200); // 每200ms更新一次
+//     }
+
+//     ~ThumbnailWidget()
+//     {
+//         makeCurrent();
+//         for (auto texture : textures) {
+//             delete texture;
+//         }
+//         textures.clear();
+//         doneCurrent();
+//     }
+
+// protected:
+//     void initializeGL() override
+//     {
+//         initializeOpenGLFunctions();
+//         glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
+//     }
+
+//     void resizeGL(int w, int h) override { glViewport(0, 0, w, h); }
+
+//     void paintGL() override
+//     {
+//         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+//         glEnable(GL_TEXTURE_2D);
+//         glEnable(GL_BLEND);
+//         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+//         int cols = 4;                   // 每行4个缩略图
+//         int thumbSize = width() / cols; // 保持1:1比例
+//         int row = 0, col = 0;
+
+//         for (auto texture : textures) {
+//             if (!texture)
+//                 continue;
+
+//             texture->bind();
+//             glBegin(GL_QUADS);
+//             int x = col * thumbSize;
+//             int y = row * thumbSize;
+
+//             glTexCoord2f(0, 0);
+//             glVertex2f(x, y);
+//             glTexCoord2f(1, 0);
+//             glVertex2f(x + thumbSize, y);
+//             glTexCoord2f(1, 1);
+//             glVertex2f(x + thumbSize, y + thumbSize);
+//             glTexCoord2f(0, 1);
+//             glVertex2f(x, y + thumbSize);
+//             glEnd();
+
+//             if (++col >= cols) {
+//                 col = 0;
+//                 row++;
+//             }
+//         }
+//     }
+
+// private slots:
+//     void updateThumbnails()
+//     {
+//         // 清理旧纹理
+//         makeCurrent();
+//         for (auto texture : textures) {
+//             delete texture;
+//         }
+//         textures.clear();
+
+//         // 获取所有窗口
+//         EnumWindows(enumWindowsProc, reinterpret_cast<LPARAM>(this));
+
+//         // 添加桌面预览
+//         addDesktopThumbnail();
+
+//         update();
+//     }
+
+// private:
+//     QTimer *updateTimer;
+//     QVector<QOpenGLTexture *> textures;
+
+//     static BOOL CALLBACK enumWindowsProc(HWND hwnd, LPARAM lParam)
+//     {
+//         if (!IsWindowVisible(hwnd))
+//             return TRUE;
+
+//         ThumbnailWidget *widget = reinterpret_cast<ThumbnailWidget *>(lParam);
+//         widget->addWindowThumbnail(hwnd);
+//         return TRUE;
+//     }
+
+//     void addWindowThumbnail(HWND hwnd)
+//     {
+//         RECT rect;
+//         GetClientRect(hwnd, &rect);
+//         int width = rect.right - rect.left;
+//         int height = rect.bottom - rect.top;
+//         if (width == 0 || height == 0)
+//             return;
+
+//         // 创建临时纹理
+//         QImage image(width, height, QImage::Format_ARGB32);
+//         HDC hdcScreen = GetDC(NULL);
+//         HDC hdcMem = CreateCompatibleDC(hdcScreen);
+//         HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, width, height);
+//         SelectObject(hdcMem, hbm);
+
+//         // 打印窗口内容到内存DC
+//         PrintWindow(hwnd, hdcMem, PW_CLIENTONLY);
+
+//         // 从HBITMAP获取数据
+//         BITMAPINFO bmi = {0};
+//         bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+//         bmi.bmiHeader.biWidth = width;
+//         bmi.bmiHeader.biHeight = -height; // 从上到下
+//         bmi.bmiHeader.biPlanes = 1;
+//         bmi.bmiHeader.biBitCount = 32;
+//         bmi.bmiHeader.biCompression = BI_RGB;
+
+//         GetDIBits(hdcMem, hbm, 0, height, image.bits(), &bmi, DIB_RGB_COLORS);
+
+//         // 创建OpenGL纹理
+//         makeCurrent();
+//         QOpenGLTexture *texture = new QOpenGLTexture(image.mirrored());
+//         texture->setMinificationFilter(QOpenGLTexture::Linear);
+//         texture->setMagnificationFilter(QOpenGLTexture::Linear);
+//         textures.append(texture);
+
+//         // 清理资源
+//         DeleteObject(hbm);
+//         DeleteDC(hdcMem);
+//         ReleaseDC(NULL, hdcScreen);
+//     }
+
+//     void addDesktopThumbnail()
+//     {
+//         QScreen *screen = QApplication::primaryScreen();
+//         QPixmap desktopPix = screen->grabWindow(0);
+//         QImage image = desktopPix.toImage();
+
+//         makeCurrent();
+//         QOpenGLTexture *texture = new QOpenGLTexture(image);
+//         texture->setMinificationFilter(QOpenGLTexture::Linear);
+//         texture->setMagnificationFilter(QOpenGLTexture::Linear);
+//         textures.prepend(texture); // 桌面放在第一个
+//     }
+// };
+
+// int main(int argc, char *argv[])
+// {
+//     QApplication app(argc, argv);
+
+//     ThumbnailWidget widget;
+//     widget.setWindowTitle("Window Thumbnail Preview");
+//     widget.show();
+
+//     return app.exec();
+// }
+
+// #include "main_simple.moc"

+ 1654 - 0
ScreenWall/screenwall_simple.cpp

@@ -0,0 +1,1654 @@
+// #include "screenwall_simple.h"
+// #include <QApplication>
+// #include <QDesktopWidget>
+// #include <QScreen>
+// #include <QMouseEvent>
+// #include <QResizeEvent>
+// #include <QShowEvent>
+// #include <QHideEvent>
+// #include <QCloseEvent>
+// #include <QPainter>
+// #include <QDebug>
+// #include <QMessageBox>
+// #include <QToolTip>
+// #include <QStyle>
+// #include <QStyleOption>
+// #include <QFileInfo>
+// #include <QDir>
+// #include <QStandardPaths>
+// #include <QSettings>
+// #include <QJsonDocument>
+// #include <QJsonObject>
+// #include <QPushButton>
+// #include <QVBoxLayout>
+// #include <QHBoxLayout>
+// #include <QLabel>
+// #include <string>
+
+// // ============================================================================
+// // SimpleWindowFinder Implementation
+// // ============================================================================
+
+// struct EnumWindowsData {
+//     QVector<SimpleWindowInfo>* windows;
+//     bool includeMinimized;
+// };
+
+// BOOL CALLBACK SimpleWindowFinder::enumWindowsProc(HWND hwnd, LPARAM lParam)
+// {
+//     auto* data = reinterpret_cast<EnumWindowsData*>(lParam);
+
+//     if (!isValidWindow(hwnd)) {
+//         return TRUE;
+//     }
+
+//     bool isMinimized = IsIconic(hwnd);
+//     if (!data->includeMinimized && isMinimized) {
+//         return TRUE;
+//     }
+
+//     SimpleWindowInfo info;
+//     info.hwnd = hwnd;
+//     info.title = getWindowTitle(hwnd);
+//     info.processName = getProcessName(hwnd);
+//     info.isMinimized = isMinimized;
+//     info.isVisible = IsWindowVisible(hwnd);
+
+//     RECT rect;
+//     GetWindowRect(hwnd, &rect);
+//     info.geometry = QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+
+//     GetWindowThreadProcessId(hwnd, &info.processId);
+
+//     // 获取图标
+//     info.icon = SimpleCacheManager::instance().getCachedIcon(hwnd);
+//     if (info.icon.isNull()) {
+//         info.icon = getWindowIcon(hwnd);
+//         if (!info.icon.isNull()) {
+//             SimpleCacheManager::instance().cacheIcon(hwnd, info.icon);
+//         }
+//     }
+
+//     data->windows->append(info);
+//     return TRUE;
+// }
+
+// QVector<SimpleWindowInfo> SimpleWindowFinder::getWindowList(bool includeMinimized)
+// {
+//     QVector<SimpleWindowInfo> windows;
+//     EnumWindowsData data;
+//     data.windows = &windows;
+//     data.includeMinimized = includeMinimized;
+
+//     EnumWindows(enumWindowsProc, reinterpret_cast<LPARAM>(&data));
+
+//     return windows;
+// }
+
+// QPixmap SimpleWindowFinder::captureWindow(HWND hwnd, const QSize& size)
+// {
+//     if (!IsWindow(hwnd)) {
+//         return QPixmap();
+//     }
+
+//     // 检查缓存
+//     QPixmap cached = SimpleCacheManager::instance().getCachedThumbnail(hwnd);
+//     if (!cached.isNull() && (size.isEmpty() || cached.size() == size)) {
+//         return cached;
+//     }
+
+//     RECT rect;
+//     GetWindowRect(hwnd, &rect);
+//     int width = rect.right - rect.left;
+//     int height = rect.bottom - rect.top;
+
+//     if (width <= 0 || height <= 0) {
+//         return QPixmap();
+//     }
+
+//     QPixmap pixmap;
+
+//     // 简化的窗口捕获:直接使用屏幕截图方法
+//     pixmap = captureScreenshot(hwnd, rect);
+//     if (!pixmap.isNull()) {
+//         qDebug() << "Captured window:" << hwnd << "size:" << width << "x" << height;
+//     } else {
+//         qDebug() << "Failed to capture window:" << hwnd;
+//         // 如果截图失败,创建一个占位图像
+//         pixmap = QPixmap(width > 0 ? width : 200, height > 0 ? height : 150);
+//         pixmap.fill(QColor(64, 64, 64)); // 深灰色背景
+
+//         QPainter painter(&pixmap);
+//         painter.setPen(Qt::white);
+//         painter.drawText(pixmap.rect(), Qt::AlignCenter, "无法捕获窗口");
+//     }
+
+//     // 缩放到指定尺寸
+//     if (!pixmap.isNull()) {
+//         if (!size.isEmpty() && pixmap.size() != size) {
+//             pixmap = pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+//         }
+
+//         // 缓存结果
+//         SimpleCacheManager::instance().cacheThumbnail(hwnd, pixmap);
+//     }
+
+//     return pixmap;
+// }
+
+// // DWM缩略图捕获方法
+// QPixmap SimpleWindowFinder::captureDWMThumbnail(HWND hwnd, int width, int height)
+// {
+//     // 检查是否支持DWM
+//     BOOL dwmEnabled = FALSE;
+//     if (FAILED(DwmIsCompositionEnabled(&dwmEnabled)) || !dwmEnabled) {
+//         return QPixmap();
+//     }
+
+//     // 创建临时窗口用于DWM缩略图
+//     HWND tempWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_LAYERED,
+//                                      L"STATIC", L"TempThumbnail",
+//                                      WS_POPUP,
+//                                      -32000, -32000, width, height,
+//                                      NULL, NULL, GetModuleHandle(NULL), NULL);
+
+//     if (!tempWindow) {
+//         return QPixmap();
+//     }
+
+//     HTHUMBNAIL thumbnail = NULL;
+//     HRESULT hr = DwmRegisterThumbnail(tempWindow, hwnd, &thumbnail);
+
+//     QPixmap result;
+//     if (SUCCEEDED(hr) && thumbnail) {
+//         // 设置缩略图属性
+//         DWM_THUMBNAIL_PROPERTIES props = {0};
+//         props.dwFlags = DWM_TNP_RECTDESTINATION | DWM_TNP_RECTSOURCE | DWM_TNP_OPACITY | DWM_TNP_VISIBLE;
+//         props.rcDestination = {0, 0, width, height};
+
+//         // 获取源窗口大小
+//         RECT sourceRect;
+//         GetWindowRect(hwnd, &sourceRect);
+//         props.rcSource = {0, 0, sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top};
+//         props.opacity = 255;
+//         props.fVisible = TRUE;
+
+//         hr = DwmUpdateThumbnailProperties(thumbnail, &props);
+
+//         if (SUCCEEDED(hr)) {
+//             // 显示临时窗口并截图
+//             ShowWindow(tempWindow, SW_SHOW);
+//             UpdateWindow(tempWindow);
+
+//             // 等待一小段时间让缩略图渲染
+//             Sleep(50);
+
+//             // 截取临时窗口
+//             HDC hdcWindow = GetDC(tempWindow);
+//             HDC hdcMemDC = CreateCompatibleDC(hdcWindow);
+//             HBITMAP hbmScreen = CreateCompatibleBitmap(hdcWindow, width, height);
+//             HGDIOBJ oldBitmap = SelectObject(hdcMemDC, hbmScreen);
+
+//             BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
+
+//             result = convertBitmapToPixmap(hbmScreen, width, height);
+
+//             // 清理资源
+//             SelectObject(hdcMemDC, oldBitmap);
+//             DeleteObject(hbmScreen);
+//             DeleteDC(hdcMemDC);
+//             ReleaseDC(tempWindow, hdcWindow);
+//         }
+
+//         DwmUnregisterThumbnail(thumbnail);
+//     }
+
+//     DestroyWindow(tempWindow);
+//     return result;
+// }
+
+// // PrintWindow捕获方法
+// QPixmap SimpleWindowFinder::capturePrintWindow(HWND hwnd, int width, int height)
+// {
+//     HDC hdcWindow = GetDC(hwnd);
+//     HDC hdcMemDC = CreateCompatibleDC(hdcWindow);
+//     HBITMAP hbmScreen = CreateCompatibleBitmap(hdcWindow, width, height);
+//     HGDIOBJ oldBitmap = SelectObject(hdcMemDC, hbmScreen);
+
+//     QPixmap result;
+
+//     // 尝试不同的PrintWindow标志
+//     UINT flags[] = {
+//         PW_RENDERFULLCONTENT,
+//         PW_CLIENTONLY,
+//         0  // 默认标志
+//     };
+
+//     for (int i = 0; i < 3; i++) {
+//         if (PrintWindow(hwnd, hdcMemDC, flags[i])) {
+//             result = convertBitmapToPixmap(hbmScreen, width, height);
+//             if (!result.isNull()) {
+//                 break;
+//             }
+//         }
+//     }
+
+//     // 清理资源
+//     SelectObject(hdcMemDC, oldBitmap);
+//     DeleteObject(hbmScreen);
+//     DeleteDC(hdcMemDC);
+//     ReleaseDC(hwnd, hdcWindow);
+
+//     return result;
+// }
+
+// // 屏幕截图方法
+// QPixmap SimpleWindowFinder::captureScreenshot(HWND hwnd, const RECT& rect)
+// {
+//     int width = rect.right - rect.left;
+//     int height = rect.bottom - rect.top;
+
+//     HDC hdcScreen = GetDC(NULL);
+//     HDC hdcMemDC = CreateCompatibleDC(hdcScreen);
+//     HBITMAP hbmScreen = CreateCompatibleBitmap(hdcScreen, width, height);
+//     HGDIOBJ oldBitmap = SelectObject(hdcMemDC, hbmScreen);
+
+//     // 使用BitBlt从屏幕复制
+//     BOOL result = BitBlt(hdcMemDC, 0, 0, width, height, hdcScreen, rect.left, rect.top, SRCCOPY);
+
+//     QPixmap pixmap;
+//     if (result) {
+//         pixmap = convertBitmapToPixmap(hbmScreen, width, height);
+//     }
+
+//     // 清理资源
+//     SelectObject(hdcMemDC, oldBitmap);
+//     DeleteObject(hbmScreen);
+//     DeleteDC(hdcMemDC);
+//     ReleaseDC(NULL, hdcScreen);
+
+//     return pixmap;
+// }
+
+// // 位图转换为QPixmap的辅助方法
+// QPixmap SimpleWindowFinder::convertBitmapToPixmap(HBITMAP hBitmap, int width, int height)
+// {
+//     if (!hBitmap || width <= 0 || height <= 0) {
+//         return QPixmap();
+//     }
+
+//     // 手动转换HBITMAP到QPixmap (Qt5兼容)
+//     HDC hdc = CreateCompatibleDC(NULL);
+//     if (!hdc) {
+//         return QPixmap();
+//     }
+
+//     BITMAPINFO bmi = {0};
+//     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+//     bmi.bmiHeader.biWidth = width;
+//     bmi.bmiHeader.biHeight = -height; // 负值表示自上而下
+//     bmi.bmiHeader.biPlanes = 1;
+//     bmi.bmiHeader.biBitCount = 32;
+//     bmi.bmiHeader.biCompression = BI_RGB;
+
+//     // 分配内存
+//     int dataSize = width * height * 4;
+//     uchar* data = new uchar[dataSize];
+
+//     QPixmap pixmap;
+
+//     if (GetDIBits(hdc, hBitmap, 0, height, data, &bmi, DIB_RGB_COLORS)) {
+//         // 创建QImage并转换为QPixmap
+//         QImage image(data, width, height, QImage::Format_RGB32);
+//         pixmap = QPixmap::fromImage(image);
+//         qDebug() << "Successfully converted HBITMAP to QPixmap, size:" << width << "x" << height;
+//     } else {
+//         qDebug() << "Failed to get DIB bits from HBITMAP";
+//     }
+
+//     delete[] data;
+//     DeleteDC(hdc);
+
+//     return pixmap;
+// }
+
+// QPixmap SimpleWindowFinder::captureDesktop(const QSize& size)
+// {
+//     // 获取主屏幕
+//     QScreen* screen = QApplication::primaryScreen();
+//     if (!screen) {
+//         return QPixmap();
+//     }
+
+//     QPixmap pixmap = screen->grabWindow(0);
+
+//     if (!pixmap.isNull() && !size.isEmpty()) {
+//         pixmap = pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+//     }
+
+//     return pixmap;
+// }
+
+// QIcon SimpleWindowFinder::getWindowIcon(HWND hwnd)
+// {
+//     // 尝试多种方式获取图标
+//     HICON hIcon = nullptr;
+
+//     // 方法1: 发送消息获取大图标
+//     hIcon = reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));
+//     if (!hIcon) {
+//         // 方法2: 发送消息获取小图标
+//         hIcon = reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
+//     }
+//     if (!hIcon) {
+//         // 方法3: 从窗口类获取图标
+//         hIcon = reinterpret_cast<HICON>(GetClassLongPtr(hwnd, GCLP_HICON));
+//     }
+//     if (!hIcon) {
+//         // 方法4: 从窗口类获取小图标
+//         hIcon = reinterpret_cast<HICON>(GetClassLongPtr(hwnd, GCLP_HICONSM));
+//     }
+
+//     if (hIcon) {
+//         // Qt5兼容的HICON转换
+//         QPixmap pixmap;
+//         ICONINFO iconInfo;
+//         if (GetIconInfo(hIcon, &iconInfo)) {
+//             // 获取位图信息
+//             BITMAP bmp;
+//             if (GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmp)) {
+//                 // 创建设备上下文
+//                 HDC hdc = CreateCompatibleDC(NULL);
+//                 if (hdc) {
+//                     // 准备位图信息头
+//                     BITMAPINFOHEADER bih = {0};
+//                     bih.biSize = sizeof(BITMAPINFOHEADER);
+//                     bih.biWidth = bmp.bmWidth;
+//                     bih.biHeight = -bmp.bmHeight;
+//                     bih.biPlanes = 1;
+//                     bih.biBitCount = 32;
+//                     bih.biCompression = BI_RGB;
+
+//                     // 分配内存
+//                     int dataSize = bmp.bmWidth * bmp.bmHeight * 4;
+//                     uchar* data = new uchar[dataSize];
+
+//                     // 获取位图数据
+//                     BITMAPINFO bi = {0};
+//                     bi.bmiHeader = bih;
+
+//                     if (GetDIBits(hdc, iconInfo.hbmColor, 0, bmp.bmHeight, data, &bi, DIB_RGB_COLORS)) {
+//                         // 创建QImage
+//                         QImage image(data, bmp.bmWidth, bmp.bmHeight, QImage::Format_ARGB32);
+//                         pixmap = QPixmap::fromImage(image.rgbSwapped());
+//                     }
+
+//                     delete[] data;
+//                     DeleteDC(hdc);
+//                 }
+//             }
+
+//             // 清理资源
+//             if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
+//             if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
+//         }
+
+//         if (!pixmap.isNull()) {
+//             return QIcon(pixmap);
+//         }
+//     }
+
+//     // 使用默认图标
+//     return QApplication::style()->standardIcon(QStyle::SP_ComputerIcon);
+// }
+
+// QString SimpleWindowFinder::getWindowTitle(HWND hwnd)
+// {
+//     wchar_t title[256];
+//     int length = GetWindowTextW(hwnd, title, 256);
+//     if (length > 0) {
+//         return QString::fromWCharArray(title, length);
+//     }
+//     return QString();
+// }
+
+// QString SimpleWindowFinder::getProcessName(HWND hwnd)
+// {
+//     DWORD processId;
+//     GetWindowThreadProcessId(hwnd, &processId);
+
+//     HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
+//     if (!hProcess) {
+//         return QString();
+//     }
+
+//     wchar_t processName[MAX_PATH];
+//     DWORD size = MAX_PATH;
+//     if (QueryFullProcessImageNameW(hProcess, 0, processName, &size)) {
+//         CloseHandle(hProcess);
+//         QString fullPath = QString::fromWCharArray(processName);
+//         return QFileInfo(fullPath).baseName();
+//     }
+
+//     CloseHandle(hProcess);
+//     return QString();
+// }
+
+// bool SimpleWindowFinder::isValidWindow(HWND hwnd)
+// {
+//     if (!IsWindow(hwnd) || !IsWindowVisible(hwnd)) {
+//         return false;
+//     }
+
+//     // 过滤掉没有标题的窗口
+//     wchar_t title[256];
+//     if (GetWindowTextW(hwnd, title, 256) == 0) {
+//         return false;
+//     }
+
+//     // 过滤掉工具窗口
+//     LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+//     if (exStyle & WS_EX_TOOLWINDOW) {
+//         return false;
+//     }
+
+//     // 检查窗口是否有父窗口(排除子窗口)
+//     if (GetParent(hwnd) != NULL) {
+//         return false;
+//     }
+
+//     // 更严格的顶层窗口检查:必须是应用程序主窗口
+//     LONG style = GetWindowLong(hwnd, GWL_STYLE);
+
+//     // 检查是否是顶层窗口(必须有标题栏或是弹出窗口)
+//     if (!(style & WS_CAPTION) && !(style & WS_POPUP)) {
+//         return false;
+//     }
+
+//     // 排除子窗口:检查WS_CHILD样式
+//     if (style & WS_CHILD) {
+//         return false;
+//     }
+
+//     // 检查窗口是否在Alt+Tab列表中(更严格的检查)
+//     HWND owner = GetWindow(hwnd, GW_OWNER);
+//     if (owner != NULL) {
+//         // 如果有所有者窗口且所有者可见,则不显示
+//         if (IsWindowVisible(owner)) {
+//             return false;
+//         }
+//         // 检查所有者是否是桌面窗口
+//         HWND desktop = GetDesktopWindow();
+//         if (owner != desktop) {
+//             return false;
+//         }
+//     }
+
+//     // 确保是应用程序窗口:检查窗口是否有应用程序图标
+//     HICON icon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0);
+//     if (!icon) {
+//         icon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0);
+//     }
+//     if (!icon) {
+//         icon = (HICON)GetClassLongPtr(hwnd, GCLP_HICON);
+//     }
+//     // 如果没有图标,可能不是应用程序主窗口
+//     if (!icon) {
+//         return false;
+//     }
+
+//     // 过滤掉一些系统窗口类名
+//     wchar_t className[256];
+//     if (GetClassNameW(hwnd, className, 256) > 0) {
+//         std::wstring classStr(className);
+//         if (classStr == L"Shell_TrayWnd" ||           // 任务栏
+//             classStr == L"DV2ControlHost" ||         // 桌面窗口
+//             classStr == L"MsgrIMEWindowClass" ||     // 输入法窗口
+//             classStr == L"SysShadow" ||              // 阴影窗口
+//             classStr.find(L"IME") != std::wstring::npos) {  // 输入法相关窗口
+//             return false;
+//         }
+//     }
+
+//     return true;
+// }
+
+// // ============================================================================
+// // SimpleDesktopPreview Implementation
+// // ============================================================================
+
+// SimpleDesktopPreview::SimpleDesktopPreview(QWidget* parent)
+//     : QLabel(parent)
+//     , m_updateTimer(new QTimer(this))
+//     , m_previewSize(240, 180)  // 程序预览的2倍 (120x90 * 2)
+//     , m_isActive(false)
+// {
+//     setMinimumSize(m_previewSize);
+//     setScaledContents(false);  // 不拉伸内容,保持1:1比例
+//     setAlignment(Qt::AlignCenter);  // 居中显示
+//     setStyleSheet(
+//         "QLabel { "
+//         "  border: 2px solid #3498db; "
+//         "  border-radius: 5px; "
+//         "  background-color: #ecf0f1; "
+//         "}"
+//     );
+//     setCursor(Qt::PointingHandCursor);
+
+//     connect(m_updateTimer, &QTimer::timeout, this, &SimpleDesktopPreview::updateDesktop);
+
+//     setText("点击开始桌面预览");
+//     setAlignment(Qt::AlignCenter);
+// }
+
+// SimpleDesktopPreview::~SimpleDesktopPreview()
+// {
+//     stopPreview();
+// }
+
+// void SimpleDesktopPreview::startPreview()
+// {
+//     if (m_isActive) {
+//         return;
+//     }
+
+//     qDebug() << "Starting desktop preview";
+//     m_isActive = true;
+//     m_updateTimer->start(1000); // 1秒更新一次
+//     updateDesktop();
+// }
+
+// void SimpleDesktopPreview::stopPreview()
+// {
+//     if (!m_isActive) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping desktop preview";
+//     m_isActive = false;
+//     m_updateTimer->stop();
+//     setText("桌面预览已停止");
+//     setAlignment(Qt::AlignCenter);
+// }
+
+// void SimpleDesktopPreview::setUpdateInterval(int ms)
+// {
+//     if (m_updateTimer->isActive()) {
+//         m_updateTimer->setInterval(ms);
+//     }
+// }
+
+// void SimpleDesktopPreview::updateDesktop()
+// {
+//     if (!m_isActive) {
+//         return;
+//     }
+
+//     QPixmap desktop = SimpleWindowFinder::captureDesktop(m_previewSize);
+//     if (!desktop.isNull()) {
+//         setPixmap(desktop);
+//     }
+// }
+
+// void SimpleDesktopPreview::mousePressEvent(QMouseEvent* event)
+// {
+//     if (event->button() == Qt::LeftButton) {
+//         emit clicked();
+//     }
+//     QLabel::mousePressEvent(event);
+// }
+
+// void SimpleDesktopPreview::paintEvent(QPaintEvent* event)
+// {
+//     QLabel::paintEvent(event);
+
+//     if (m_isActive) {
+//         QPainter painter(this);
+//         painter.setRenderHint(QPainter::Antialiasing);
+
+//         // 绘制录制指示器
+//         painter.setPen(QPen(Qt::red, 2));
+//         painter.setBrush(Qt::red);
+//         painter.drawEllipse(width() - 20, 10, 10, 10);
+
+//         painter.setPen(Qt::white);
+//         painter.drawText(width() - 60, 25, "LIVE");
+//     }
+// }
+
+// // ============================================================================
+// // SimpleWindowList Implementation
+// // ============================================================================
+
+// SimpleWindowList::SimpleWindowList(QWidget* parent)
+//     : QScrollArea(parent)
+//     , m_contentWidget(new QWidget)
+//     , m_layout(new QGridLayout(m_contentWidget))
+//     , m_thumbnailSize(120, 90)
+//     , m_showMinimized(true)
+//     , m_columnsCount(6)
+// {
+//     setWidget(m_contentWidget);
+//     setWidgetResizable(true);
+//     setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+//     setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+//     m_layout->setSpacing(5);
+//     m_layout->setContentsMargins(5, 5, 5, 5);
+
+//     setStyleSheet(
+//         "QScrollArea { "
+//         "  background-color: #f8f9fa; "
+//         "  border: 1px solid #bdc3c7; "
+//         "  border-radius: 3px; "
+//         "}"
+//         "QWidget { background-color: transparent; }"
+//     );
+// }
+
+// SimpleWindowList::~SimpleWindowList()
+// {
+//     clearLayout();
+// }
+
+// void SimpleWindowList::setThumbnailSize(const QSize& size)
+// {
+//     if (m_thumbnailSize != size) {
+//         m_thumbnailSize = size;
+//         refreshWindowList();
+//     }
+// }
+
+// void SimpleWindowList::setShowMinimized(bool show)
+// {
+//     if (m_showMinimized != show) {
+//         m_showMinimized = show;
+//         refreshWindowList();
+//     }
+// }
+
+// QWidget* SimpleWindowList::createDesktopPreviewItem()
+// {
+//     auto* widget = new QWidget;
+//     widget->setFixedSize(m_thumbnailSize + QSize(10, 30));
+//     widget->setCursor(Qt::PointingHandCursor);
+
+//     auto* layout = new QVBoxLayout(widget);
+//     layout->setContentsMargins(2, 2, 2, 2);
+//     layout->setSpacing(2);
+
+//     // 桌面缩略图
+//     auto* thumbnailLabel = new QLabel;
+//     thumbnailLabel->setFixedSize(m_thumbnailSize);
+//     thumbnailLabel->setScaledContents(false);
+//     thumbnailLabel->setAlignment(Qt::AlignCenter);
+//     thumbnailLabel->setStyleSheet(
+//         "QLabel { "
+//         "  border: 2px solid #3498db; "
+//         "  border-radius: 3px; "
+//         "  background-color: #ecf0f1; "
+//         "}"
+//     );
+
+//     // 获取桌面缩略图
+//     QPixmap desktop = SimpleWindowFinder::captureDesktop(m_thumbnailSize);
+//     if (!desktop.isNull()) {
+//         thumbnailLabel->setPixmap(desktop);
+//     } else {
+//         thumbnailLabel->setText("桌面");
+//         thumbnailLabel->setAlignment(Qt::AlignCenter);
+//     }
+
+//     layout->addWidget(thumbnailLabel);
+
+//     // 标题
+//     auto* titleLabel = new QLabel("桌面预览");
+//     titleLabel->setAlignment(Qt::AlignCenter);
+//     titleLabel->setWordWrap(true);
+//     titleLabel->setMaximumHeight(20);
+//     titleLabel->setStyleSheet("font-size: 10px; color: #2c3e50; font-weight: bold;");
+
+//     layout->addWidget(titleLabel);
+
+//     // 标记为桌面预览项
+//     widget->setProperty("isDesktop", true);
+
+//     // 连接点击事件
+//     widget->installEventFilter(this);
+
+//     return widget;
+// }
+
+// void SimpleWindowList::refreshWindowList()
+// {
+//     qDebug() << "Refreshing window list...";
+
+//     auto newWindows = SimpleWindowFinder::getWindowList(m_showMinimized);
+
+//     // 检查是否有变化
+//     bool hasChanges = (newWindows.size() != m_windows.size());
+//     if (!hasChanges) {
+//         for (int i = 0; i < newWindows.size(); ++i) {
+//             if (newWindows[i].hwnd != m_windows[i].hwnd) {
+//                 hasChanges = true;
+//                 break;
+//             }
+//         }
+//     }
+
+//     if (hasChanges) {
+//         m_windows = newWindows;
+//         updateLayout();
+//         qDebug() << "Window list updated:" << m_windows.size() << "windows";
+//     }
+// }
+
+// void SimpleWindowList::updateLayout()
+// {
+//     clearLayout();
+
+//     // 计算列数
+//     int availableWidth = viewport()->width() - 20;
+//     m_columnsCount = qMax(1, availableWidth / (m_thumbnailSize.width() + 10));
+
+//     int row = 0, col = 0;
+
+//     // 首先添加桌面预览项
+//     auto* desktopItem = createDesktopPreviewItem();
+//     if (desktopItem) {
+//         m_layout->addWidget(desktopItem, row, col);
+//         col++;
+//         if (col >= m_columnsCount) {
+//             col = 0;
+//             row++;
+//         }
+//     }
+
+//     // 然后添加窗口项
+//     for (const auto& window : m_windows) {
+//         auto* item = createWindowItem(window);
+//         if (item) {
+//             m_layout->addWidget(item, row, col);
+
+//             col++;
+//             if (col >= m_columnsCount) {
+//                 col = 0;
+//                 row++;
+//             }
+//         }
+//     }
+
+//     // 添加弹性空间
+//     m_layout->setRowStretch(row + 1, 1);
+//     m_layout->setColumnStretch(m_columnsCount, 1);
+// }
+
+// QWidget* SimpleWindowList::createWindowItem(const SimpleWindowInfo& info)
+// {
+//     auto* widget = new QWidget;
+//     widget->setFixedSize(m_thumbnailSize + QSize(10, 30));
+//     widget->setCursor(Qt::PointingHandCursor);
+
+//     auto* layout = new QVBoxLayout(widget);
+//     layout->setContentsMargins(2, 2, 2, 2);
+//     layout->setSpacing(2);
+
+//     // 缩略图
+//     auto* thumbnailLabel = new QLabel;
+//     thumbnailLabel->setFixedSize(m_thumbnailSize);
+//     thumbnailLabel->setScaledContents(false);  // 不拉伸内容,保持原比例
+//     thumbnailLabel->setAlignment(Qt::AlignCenter);  // 居中显示
+//     thumbnailLabel->setStyleSheet(
+//         "QLabel { "
+//         "  border: 1px solid #bdc3c7; "
+//         "  border-radius: 3px; "
+//         "  background-color: #ecf0f1; "
+//         "}"
+//     );
+
+//     // 获取缩略图
+//     QPixmap thumbnail = SimpleWindowFinder::captureWindow(info.hwnd, m_thumbnailSize);
+//     if (!thumbnail.isNull()) {
+//         thumbnailLabel->setPixmap(thumbnail);
+//     } else {
+//         // 使用图标作为占位符
+//         QPixmap iconPixmap = info.icon.pixmap(64, 64);
+//         thumbnailLabel->setPixmap(iconPixmap);
+//     }
+
+//     layout->addWidget(thumbnailLabel);
+
+//     // 标题
+//     auto* titleLabel = new QLabel(info.title);
+//     titleLabel->setAlignment(Qt::AlignCenter);
+//     titleLabel->setWordWrap(true);
+//     titleLabel->setMaximumHeight(20);
+//     titleLabel->setStyleSheet("font-size: 10px; color: #2c3e50;");
+
+//     // 截断过长的标题
+//     QString displayTitle = info.title;
+//     if (displayTitle.length() > 20) {
+//         displayTitle = displayTitle.left(17) + "...";
+//     }
+//     titleLabel->setText(displayTitle);
+//     titleLabel->setToolTip(info.title);
+
+//     layout->addWidget(titleLabel);
+
+//     // 存储窗口句柄
+//     widget->setProperty("hwnd", reinterpret_cast<qintptr>(info.hwnd));
+
+//     // 连接点击事件
+//     widget->installEventFilter(this);
+
+//     // 最小化窗口的视觉提示
+//     if (info.isMinimized) {
+//         widget->setStyleSheet("QWidget { opacity: 0.7; }");
+//     }
+
+//     return widget;
+// }
+
+// void SimpleWindowList::clearLayout()
+// {
+//     while (QLayoutItem* item = m_layout->takeAt(0)) {
+//         if (QWidget* widget = item->widget()) {
+//             widget->deleteLater();
+//         }
+//         delete item;
+//     }
+// }
+
+// void SimpleWindowList::resizeEvent(QResizeEvent* event)
+// {
+//     QScrollArea::resizeEvent(event);
+//     QTimer::singleShot(100, this, &SimpleWindowList::updateLayout);
+// }
+
+// bool SimpleWindowList::eventFilter(QObject* obj, QEvent* event)
+// {
+//     if (auto* widget = qobject_cast<QWidget*>(obj)) {
+//         // 检查是否是桌面预览项
+//         bool isDesktop = widget->property("isDesktop").toBool();
+
+//         if (event->type() == QEvent::MouseButtonPress) {
+//             auto* mouseEvent = static_cast<QMouseEvent*>(event);
+//             if (mouseEvent->button() == Qt::LeftButton) {
+//                 if (isDesktop) {
+//                     emit desktopClicked();
+//                     return true;
+//                 } else {
+//                     QVariant hwndVariant = widget->property("hwnd");
+//                     if (hwndVariant.isValid()) {
+//                         HWND hwnd = reinterpret_cast<HWND>(hwndVariant.value<qintptr>());
+//                         if (hwnd) {
+//                             // 查找窗口标题
+//                             QString title;
+//                             for (const auto& window : m_windows) {
+//                                 if (window.hwnd == hwnd) {
+//                                     title = window.title;
+//                                     break;
+//                                 }
+//                             }
+//                             emit windowSelected(hwnd, title);
+//                             return true;
+//                         } else {
+//                             qDebug() << "Invalid hwnd in click event";
+//                         }
+//                     } else {
+//                         qDebug() << "No hwnd property found in click event";
+//                     }
+//                 }
+//             }
+//         } else if (event->type() == QEvent::MouseButtonDblClick) {
+//             if (!isDesktop) {
+//                 QVariant hwndVariant = widget->property("hwnd");
+//                 if (hwndVariant.isValid()) {
+//                     HWND hwnd = reinterpret_cast<HWND>(hwndVariant.value<qintptr>());
+//                     if (hwnd) {
+//                         emit windowDoubleClicked(hwnd);
+//                         return true;
+//                     } else {
+//                         qDebug() << "Invalid hwnd in double click event";
+//                     }
+//                 } else {
+//                     qDebug() << "No hwnd property found in double click event";
+//                 }
+//             }
+//         }
+//     }
+
+//     return QScrollArea::eventFilter(obj, event);
+// }
+
+// // ============================================================================
+// // SimpleWindowPreview Implementation
+// // ============================================================================
+
+// SimpleWindowPreview::SimpleWindowPreview(QWidget* parent)
+//     : QLabel(parent)
+//     , m_updateTimer(new QTimer(this))
+//     , m_stateTimer(new QTimer(this))
+//     , m_targetHwnd(nullptr)
+//     , m_isActive(false)
+//     , m_isWindowMinimized(false)
+// {
+//     setMinimumSize(400, 300);
+//     setScaledContents(true);
+//     setStyleSheet(
+//         "QLabel { "
+//         "  border: 2px solid #e74c3c; "
+//         "  border-radius: 5px; "
+//         "  background-color: #ecf0f1; "
+//         "}"
+//     );
+
+//     connect(m_updateTimer, &QTimer::timeout, this, &SimpleWindowPreview::updatePreview);
+//     connect(m_stateTimer, &QTimer::timeout, this, &SimpleWindowPreview::checkWindowState);
+
+//     setText("请选择要预览的窗口");
+//     setAlignment(Qt::AlignCenter);
+// }
+
+// SimpleWindowPreview::~SimpleWindowPreview()
+// {
+//     stopPreview();
+// }
+
+// void SimpleWindowPreview::setTargetWindow(HWND hwnd, const QString& title)
+// {
+//     if (m_targetHwnd == hwnd) {
+//         return;
+//     }
+
+//     stopPreview();
+//     m_targetHwnd = hwnd;
+//     m_windowTitle = title;
+
+//     if (hwnd && IsWindow(hwnd)) {
+//         setText(QString("准备预览: %1").arg(m_windowTitle));
+//     } else {
+//         setText("请选择要预览的窗口");
+//     }
+//     setAlignment(Qt::AlignCenter);
+// }
+
+// void SimpleWindowPreview::startPreview()
+// {
+//     if (!m_targetHwnd || !IsWindow(m_targetHwnd) || m_isActive) {
+//         return;
+//     }
+
+//     qDebug() << "Starting window preview for" << m_windowTitle;
+
+//     m_isActive = true;
+//     m_isWindowMinimized = IsIconic(m_targetHwnd);
+
+//     m_updateTimer->start(500); // 0.5秒更新一次
+//     m_stateTimer->start(1000); // 每秒检查窗口状态
+
+//     updatePreview();
+// }
+
+// void SimpleWindowPreview::stopPreview()
+// {
+//     if (!m_isActive) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping window preview";
+
+//     m_updateTimer->stop();
+//     m_stateTimer->stop();
+//     m_isActive = false;
+
+//     if (!m_windowTitle.isEmpty()) {
+//         setText(QString("预览已停止: %1").arg(m_windowTitle));
+//     } else {
+//         setText("请选择要预览的窗口");
+//     }
+//     setAlignment(Qt::AlignCenter);
+// }
+
+// void SimpleWindowPreview::setUpdateInterval(int ms)
+// {
+//     if (m_updateTimer->isActive()) {
+//         m_updateTimer->setInterval(ms);
+//     }
+// }
+
+// void SimpleWindowPreview::updatePreview()
+// {
+//     if (!m_isActive || !m_targetHwnd || !IsWindow(m_targetHwnd)) {
+//         return;
+//     }
+
+//     QPixmap frame = SimpleWindowFinder::captureWindow(m_targetHwnd, size());
+//     if (!frame.isNull()) {
+//         // 如果窗口未最小化,保存最后一帧
+//         if (!m_isWindowMinimized) {
+//             m_lastFrame = frame;
+//         }
+//         setPixmap(frame);
+//     } else if (m_isWindowMinimized && !m_lastFrame.isNull()) {
+//         // 显示最后一帧
+//         setPixmap(m_lastFrame);
+//     }
+// }
+
+// void SimpleWindowPreview::checkWindowState()
+// {
+//     if (!m_targetHwnd || !IsWindow(m_targetHwnd)) {
+//         stopPreview();
+//         return;
+//     }
+
+//     bool isMinimized = IsIconic(m_targetHwnd);
+//     if (isMinimized != m_isWindowMinimized) {
+//         m_isWindowMinimized = isMinimized;
+
+//         if (isMinimized) {
+//             qDebug() << "Window minimized:" << m_windowTitle;
+//         } else {
+//             qDebug() << "Window restored:" << m_windowTitle;
+//         }
+//     }
+// }
+
+// void SimpleWindowPreview::paintEvent(QPaintEvent* event)
+// {
+//     QLabel::paintEvent(event);
+
+//     if (!m_windowTitle.isEmpty()) {
+//         QPainter painter(this);
+//         painter.setRenderHint(QPainter::Antialiasing);
+
+//         // 绘制窗口标题
+//         painter.setPen(Qt::white);
+//         painter.drawText(10, height() - 10, m_windowTitle);
+
+//         // 绘制状态指示器
+//         if (m_isActive) {
+//             painter.setPen(QPen(Qt::green, 2));
+//             painter.setBrush(Qt::green);
+//             painter.drawEllipse(width() - 20, 10, 10, 10);
+//         }
+
+//         if (m_isWindowMinimized) {
+//             painter.setPen(Qt::yellow);
+//             painter.drawText(width() - 100, 25, "MINIMIZED");
+//         }
+//     }
+// }
+
+// // ============================================================================
+// // SimpleScreenWall Implementation
+// // ============================================================================
+
+// SimpleScreenWall::SimpleScreenWall(QWidget* parent)
+//     : QWidget(parent)
+//     , m_mainLayout(nullptr)
+//     , m_desktopPreview(nullptr)
+//     , m_windowList(nullptr)
+
+//     , m_isRunning(false)
+//     , m_selectedWindow(nullptr)
+//     , m_refreshTimer(new QTimer(this))
+// {
+//     setupUI();
+//     setupConnections();
+
+//     setMinimumSize(800, 600);
+//     resize(1200, 900);
+// }
+
+// SimpleScreenWall::~SimpleScreenWall()
+// {
+//     stopScreenWall();
+// }
+
+// void SimpleScreenWall::setupUI()
+// {
+//     m_mainLayout = new QVBoxLayout(this);
+//     m_mainLayout->setContentsMargins(5, 5, 5, 5);
+//     m_mainLayout->setSpacing(5);
+
+//     // 统一的预览区域,包含桌面和程序预览
+//     m_windowList = new SimpleWindowList(this);
+//     m_mainLayout->addWidget(m_windowList, 1);
+
+//     // 移除单独的桌面预览和窗口预览组件
+//     m_desktopPreview = nullptr;
+// }
+
+// void SimpleScreenWall::setupConnections()
+// {
+//     connect(m_windowList, &SimpleWindowList::desktopClicked,
+//             this, &SimpleScreenWall::onDesktopClicked);
+
+//     connect(m_windowList, &SimpleWindowList::windowSelected,
+//             this, &SimpleScreenWall::onWindowSelected);
+
+//     connect(m_windowList, &SimpleWindowList::windowDoubleClicked,
+//             this, &SimpleScreenWall::onWindowDoubleClicked);
+
+//     connect(m_refreshTimer, &QTimer::timeout,
+//             this, &SimpleScreenWall::refreshWindowList);
+// }
+
+// void SimpleScreenWall::setConfig(const SimpleScreenWallConfig& config)
+// {
+//     m_config = config;
+
+//     if (m_windowList) {
+//         m_windowList->setThumbnailSize(config.thumbnailSize);
+//         m_windowList->setShowMinimized(config.showMinimizedWindows);
+//     }
+
+//     // 桌面预览现在集成在窗口列表中,不需要单独设置
+
+//     SimpleCacheManager::instance().setMaxCacheSize(config.maxCachedThumbnails);
+// }
+
+// void SimpleScreenWall::startScreenWall()
+// {
+//     if (m_isRunning) {
+//         return;
+//     }
+
+//     qDebug() << "Starting SimpleScreenWall...";
+
+//     m_isRunning = true;
+
+//     // 桌面预览现在集成在窗口列表中
+
+//     // 刷新窗口列表
+//     refreshWindowList();
+
+//     // 启动定时刷新
+//     m_refreshTimer->start(m_config.windowUpdateInterval);
+
+//     emit started();
+//     qDebug() << "SimpleScreenWall started successfully";
+// }
+
+// void SimpleScreenWall::stopScreenWall()
+// {
+//     if (!m_isRunning) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping SimpleScreenWall...";
+
+//     m_isRunning = false;
+
+//     // 停止定时器
+//     m_refreshTimer->stop();
+
+//     // 窗口预览功能已集成到窗口列表中
+
+//     // 清理缓存
+//     SimpleCacheManager::instance().clearCache();
+
+//     m_selectedWindow = nullptr;
+
+//     emit stopped();
+//     qDebug() << "SimpleScreenWall stopped";
+// }
+
+// void SimpleScreenWall::refreshWindowList()
+// {
+//     if (m_windowList) {
+//         m_windowList->refreshWindowList();
+//     }
+// }
+
+// void SimpleScreenWall::onWindowSelected(HWND hwnd, const QString& title)
+// {
+//     if (m_selectedWindow == hwnd) {
+//         return;
+//     }
+
+//     m_selectedWindow = hwnd;
+
+//     if (hwnd && IsWindow(hwnd)) {
+//         emit windowSelected(hwnd, title);
+//     }
+// }
+
+// void SimpleScreenWall::onDesktopClicked()
+// {
+//     // 取消窗口选择
+//     if (m_selectedWindow) {
+//         m_selectedWindow = nullptr;
+//     }
+
+//     emit desktopSelected();
+// }
+
+// void SimpleScreenWall::onWindowDoubleClicked(HWND hwnd)
+// {
+//     // 检查窗口句柄是否有效
+//     if (!hwnd || !IsWindow(hwnd)) {
+//         qDebug() << "Invalid window handle in double click event";
+//         return;
+//     }
+
+//     // 激活窗口
+//     if (!SimpleScreenWallUtils::activateWindow(hwnd)) {
+//         qDebug() << "Failed to activate window:" << hwnd;
+//     }
+// }
+
+// void SimpleScreenWall::showEvent(QShowEvent* event)
+// {
+//     QWidget::showEvent(event);
+
+//     if (!m_isRunning) {
+//         QTimer::singleShot(500, this, &SimpleScreenWall::startScreenWall);
+//     }
+// }
+
+// void SimpleScreenWall::hideEvent(QHideEvent* event)
+// {
+//     QWidget::hideEvent(event);
+
+//     if (m_isRunning) {
+//         stopScreenWall();
+//     }
+// }
+
+// void SimpleScreenWall::resizeEvent(QResizeEvent* event)
+// {
+//     QWidget::resizeEvent(event);
+
+//     if (m_windowList) {
+//         QTimer::singleShot(100, m_windowList, &SimpleWindowList::refreshWindowList);
+//     }
+// }
+
+// void SimpleScreenWall::updateLayout()
+// {
+//     // 根据窗口大小调整布局比例
+//     int totalHeight = height();
+//     int desktopHeight = totalHeight * 0.3;
+//     int listHeight = totalHeight * 0.2;
+//     int previewHeight = totalHeight * 0.5;
+
+//     // 现在只有窗口列表,不需要复杂的布局分配
+//     // m_windowList 会自动调整大小
+// }
+
+// // ============================================================================
+// // SimpleCacheManager Implementation
+// // ============================================================================
+
+// SimpleCacheManager& SimpleCacheManager::instance()
+// {
+//     static SimpleCacheManager instance;
+//     return instance;
+// }
+
+// void SimpleCacheManager::cacheThumbnail(HWND hwnd, const QPixmap& thumbnail)
+// {
+//     m_thumbnailCache.insert(hwnd, new QPixmap(thumbnail));
+// }
+
+// QPixmap SimpleCacheManager::getCachedThumbnail(HWND hwnd) const
+// {
+//     QPixmap* cached = m_thumbnailCache.object(hwnd);
+//     return cached ? *cached : QPixmap();
+// }
+
+// void SimpleCacheManager::cacheIcon(HWND hwnd, const QIcon& icon)
+// {
+//     m_iconCache.insert(hwnd, new QIcon(icon));
+// }
+
+// QIcon SimpleCacheManager::getCachedIcon(HWND hwnd) const
+// {
+//     QIcon* cached = m_iconCache.object(hwnd);
+//     return cached ? *cached : QIcon();
+// }
+
+// void SimpleCacheManager::clearCache()
+// {
+//     m_thumbnailCache.clear();
+//     m_iconCache.clear();
+// }
+
+// void SimpleCacheManager::setMaxCacheSize(int size)
+// {
+//     m_thumbnailCache.setMaxCost(size);
+//     m_iconCache.setMaxCost(size);
+// }
+
+// // ============================================================================
+// // SimpleScreenWallUtils Implementation
+// // ============================================================================
+
+// QPixmap SimpleScreenWallUtils::scalePixmap(const QPixmap& pixmap, const QSize& size, Qt::AspectRatioMode mode)
+// {
+//     if (pixmap.isNull() || size.isEmpty()) {
+//         return pixmap;
+//     }
+
+//     return pixmap.scaled(size, mode, Qt::SmoothTransformation);
+// }
+
+// QPixmap SimpleScreenWallUtils::addBorder(const QPixmap& pixmap, int borderWidth, const QColor& color)
+// {
+//     if (pixmap.isNull() || borderWidth <= 0) {
+//         return pixmap;
+//     }
+
+//     QPixmap result(pixmap.size() + QSize(borderWidth * 2, borderWidth * 2));
+//     result.fill(color);
+
+//     QPainter painter(&result);
+//     painter.drawPixmap(borderWidth, borderWidth, pixmap);
+
+//     return result;
+// }
+
+// QPixmap SimpleScreenWallUtils::addShadow(const QPixmap& pixmap, int shadowSize, const QColor& color)
+// {
+//     if (pixmap.isNull() || shadowSize <= 0) {
+//         return pixmap;
+//     }
+
+//     QPixmap result(pixmap.size() + QSize(shadowSize * 2, shadowSize * 2));
+//     result.fill(Qt::transparent);
+
+//     QPainter painter(&result);
+//     painter.setRenderHint(QPainter::Antialiasing);
+
+//     // 绘制阴影
+//     painter.setBrush(color);
+//     painter.setPen(Qt::NoPen);
+//     painter.drawRoundedRect(shadowSize, shadowSize, pixmap.width(), pixmap.height(), 5, 5);
+
+//     // 绘制原图
+//     painter.drawPixmap(0, 0, pixmap);
+
+//     return result;
+// }
+
+// QString SimpleScreenWallUtils::getSystemInfo()
+// {
+//     QString info;
+//     info += QString("OS: Windows\n");
+//     info += QString("Qt Version: %1\n").arg(QT_VERSION_STR);
+//     info += QString("Screen Count: %1\n").arg(QApplication::screens().count());
+
+//     return info;
+// }
+
+// QStringList SimpleScreenWallUtils::getRunningProcesses()
+// {
+//     QStringList processes;
+
+//     DWORD processIds[1024], bytesReturned;
+//     if (EnumProcesses(processIds, sizeof(processIds), &bytesReturned)) {
+//         DWORD processCount = bytesReturned / sizeof(DWORD);
+
+//         for (DWORD i = 0; i < processCount; i++) {
+//             HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIds[i]);
+//             if (hProcess) {
+//                 wchar_t processName[MAX_PATH];
+//                 DWORD size = MAX_PATH;
+//                 if (QueryFullProcessImageNameW(hProcess, 0, processName, &size)) {
+//                     QString fullPath = QString::fromWCharArray(processName);
+//                     processes.append(QFileInfo(fullPath).baseName());
+//                 }
+//                 CloseHandle(hProcess);
+//             }
+//         }
+//     }
+
+//     return processes;
+// }
+
+// int SimpleScreenWallUtils::getSystemMemoryUsage()
+// {
+//     MEMORYSTATUSEX memInfo;
+//     memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+//     GlobalMemoryStatusEx(&memInfo);
+
+//     return static_cast<int>(memInfo.dwMemoryLoad);
+// }
+
+// int SimpleScreenWallUtils::getCpuUsage()
+// {
+//     // 简化实现,返回固定值
+//     // 实际实现需要使用性能计数器
+//     return 0;
+// }
+
+// void SimpleScreenWallUtils::saveConfig(const SimpleScreenWallConfig& config, const QString& filePath)
+// {
+//     QString path = filePath;
+//     if (path.isEmpty()) {
+//         path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/screenwall_config.json";
+//     }
+
+//     QJsonObject json;
+//     json["desktopUpdateInterval"] = config.desktopUpdateInterval;
+//     json["windowUpdateInterval"] = config.windowUpdateInterval;
+//     json["previewUpdateInterval"] = config.previewUpdateInterval;
+//     json["thumbnailWidth"] = config.thumbnailSize.width();
+//     json["thumbnailHeight"] = config.thumbnailSize.height();
+//     json["desktopPreviewWidth"] = config.desktopPreviewSize.width();
+//     json["desktopPreviewHeight"] = config.desktopPreviewSize.height();
+//     json["maxCachedThumbnails"] = config.maxCachedThumbnails;
+//     json["enableDesktopPreview"] = config.enableDesktopPreview;
+//     json["enableWindowPreview"] = config.enableWindowPreview;
+//     json["showMinimizedWindows"] = config.showMinimizedWindows;
+
+//     QJsonDocument doc(json);
+
+//     QDir().mkpath(QFileInfo(path).absolutePath());
+//     QFile file(path);
+//     if (file.open(QIODevice::WriteOnly)) {
+//         file.write(doc.toJson());
+//     }
+// }
+
+// SimpleScreenWallConfig SimpleScreenWallUtils::loadConfig(const QString& filePath)
+// {
+//     QString path = filePath;
+//     if (path.isEmpty()) {
+//         path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/screenwall_config.json";
+//     }
+
+//     SimpleScreenWallConfig config; // 使用默认值
+
+//     QFile file(path);
+//     if (file.open(QIODevice::ReadOnly)) {
+//         QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
+//         QJsonObject json = doc.object();
+
+//         if (json.contains("desktopUpdateInterval")) {
+//             config.desktopUpdateInterval = json["desktopUpdateInterval"].toInt();
+//         }
+//         if (json.contains("windowUpdateInterval")) {
+//             config.windowUpdateInterval = json["windowUpdateInterval"].toInt();
+//         }
+//         if (json.contains("previewUpdateInterval")) {
+//             config.previewUpdateInterval = json["previewUpdateInterval"].toInt();
+//         }
+//         if (json.contains("thumbnailWidth") && json.contains("thumbnailHeight")) {
+//             config.thumbnailSize = QSize(json["thumbnailWidth"].toInt(), json["thumbnailHeight"].toInt());
+//         }
+//         if (json.contains("desktopPreviewWidth") && json.contains("desktopPreviewHeight")) {
+//             config.desktopPreviewSize = QSize(json["desktopPreviewWidth"].toInt(), json["desktopPreviewHeight"].toInt());
+//         }
+//         if (json.contains("maxCachedThumbnails")) {
+//             config.maxCachedThumbnails = json["maxCachedThumbnails"].toInt();
+//         }
+//         if (json.contains("enableDesktopPreview")) {
+//             config.enableDesktopPreview = json["enableDesktopPreview"].toBool();
+//         }
+//         if (json.contains("enableWindowPreview")) {
+//             config.enableWindowPreview = json["enableWindowPreview"].toBool();
+//         }
+//         if (json.contains("showMinimizedWindows")) {
+//             config.showMinimizedWindows = json["showMinimizedWindows"].toBool();
+//         }
+//     }
+
+//     return config;
+// }
+
+// // ============================================================================
+// // SimpleScreenWallWindow Implementation
+// // ============================================================================
+
+// SimpleScreenWallWindow::SimpleScreenWallWindow(QWidget* parent)
+//     : QWidget(parent)
+//     , m_mainLayout(nullptr)
+//     , m_controlPanel(nullptr)
+//     , m_controlLayout(nullptr)
+//     , m_startButton(nullptr)
+//     , m_stopButton(nullptr)
+//     , m_refreshButton(nullptr)
+//     , m_settingsButton(nullptr)
+//     , m_statusLabel(nullptr)
+//     , m_screenWall(nullptr)
+// {
+//     setupUI();
+//     setupConnections();
+
+//     setWindowTitle("简化版屏幕墙");
+//     setMinimumSize(1000, 700);
+//     resize(1200, 900);
+// }
+
+// SimpleScreenWallWindow::~SimpleScreenWallWindow()
+// {
+//     if (m_screenWall && m_screenWall->isRunning()) {
+//         m_screenWall->stopScreenWall();
+//     }
+// }
+
+// void SimpleScreenWallWindow::setupUI()
+// {
+//     m_mainLayout = new QVBoxLayout(this);
+//     m_mainLayout->setContentsMargins(5, 5, 5, 5);
+//     m_mainLayout->setSpacing(5);
+
+//     // 控制面板
+//     m_controlPanel = new QWidget(this);
+//     m_controlLayout = new QHBoxLayout(m_controlPanel);
+//     m_controlLayout->setContentsMargins(0, 0, 0, 0);
+
+//     m_startButton = new QPushButton("启动屏幕墙", this);
+//     m_stopButton = new QPushButton("停止屏幕墙", this);
+//     m_refreshButton = new QPushButton("刷新窗口", this);
+//     m_settingsButton = new QPushButton("设置", this);
+
+//     m_statusLabel = new QLabel("状态: 已停止", this);
+
+//     m_controlLayout->addWidget(m_startButton);
+//     m_controlLayout->addWidget(m_stopButton);
+//     m_controlLayout->addWidget(m_refreshButton);
+//     m_controlLayout->addWidget(m_settingsButton);
+//     m_controlLayout->addStretch();
+//     m_controlLayout->addWidget(m_statusLabel);
+
+//     m_mainLayout->addWidget(m_controlPanel);
+
+//     // 屏幕墙组件
+//     m_screenWall = new SimpleScreenWall(this);
+//     m_mainLayout->addWidget(m_screenWall, 1);
+
+//     updateControlButtons();
+// }
+
+// void SimpleScreenWallWindow::setupConnections()
+// {
+//     connect(m_startButton, &QPushButton::clicked, this, &SimpleScreenWallWindow::startScreenWall);
+//     connect(m_stopButton, &QPushButton::clicked, this, &SimpleScreenWallWindow::stopScreenWall);
+//     connect(m_refreshButton, &QPushButton::clicked, this, &SimpleScreenWallWindow::refreshWindows);
+//     connect(m_settingsButton, &QPushButton::clicked, this, &SimpleScreenWallWindow::showSettings);
+
+//     if (m_screenWall) {
+//         connect(m_screenWall, &SimpleScreenWall::windowSelected, this, &SimpleScreenWallWindow::onWindowSelected);
+//         connect(m_screenWall, &SimpleScreenWall::desktopSelected, this, &SimpleScreenWallWindow::onDesktopSelected);
+//         connect(m_screenWall, &SimpleScreenWall::started, this, &SimpleScreenWallWindow::onScreenWallStarted);
+//         connect(m_screenWall, &SimpleScreenWall::stopped, this, &SimpleScreenWallWindow::onScreenWallStopped);
+//     }
+// }
+
+// void SimpleScreenWallWindow::updateControlButtons()
+// {
+//     bool isRunning = m_screenWall && m_screenWall->isRunning();
+
+//     m_startButton->setEnabled(!isRunning);
+//     m_stopButton->setEnabled(isRunning);
+//     m_refreshButton->setEnabled(isRunning);
+
+//     m_statusLabel->setText(isRunning ? "状态: 运行中" : "状态: 已停止");
+// }
+
+// void SimpleScreenWallWindow::closeEvent(QCloseEvent* event)
+// {
+//     if (m_screenWall && m_screenWall->isRunning()) {
+//         m_screenWall->stopScreenWall();
+//     }
+//     QWidget::closeEvent(event);
+// }
+
+// void SimpleScreenWallWindow::startScreenWall()
+// {
+//     if (m_screenWall) {
+//         m_screenWall->startScreenWall();
+//     }
+// }
+
+// void SimpleScreenWallWindow::stopScreenWall()
+// {
+//     if (m_screenWall) {
+//         m_screenWall->stopScreenWall();
+//     }
+// }
+
+// void SimpleScreenWallWindow::refreshWindows()
+// {
+//     if (m_screenWall) {
+//         m_screenWall->refreshWindowList();
+//     }
+// }
+
+// void SimpleScreenWallWindow::showSettings()
+// {
+//     QMessageBox::information(this, "设置", "设置功能尚未实现");
+// }
+
+// void SimpleScreenWallWindow::showAbout()
+// {
+//     QMessageBox::about(this, "关于", "简化版屏幕墙\n版本: 1.0\n\n实时窗口预览系统");
+// }
+
+// void SimpleScreenWallWindow::onWindowSelected(HWND hwnd, const QString& title)
+// {
+//     Q_UNUSED(hwnd)
+//     m_statusLabel->setText(QString("已选择窗口: %1").arg(title));
+// }
+
+// void SimpleScreenWallWindow::onDesktopSelected()
+// {
+//     m_statusLabel->setText("已选择桌面预览");
+// }
+
+// void SimpleScreenWallWindow::onScreenWallStarted()
+// {
+//     updateControlButtons();
+//     m_statusLabel->setText("状态: 运行中");
+// }
+
+// void SimpleScreenWallWindow::onScreenWallStopped()
+// {
+//     updateControlButtons();
+//     m_statusLabel->setText("状态: 已停止");
+// }

+ 374 - 0
ScreenWall/screenwall_simple.h

@@ -0,0 +1,374 @@
+// #pragma once
+
+// #include <QWidget>
+// #include <QVBoxLayout>
+// #include <QHBoxLayout>
+// #include <QGridLayout>
+// #include <QScrollArea>
+// #include <QLabel>
+// #include <QTimer>
+// #include <QPushButton>
+// #include <QPixmap>
+// #include <QIcon>
+// #include <QCache>
+// #include <QSet>
+// #include <QVector>
+// #include <QMouseEvent>
+// #include <QPaintEvent>
+// #include <QResizeEvent>
+// #include <QPainter>
+// #include <QApplication>
+// #include <QDesktopWidget>
+// #include <QScreen>
+// #include <QDebug>
+
+// #ifdef _WIN32
+// #include <windows.h>
+// #include <dwmapi.h>
+// #include <shellapi.h>
+// #include <psapi.h>
+// #pragma comment(lib, "dwmapi.lib")
+// #pragma comment(lib, "shell32.lib")
+// #pragma comment(lib, "psapi.lib")
+// #pragma comment(lib, "user32.lib")
+// #pragma comment(lib, "gdi32.lib")
+// #endif
+
+// /**
+//  * 简化版屏幕墙实现
+//  * 不依赖AvRecorder,使用Windows API直接捕获
+//  * 适用于快速原型和独立部署
+//  */
+
+// // 简化的窗口信息结构
+// struct SimpleWindowInfo {
+//     HWND hwnd = nullptr;
+//     QString title;
+//     QString processName;
+//     QIcon icon;
+//     QPixmap thumbnail;
+//     QRect geometry;
+//     bool isMinimized = false;
+//     bool isVisible = true;
+//     DWORD processId = 0;
+// };
+
+// // 简化的配置结构
+// struct SimpleScreenWallConfig {
+//     int desktopUpdateInterval = 1000;    // 桌面更新间隔(ms)
+//     int windowUpdateInterval = 2000;     // 窗口列表更新间隔(ms)
+//     int previewUpdateInterval = 500;     // 窗口预览更新间隔(ms)
+//     QSize thumbnailSize = QSize(120, 90); // 缩略图尺寸
+//     QSize desktopPreviewSize = QSize(320, 240); // 桌面预览尺寸
+//     int maxCachedThumbnails = 50;        // 最大缓存缩略图数量
+//     bool enableDesktopPreview = true;    // 启用桌面预览
+//     bool enableWindowPreview = true;     // 启用窗口预览
+//     bool showMinimizedWindows = true;    // 显示最小化窗口
+// };
+
+// /**
+//  * 简化的窗口查找器
+//  */
+// class SimpleWindowFinder {
+// public:
+//     static QVector<SimpleWindowInfo> getWindowList(bool includeMinimized = true);
+//     static QPixmap captureWindow(HWND hwnd, const QSize& size = QSize());
+//     static QPixmap captureDesktop(const QSize& size = QSize());
+//     static QIcon getWindowIcon(HWND hwnd);
+//     static QString getWindowTitle(HWND hwnd);
+//     static QString getProcessName(HWND hwnd);
+//     static bool isValidWindow(HWND hwnd);
+
+// private:
+//     static BOOL CALLBACK enumWindowsProc(HWND hwnd, LPARAM lParam);
+
+//     // 多种窗口捕获方法
+//     static QPixmap captureDWMThumbnail(HWND hwnd, int width, int height);
+//     static QPixmap capturePrintWindow(HWND hwnd, int width, int height);
+//     static QPixmap captureScreenshot(HWND hwnd, const RECT& rect);
+//     static QPixmap convertBitmapToPixmap(HBITMAP hBitmap, int width, int height);
+// };
+
+// /**
+//  * 简化的桌面预览组件
+//  */
+// class SimpleDesktopPreview : public QLabel {
+//     Q_OBJECT
+
+// public:
+//     explicit SimpleDesktopPreview(QWidget* parent = nullptr);
+//     ~SimpleDesktopPreview();
+
+//     void startPreview();
+//     void stopPreview();
+//     void setUpdateInterval(int ms);
+
+// signals:
+//     void clicked();
+
+// protected:
+//     void mousePressEvent(QMouseEvent* event) override;
+//     void paintEvent(QPaintEvent* event) override;
+
+// private slots:
+//     void updateDesktop();
+
+// private:
+//     QTimer* m_updateTimer;
+//     QSize m_previewSize;
+//     bool m_isActive;
+// };
+
+// /**
+//  * 简化的窗口图标列表组件
+//  */
+// class SimpleWindowList : public QScrollArea {
+//     Q_OBJECT
+
+// public:
+//     explicit SimpleWindowList(QWidget* parent = nullptr);
+//     ~SimpleWindowList();
+
+//     void setThumbnailSize(const QSize& size);
+//     void setShowMinimized(bool show);
+//     void refreshWindowList();
+
+// signals:
+//     void windowSelected(HWND hwnd, const QString& title);
+//     void windowDoubleClicked(HWND hwnd);
+//     void desktopClicked();
+
+// protected:
+//     void resizeEvent(QResizeEvent* event) override;
+//     bool eventFilter(QObject* obj, QEvent* event) override;
+
+// private:
+//     void updateLayout();
+//     QWidget* createWindowItem(const SimpleWindowInfo& info);
+//     QWidget* createDesktopPreviewItem();
+//     void clearLayout();
+
+// private:
+//     QWidget* m_contentWidget;
+//     QGridLayout* m_layout;
+//     QVector<SimpleWindowInfo> m_windows;
+//     QSize m_thumbnailSize;
+//     bool m_showMinimized;
+//     int m_columnsCount;
+// };
+
+// /**
+//  * 简化的窗口预览组件
+//  */
+// class SimpleWindowPreview : public QLabel {
+//     Q_OBJECT
+
+// public:
+//     explicit SimpleWindowPreview(QWidget* parent = nullptr);
+//     ~SimpleWindowPreview();
+
+//     void setTargetWindow(HWND hwnd, const QString& title = QString());
+//     void startPreview();
+//     void stopPreview();
+//     void setUpdateInterval(int ms);
+
+// protected:
+//     void paintEvent(QPaintEvent* event) override;
+
+// private slots:
+//     void updatePreview();
+//     void checkWindowState();
+
+// private:
+//     QTimer* m_updateTimer;
+//     QTimer* m_stateTimer;
+//     HWND m_targetHwnd;
+//     QString m_windowTitle;
+//     QPixmap m_lastFrame;
+//     bool m_isActive;
+//     bool m_isWindowMinimized;
+// };
+
+// /**
+//  * 简化的屏幕墙主组件
+//  */
+// class SimpleScreenWall : public QWidget {
+//     Q_OBJECT
+
+// public:
+//     explicit SimpleScreenWall(QWidget* parent = nullptr);
+//     ~SimpleScreenWall();
+
+//     void setConfig(const SimpleScreenWallConfig& config);
+//     const SimpleScreenWallConfig& config() const { return m_config; }
+// public slots:
+//     void startScreenWall();
+//     void stopScreenWall();
+//     bool isRunning() const { return m_isRunning; }
+
+//     void refreshWindowList();
+
+// signals:
+//     void windowSelected(HWND hwnd, const QString& title);
+//     void desktopSelected();
+//     void started();
+//     void stopped();
+
+// protected:
+//     void showEvent(QShowEvent* event) override;
+//     void hideEvent(QHideEvent* event) override;
+//     void resizeEvent(QResizeEvent* event) override;
+
+// private slots:
+//     void onWindowSelected(HWND hwnd, const QString& title);
+//     void onDesktopClicked();
+//     void onWindowDoubleClicked(HWND hwnd);
+
+// private:
+//     void setupUI();
+//     void setupConnections();
+//     void updateLayout();
+
+// private:
+//     // UI组件
+//     QVBoxLayout* m_mainLayout;
+//     SimpleDesktopPreview* m_desktopPreview;
+//     SimpleWindowList* m_windowList;
+
+//     // 配置和状态
+//     SimpleScreenWallConfig m_config;
+//     bool m_isRunning;
+//     HWND m_selectedWindow;
+
+//     // 定时器
+//     QTimer* m_refreshTimer;
+// };
+
+// /**
+//  * 简化的屏幕墙主窗口
+//  */
+// class SimpleScreenWallWindow : public QWidget {
+//     Q_OBJECT
+
+// public:
+//     explicit SimpleScreenWallWindow(QWidget* parent = nullptr);
+//     ~SimpleScreenWallWindow();
+
+// protected:
+//     void closeEvent(QCloseEvent* event) override;
+
+// private slots:
+//     void startScreenWall();
+//     void stopScreenWall();
+//     void refreshWindows();
+//     void showSettings();
+//     void showAbout();
+//     void onWindowSelected(HWND hwnd, const QString& title);
+//     void onDesktopSelected();
+//     void onScreenWallStarted();
+//     void onScreenWallStopped();
+
+// private:
+//     void setupUI();
+//     void setupConnections();
+//     void updateControlButtons();
+
+// private:
+//     // UI组件
+//     QVBoxLayout* m_mainLayout;
+//     QWidget* m_controlPanel;
+//     QHBoxLayout* m_controlLayout;
+//     QPushButton* m_startButton;
+//     QPushButton* m_stopButton;
+//     QPushButton* m_refreshButton;
+//     QPushButton* m_settingsButton;
+//     QLabel* m_statusLabel;
+
+//     SimpleScreenWall* m_screenWall;
+// };
+
+// /**
+//  * 缓存管理器
+//  */
+// class SimpleCacheManager {
+// public:
+//     static SimpleCacheManager& instance();
+
+//     void cacheThumbnail(HWND hwnd, const QPixmap& thumbnail);
+//     QPixmap getCachedThumbnail(HWND hwnd) const;
+//     void cacheIcon(HWND hwnd, const QIcon& icon);
+//     QIcon getCachedIcon(HWND hwnd) const;
+
+//     void clearCache();
+//     void setMaxCacheSize(int size);
+
+// private:
+//     SimpleCacheManager() = default;
+
+// private:
+//     QCache<HWND, QPixmap> m_thumbnailCache;
+//     QCache<HWND, QIcon> m_iconCache;
+// };
+
+// /**
+//  * 工具函数
+//  */
+// namespace SimpleScreenWallUtils {
+//     // 窗口操作
+//     bool activateWindow(HWND hwnd);
+//     bool minimizeWindow(HWND hwnd);
+//     bool restoreWindow(HWND hwnd);
+//     bool closeWindow(HWND hwnd);
+
+//     // 图像处理
+//     QPixmap scalePixmap(const QPixmap& pixmap, const QSize& size, Qt::AspectRatioMode mode = Qt::KeepAspectRatio);
+//     QPixmap addBorder(const QPixmap& pixmap, int borderWidth, const QColor& color);
+//     QPixmap addShadow(const QPixmap& pixmap, int shadowSize, const QColor& color);
+
+//     // 系统信息
+//     QString getSystemInfo();
+//     QStringList getRunningProcesses();
+//     int getSystemMemoryUsage();
+//     int getCpuUsage();
+
+//     // 配置管理
+//     void saveConfig(const SimpleScreenWallConfig& config, const QString& filePath = QString());
+//     SimpleScreenWallConfig loadConfig(const QString& filePath = QString());
+// }
+
+// // 内联实现一些简单函数
+// inline bool SimpleScreenWallUtils::activateWindow(HWND hwnd) {
+// #ifdef _WIN32
+//     return SetForegroundWindow(hwnd) && ShowWindow(hwnd, SW_RESTORE);
+// #else
+//     Q_UNUSED(hwnd)
+//     return false;
+// #endif
+// }
+
+// inline bool SimpleScreenWallUtils::minimizeWindow(HWND hwnd) {
+// #ifdef _WIN32
+//     return ShowWindow(hwnd, SW_MINIMIZE);
+// #else
+//     Q_UNUSED(hwnd)
+//     return false;
+// #endif
+// }
+
+// inline bool SimpleScreenWallUtils::restoreWindow(HWND hwnd) {
+// #ifdef _WIN32
+//     return ShowWindow(hwnd, SW_RESTORE);
+// #else
+//     Q_UNUSED(hwnd)
+//     return false;
+// #endif
+// }
+
+// inline bool SimpleScreenWallUtils::closeWindow(HWND hwnd) {
+// #ifdef _WIN32
+//     return PostMessage(hwnd, WM_CLOSE, 0, 0);
+// #else
+//     Q_UNUSED(hwnd)
+//     return false;
+// #endif
+// }

+ 1073 - 0
ScreenWall/screenwall_widget.cpp

@@ -0,0 +1,1073 @@
+// #include "screenwall_widget.h"
+// #include <QApplication>
+// #include <QDebug>
+// #include <QDesktopWidget>
+// #include <QHideEvent>
+// #include <QMessageBox>
+// #include <QMouseEvent>
+// #include <QPainter>
+// #include <QResizeEvent>
+// #include <QShowEvent>
+// #include <QStyle>
+// #include <QStyleOption>
+// #include <QToolTip>
+// #include "qfileinfo.h"
+// #include <dwmapi.h>
+// #include <psapi.h>
+// #include <shellapi.h>
+
+// #pragma comment(lib, "dwmapi.lib")
+// #pragma comment(lib, "shell32.lib")
+// #pragma comment(lib, "psapi.lib")
+
+// // ============================================================================
+// // ScreenWallWidget Implementation
+// // ============================================================================
+
+// ScreenWallWidget::ScreenWallWidget(QWidget* parent)
+//     : QWidget(parent)
+//     , m_mainLayout(nullptr)
+//     , m_desktopPreview(nullptr)
+//     , m_windowList(nullptr)
+//     , m_windowPreview(nullptr)
+//     , m_updateTimer(new QTimer(this))
+//     , m_performanceTimer(new QTimer(this))
+//     , m_isRunning(false)
+//     , m_selectedWindow(nullptr)
+//     , m_activeCaptureCount(0)
+// {
+//     setupUI();
+//     setupConnections();
+
+//     // 设置默认配置
+//     m_config = ScreenWallConfig();
+
+//     setMinimumSize(800, 600);
+//     resize(1200, 900);
+// }
+
+// ScreenWallWidget::~ScreenWallWidget()
+// {
+//     stopScreenWall();
+//     cleanupResources();
+// }
+
+// void ScreenWallWidget::setupUI()
+// {
+//     m_mainLayout = new QVBoxLayout(this);
+//     m_mainLayout->setContentsMargins(5, 5, 5, 5);
+//     m_mainLayout->setSpacing(5);
+
+//     // 桌面预览区域 (30%)
+//     m_desktopPreview = new DesktopPreviewWidget(this);
+//     m_desktopPreview->setMinimumHeight(200);
+//     m_desktopPreview->setStyleSheet("border: 2px solid #3498db; border-radius: 5px;");
+//     m_mainLayout->addWidget(m_desktopPreview, 3);
+
+//     // 窗口图标列表 (20%)
+//     m_windowList = new WindowIconListWidget(this);
+//     m_windowList->setMaximumHeight(180);
+//     m_windowList->setMinimumHeight(120);
+//     m_windowList->setStyleSheet("border: 1px solid #bdc3c7; border-radius: 3px;");
+//     m_mainLayout->addWidget(m_windowList, 2);
+
+//     // 窗口预览区域 (50%)
+//     m_windowPreview = new WindowPreviewWidget(this);
+//     m_windowPreview->setMinimumHeight(300);
+//     m_windowPreview->setStyleSheet("border: 2px solid #e74c3c; border-radius: 5px;");
+//     m_mainLayout->addWidget(m_windowPreview, 5);
+// }
+
+// void ScreenWallWidget::setupConnections()
+// {
+//     // 桌面预览点击
+//     connect(m_desktopPreview, &DesktopPreviewWidget::clicked,
+//             this, &ScreenWallWidget::onDesktopClicked);
+
+//     // 窗口选择
+//     connect(m_windowList, &WindowIconListWidget::windowSelected,
+//             this, &ScreenWallWidget::onWindowSelected);
+
+//     // 定时更新
+//     connect(m_updateTimer, &QTimer::timeout,
+//             this, &ScreenWallWidget::updatePreviews);
+
+//     // 性能优化定时器
+//     connect(m_performanceTimer, &QTimer::timeout,
+//             this, &ScreenWallWidget::optimizePerformance);
+// }
+
+// void ScreenWallWidget::setConfig(const ScreenWallConfig& config)
+// {
+//     m_config = config;
+
+//     if (m_windowList) {
+//         m_windowList->setThumbnailSize(config.thumbnailSize);
+//     }
+
+//     if (m_updateTimer) {
+//         m_updateTimer->setInterval(config.updateInterval);
+//     }
+// }
+
+// void ScreenWallWidget::startScreenWall()
+// {
+//     if (m_isRunning) {
+//         return;
+//     }
+
+//     qDebug() << "Starting ScreenWall...";
+
+//     // 启动桌面预览
+//     m_desktopPreview->startDesktopCapture(m_config.desktopFrameRate);
+
+//     // 刷新窗口列表
+//     refreshWindowList();
+
+//     // 启动定时器
+//     m_updateTimer->start(m_config.updateInterval);
+//     m_performanceTimer->start(5000); // 每5秒优化一次性能
+
+//     m_isRunning = true;
+
+//     qDebug() << "ScreenWall started successfully";
+// }
+
+// void ScreenWallWidget::stopScreenWall()
+// {
+//     if (!m_isRunning) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping ScreenWall...";
+
+//     // 停止定时器
+//     m_updateTimer->stop();
+//     m_performanceTimer->stop();
+
+//     // 停止预览
+//     m_desktopPreview->stopDesktopCapture();
+//     m_windowPreview->stopPreview();
+
+//     // 清理资源
+//     ResourceManager::instance().cleanup();
+
+//     m_isRunning = false;
+//     m_selectedWindow = nullptr;
+
+//     qDebug() << "ScreenWall stopped";
+// }
+
+// void ScreenWallWidget::refreshWindowList()
+// {
+//     if (m_windowList) {
+//         m_windowList->refreshWindowList();
+//     }
+// }
+
+// void ScreenWallWidget::onWindowSelected(HWND hwnd)
+// {
+//     if (m_selectedWindow == hwnd) {
+//         return;
+//     }
+
+//     // 停止之前的预览
+//     if (m_selectedWindow) {
+//         m_windowPreview->stopPreview();
+//         ResourceManager::instance().removeCaptureSession(m_selectedWindow);
+//     }
+
+//     m_selectedWindow = hwnd;
+
+//     if (hwnd && IsWindow(hwnd)) {
+//         // 检查是否可以开始新的捕获
+//         if (ResourceManager::instance().canStartCapture()) {
+//             m_windowPreview->setTargetWindow(hwnd);
+//             m_windowPreview->startPreview(m_config.windowFrameRate);
+//             ResourceManager::instance().addCaptureSession(hwnd);
+
+//             // 获取窗口标题
+//             wchar_t title[256];
+//             GetWindowTextW(hwnd, title, 256);
+//             QString windowTitle = QString::fromWCharArray(title);
+
+//             emit windowSelected(hwnd, windowTitle);
+//         } else {
+//             QMessageBox::warning(this, "资源限制",
+//                                "已达到最大同时捕获数量限制,请先关闭其他预览。");
+//         }
+//     }
+// }
+
+// void ScreenWallWidget::onDesktopClicked()
+// {
+//     // 取消窗口选择,显示桌面
+//     if (m_selectedWindow) {
+//         m_windowPreview->stopPreview();
+//         ResourceManager::instance().removeCaptureSession(m_selectedWindow);
+//         m_selectedWindow = nullptr;
+//     }
+
+//     emit desktopSelected();
+// }
+
+// void ScreenWallWidget::updatePreviews()
+// {
+//     // 刷新窗口列表
+//     refreshWindowList();
+
+//     // 检查选中窗口是否仍然有效
+//     if (m_selectedWindow && !IsWindow(m_selectedWindow)) {
+//         onWindowSelected(nullptr);
+//     }
+// }
+
+// void ScreenWallWidget::optimizePerformance()
+// {
+//     // 根据窗口状态调整帧率
+//     if (m_selectedWindow && IsWindow(m_selectedWindow)) {
+//         bool isMinimized = IsIconic(m_selectedWindow);
+//         bool isVisible = IsWindowVisible(m_selectedWindow);
+
+//         int frameRate = m_config.windowFrameRate;
+//         if (isMinimized) {
+//             frameRate = 1; // 最小化窗口使用极低帧率
+//         } else if (!isVisible) {
+//             frameRate = 5; // 不可见窗口使用低帧率
+//         }
+
+//         // 这里可以调整捕获帧率(需要在VideoRecorder中实现)
+//         // m_windowPreview->setFrameRate(frameRate);
+//     }
+// }
+
+// void ScreenWallWidget::resizeEvent(QResizeEvent* event)
+// {
+//     QWidget::resizeEvent(event);
+
+//     // 调整窗口列表布局
+//     if (m_windowList) {
+//         QTimer::singleShot(100, m_windowList, &WindowIconListWidget::refreshWindowList);
+//     }
+// }
+
+// void ScreenWallWidget::showEvent(QShowEvent* event)
+// {
+//     QWidget::showEvent(event);
+
+//     if (!m_isRunning) {
+//         QTimer::singleShot(500, this, &ScreenWallWidget::startScreenWall);
+//     }
+// }
+
+// void ScreenWallWidget::hideEvent(QHideEvent* event)
+// {
+//     QWidget::hideEvent(event);
+
+//     if (m_isRunning) {
+//         stopScreenWall();
+//     }
+// }
+
+// void ScreenWallWidget::cleanupResources()
+// {
+//     ResourceManager::instance().cleanup();
+// }
+
+// // ============================================================================
+// // DesktopPreviewWidget Implementation
+// // ============================================================================
+
+// DesktopPreviewWidget::DesktopPreviewWidget(QWidget* parent)
+//     : OpenGLVideoWidget(parent)
+//     , m_captureTimer(new QTimer(this))
+//     , m_isCapturing(false)
+//     , m_monitorIndex(0)
+// {
+//     // connect(m_captureTimer, &QTimer::timeout,
+//     //         this, &DesktopPreviewWidget::captureDesktop);
+
+//     // setNoVideoTip("点击开始桌面预览");
+//     setCursor(Qt::PointingHandCursor);
+// }
+
+// DesktopPreviewWidget::~DesktopPreviewWidget()
+// {
+//     stopDesktopCapture();
+// }
+
+// void DesktopPreviewWidget::startDesktopCapture(int frameRate)
+// {
+//     if (m_isCapturing) {
+//         return;
+//     }
+
+//     qDebug() << "Starting desktop capture at" << frameRate << "fps";
+
+//     // 使用主显示器
+//     Encoder<MediaType::VIDEO>::Param videoParam;
+//     videoParam.width = GetSystemMetrics(SM_CXSCREEN);
+//     videoParam.height = GetSystemMetrics(SM_CYSCREEN);
+//     videoParam.fps = frameRate;
+
+//     if (m_desktopRecorder.Open(m_monitorIndex, videoParam, CaptureMethod::WGC)) {
+//         m_captureTimer->start(1000 / frameRate);
+//         m_isCapturing = true;
+//         setNoVideoTip("");
+//     } else {
+//         qWarning() << "Failed to start desktop capture";
+//         setNoVideoTip("桌面捕获失败");
+//     }
+// }
+
+// void ScreenWallWidget::onWindowStateChanged()
+// {
+//     // 处理窗口状态变化
+//     updatePreviews();
+// }
+
+// void DesktopPreviewWidget::stopDesktopCapture()
+// {
+//     if (!m_isCapturing) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping desktop capture";
+
+//     m_captureTimer->stop();
+//     m_desktopRecorder.Close();
+//     m_isCapturing = false;
+
+//     setNoVideoTip("桌面预览已停止");
+// }
+
+// void DesktopPreviewWidget::captureDesktop()
+// {
+//     if (!m_isCapturing) {
+//         return;
+//     }
+
+//     AVFrame* frame = m_desktopRecorder.GetRenderFrame();
+//     if (frame) {
+//         // 异步渲染帧
+//         QMetaObject::invokeMethod(this, "Render", Qt::QueuedConnection,
+//                                 Q_ARG(AVFrame*, av_frame_clone(frame)));
+//     }
+// }
+
+// void DesktopPreviewWidget::mousePressEvent(QMouseEvent* event)
+// {
+//     if (event->button() == Qt::LeftButton) {
+//         emit clicked();
+//     }
+//     OpenGLVideoWidget::mousePressEvent(event);
+// }
+
+// void DesktopPreviewWidget::paintEvent(QPaintEvent* event)
+// {
+//     OpenGLVideoWidget::paintEvent(event);
+
+//     // 绘制边框和状态信息
+//     QPainter painter(this);
+//     painter.setRenderHint(QPainter::Antialiasing);
+
+//     if (m_isCapturing) {
+//         // 绘制录制指示器
+//         painter.setPen(QPen(Qt::red, 2));
+//         painter.setBrush(Qt::red);
+//         painter.drawEllipse(width() - 20, 10, 10, 10);
+
+//         painter.setPen(Qt::white);
+//         painter.drawText(width() - 60, 25, "LIVE");
+//     }
+// }
+
+// // ============================================================================
+// // WindowIconListWidget Implementation
+// // ============================================================================
+
+// WindowIconListWidget::WindowIconListWidget(QWidget* parent)
+//     : QScrollArea(parent)
+//     , m_contentWidget(new QWidget)
+//     , m_layout(new QGridLayout(m_contentWidget))
+//     , m_thumbnailSize(120, 90)
+//     , m_columnsCount(6)
+// {
+//     setWidget(m_contentWidget);
+//     setWidgetResizable(true);
+//     setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+//     setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+//     m_layout->setSpacing(5);
+//     m_layout->setContentsMargins(5, 5, 5, 5);
+
+//     // 设置样式
+//     setStyleSheet(
+//         "QScrollArea { background-color: #f8f9fa; }"
+//         "QWidget { background-color: transparent; }"
+//     );
+// }
+
+// WindowIconListWidget::~WindowIconListWidget()
+// {
+//     clearLayout();
+// }
+
+// void WindowIconListWidget::refreshWindowList()
+// {
+//     qDebug() << "Refreshing window list...";
+
+//     // 获取窗口列表
+//     auto newWindows = EnhancedWindowFinder::GetExtendedList(true);
+
+//     // 检查是否有变化
+//     bool hasChanges = (newWindows.size() != m_windows.size());
+//     if (!hasChanges) {
+//         for (int i = 0; i < newWindows.size(); ++i) {
+//             if (newWindows[i].hwnd != m_windows[i].hwnd) {
+//                 hasChanges = true;
+//                 break;
+//             }
+//         }
+//     }
+
+//     if (hasChanges) {
+//         m_windows = newWindows;
+//         updateLayout();
+//         qDebug() << "Window list updated:" << m_windows.size() << "windows";
+//     }
+// }
+
+// void WindowIconListWidget::setThumbnailSize(const QSize& size)
+// {
+//     if (m_thumbnailSize != size) {
+//         m_thumbnailSize = size;
+//         updateLayout();
+//     }
+// }
+
+// void WindowIconListWidget::updateLayout()
+// {
+//     clearLayout();
+
+//     if (m_windows.isEmpty()) {
+//         return;
+//     }
+
+//     // 计算列数
+//     int availableWidth = viewport()->width() - 20;
+//     m_columnsCount = qMax(1, availableWidth / (m_thumbnailSize.width() + 10));
+
+//     int row = 0, col = 0;
+
+//     for (const auto& window : m_windows) {
+//         auto* iconWidget = createWindowIcon(window);
+//         if (iconWidget) {
+//             m_layout->addWidget(iconWidget, row, col);
+
+//             col++;
+//             if (col >= m_columnsCount) {
+//                 col = 0;
+//                 row++;
+//             }
+//         }
+//     }
+
+//     // 添加弹性空间
+//     m_layout->setRowStretch(row + 1, 1);
+//     m_layout->setColumnStretch(m_columnsCount, 1);
+// }
+
+// QWidget* WindowIconListWidget::createWindowIcon(const WindowInfo& info)
+// {
+//     auto* widget = new QWidget;
+//     widget->setFixedSize(m_thumbnailSize + QSize(10, 30));
+//     widget->setCursor(Qt::PointingHandCursor);
+
+//     auto* layout = new QVBoxLayout(widget);
+//     layout->setContentsMargins(2, 2, 2, 2);
+//     layout->setSpacing(2);
+
+//     // 缩略图
+//     auto* thumbnailLabel = new QLabel;
+//     thumbnailLabel->setFixedSize(m_thumbnailSize);
+//     thumbnailLabel->setScaledContents(true);
+//     thumbnailLabel->setStyleSheet(
+//         "QLabel { "
+//         "  border: 1px solid #bdc3c7; "
+//         "  border-radius: 3px; "
+//         "  background-color: #ecf0f1; "
+//         "}"
+//     );
+
+//     // 设置缩略图
+//     if (!info.thumbnail.isNull()) {
+//         thumbnailLabel->setPixmap(info.thumbnail.scaled(m_thumbnailSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+//     } else {
+//         // 使用图标作为占位符
+//         QPixmap iconPixmap = info.icon.pixmap(64, 64);
+//         thumbnailLabel->setPixmap(iconPixmap);
+//     }
+
+//     layout->addWidget(thumbnailLabel);
+
+//     // 标题
+//     auto* titleLabel = new QLabel(info.title);
+//     titleLabel->setAlignment(Qt::AlignCenter);
+//     titleLabel->setWordWrap(true);
+//     titleLabel->setMaximumHeight(20);
+//     titleLabel->setStyleSheet("font-size: 10px; color: #2c3e50;");
+
+//     // 截断过长的标题
+//     QString displayTitle = info.title;
+//     if (displayTitle.length() > 20) {
+//         displayTitle = displayTitle.left(17) + "...";
+//     }
+//     titleLabel->setText(displayTitle);
+//     titleLabel->setToolTip(info.title);
+
+//     layout->addWidget(titleLabel);
+
+//     // 存储窗口句柄
+//     widget->setProperty("hwnd", reinterpret_cast<qintptr>(info.hwnd));
+
+//     // 连接点击事件
+//     widget->installEventFilter(this);
+
+//     // 最小化窗口的视觉提示
+//     if (info.isMinimized) {
+//         widget->setStyleSheet("QWidget { opacity: 0.7; }");
+//     }
+
+//     return widget;
+// }
+
+// void WindowIconListWidget::clearLayout()
+// {
+//     while (QLayoutItem* item = m_layout->takeAt(0)) {
+//         if (QWidget* widget = item->widget()) {
+//             widget->deleteLater();
+//         }
+//         delete item;
+//     }
+// }
+
+// void WindowIconListWidget::resizeEvent(QResizeEvent* event)
+// {
+//     QScrollArea::resizeEvent(event);
+
+//     // 延迟更新布局,避免频繁重绘
+//     QTimer::singleShot(100, this, &WindowIconListWidget::updateLayout);
+// }
+
+// bool WindowIconListWidget::eventFilter(QObject* obj, QEvent* event)
+// {
+//     if (auto* widget = qobject_cast<QWidget*>(obj)) {
+//         HWND hwnd = reinterpret_cast<HWND>(widget->property("hwnd").value<qintptr>());
+
+//         if (event->type() == QEvent::MouseButtonPress) {
+//             auto* mouseEvent = static_cast<QMouseEvent*>(event);
+//             if (mouseEvent->button() == Qt::LeftButton) {
+//                 emit windowSelected(hwnd);
+//                 return true;
+//             }
+//         } else if (event->type() == QEvent::MouseButtonDblClick) {
+//             emit windowDoubleClicked(hwnd);
+//             return true;
+//         }
+//     }
+
+//     return QScrollArea::eventFilter(obj, event);
+// }
+
+// // ============================================================================
+// // WindowPreviewWidget Implementation
+// // ============================================================================
+
+// WindowPreviewWidget::WindowPreviewWidget(QWidget* parent)
+//     : OpenGLVideoWidget(parent)
+//     , m_captureTimer(new QTimer(this))
+//     , m_stateTimer(new QTimer(this))
+//     , m_targetHwnd(nullptr)
+//     , m_isPreviewActive(false)
+//     , m_isWindowMinimized(false)
+// {
+//     connect(m_captureTimer, &QTimer::timeout,
+//             this, &WindowPreviewWidget::captureWindow);
+
+//     connect(m_stateTimer, &QTimer::timeout,
+//             this, &WindowPreviewWidget::checkWindowState);
+
+//     setNoVideoTip("请选择要预览的窗口");
+// }
+
+// WindowPreviewWidget::~WindowPreviewWidget()
+// {
+//     stopPreview();
+// }
+
+// void WindowPreviewWidget::setTargetWindow(HWND hwnd)
+// {
+//     if (m_targetHwnd == hwnd) {
+//         return;
+//     }
+
+//     stopPreview();
+//     m_targetHwnd = hwnd;
+
+//     if (hwnd && IsWindow(hwnd)) {
+//         // 获取窗口标题
+//         wchar_t title[256];
+//         GetWindowTextW(hwnd, title, 256);
+//         m_windowTitle = QString::fromWCharArray(title);
+
+//         setNoVideoTip(QString("准备预览: %1").arg(m_windowTitle));
+//     } else {
+//         m_windowTitle.clear();
+//         setNoVideoTip("请选择要预览的窗口");
+//     }
+// }
+
+// void WindowPreviewWidget::startPreview(int frameRate)
+// {
+//     if (!m_targetHwnd || !IsWindow(m_targetHwnd) || m_isPreviewActive) {
+//         return;
+//     }
+
+//     qDebug() << "Starting window preview for" << m_windowTitle << "at" << frameRate << "fps";
+
+//     // 配置视频参数
+//     Encoder<MediaType::VIDEO>::Param videoParam;
+//     RECT rect;
+//     GetClientRect(m_targetHwnd, &rect);
+//     videoParam.width = rect.right - rect.left;
+//     videoParam.height = rect.bottom - rect.top;
+//     videoParam.fps = frameRate;
+
+//     if (videoParam.width <= 0 || videoParam.height <= 0) {
+//         qWarning() << "Invalid window size for" << m_windowTitle;
+//         setNoVideoTip("窗口尺寸无效");
+//         return;
+//     }
+
+//     if (m_windowRecorder.Open(m_targetHwnd, videoParam, CaptureMethod::WGC)) {
+//         m_captureTimer->start(1000 / frameRate);
+//         m_stateTimer->start(1000); // 每秒检查窗口状态
+//         m_isPreviewActive = true;
+//         m_isWindowMinimized = IsIconic(m_targetHwnd);
+
+//         setNoVideoTip("");
+//         qDebug() << "Window preview started successfully";
+//     } else {
+//         qWarning() << "Failed to start window preview for" << m_windowTitle;
+//         setNoVideoTip("预览启动失败");
+//     }
+// }
+
+// void WindowPreviewWidget::stopPreview()
+// {
+//     if (!m_isPreviewActive) {
+//         return;
+//     }
+
+//     qDebug() << "Stopping window preview";
+
+//     m_captureTimer->stop();
+//     m_stateTimer->stop();
+//     m_windowRecorder.Close();
+//     m_isPreviewActive = false;
+
+//     if (!m_windowTitle.isEmpty()) {
+//         setNoVideoTip(QString("预览已停止: %1").arg(m_windowTitle));
+//     } else {
+//         setNoVideoTip("请选择要预览的窗口");
+//     }
+// }
+
+// void WindowPreviewWidget::captureWindow()
+// {
+//     if (!m_isPreviewActive || !m_targetHwnd || !IsWindow(m_targetHwnd)) {
+//         return;
+//     }
+
+//     AVFrame* frame = m_windowRecorder.GetRenderFrame();
+//     if (frame) {
+//         // 如果窗口未最小化,保存最后一帧
+//         if (!m_isWindowMinimized) {
+//             // 这里可以将AVFrame转换为QPixmap保存
+//             // m_lastFrame = convertAVFrameToPixmap(frame);
+//         }
+
+//         // 异步渲染帧
+//         QMetaObject::invokeMethod(this, "Render", Qt::QueuedConnection,
+//                                 Q_ARG(AVFrame*, av_frame_clone(frame)));
+//     } else if (m_isWindowMinimized && !m_lastFrame.isNull()) {
+//         // 显示最后一帧
+//         handleMinimizedWindow();
+//     }
+// }
+
+// void WindowPreviewWidget::checkWindowState()
+// {
+//     if (!m_targetHwnd || !IsWindow(m_targetHwnd)) {
+//         stopPreview();
+//         return;
+//     }
+
+//     bool isMinimized = IsIconic(m_targetHwnd);
+//     if (isMinimized != m_isWindowMinimized) {
+//         m_isWindowMinimized = isMinimized;
+
+//         if (isMinimized) {
+//             handleMinimizedWindow();
+//         } else {
+//             handleRestoredWindow();
+//         }
+//     }
+// }
+
+// void WindowPreviewWidget::handleMinimizedWindow()
+// {
+//     qDebug() << "Window minimized:" << m_windowTitle;
+
+//     if (!m_lastFrame.isNull()) {
+//         // 显示最后一帧的静态图像
+//         // 这里需要实现将QPixmap显示在OpenGL组件上的功能
+//         setNoVideoTip(QString("窗口已最小化: %1\n(显示最后画面)").arg(m_windowTitle));
+//     } else {
+//         setNoVideoTip(QString("窗口已最小化: %1").arg(m_windowTitle));
+//     }
+// }
+
+// void WindowPreviewWidget::handleRestoredWindow()
+// {
+//     qDebug() << "Window restored:" << m_windowTitle;
+//     setNoVideoTip("");
+// }
+
+// void WindowPreviewWidget::setLastFrame(const QPixmap& frame)
+// {
+//     m_lastFrame = frame;
+// }
+
+// void WindowPreviewWidget::paintEvent(QPaintEvent* event)
+// {
+//     OpenGLVideoWidget::paintEvent(event);
+
+//     // 绘制窗口信息
+//     if (!m_windowTitle.isEmpty()) {
+//         QPainter painter(this);
+//         painter.setRenderHint(QPainter::Antialiasing);
+
+//         // 绘制窗口标题
+//         painter.setPen(Qt::white);
+//         painter.drawText(10, height() - 10, m_windowTitle);
+
+//         // 绘制状态指示器
+//         if (m_isPreviewActive) {
+//             painter.setPen(QPen(Qt::green, 2));
+//             painter.setBrush(Qt::green);
+//             painter.drawEllipse(width() - 20, 10, 10, 10);
+//         }
+
+//         if (m_isWindowMinimized) {
+//             painter.setPen(Qt::yellow);
+//             painter.drawText(width() - 100, 25, "MINIMIZED");
+//         }
+//     }
+// }
+
+// // ============================================================================
+// // EnhancedWindowFinder Implementation
+// // ============================================================================
+
+// QVector<EnhancedWindowFinder::ExtendedInfo> EnhancedWindowFinder::GetExtendedList(bool includeMinimized)
+// {
+//     QVector<ExtendedInfo> result;
+
+//     // 获取基本窗口列表
+//     const auto& basicList = WindowFinder::GetList(true);
+
+//     for (const auto& basic : basicList) {
+//         if (!IsWindow(basic.hwnd)) {
+//             continue;
+//         }
+
+//         bool isMinimized = IsWindowMinimized(basic.hwnd);
+//         if (!includeMinimized && isMinimized) {
+//             continue;
+//         }
+
+//         ExtendedInfo info;
+//         info.hwnd = basic.hwnd;
+//         info.title = "";
+//         //basic.title;
+//         info.isMinimized = isMinimized;
+//         info.isVisible = IsWindowVisible(basic.hwnd);
+//         info.rect = GetWindowRect(basic.hwnd);
+//         info.processId = GetProcessId(basic.hwnd);
+//         info.processName = GetProcessName(basic.hwnd);
+//         info.icon = GetWindowIcon(basic.hwnd);
+
+//         // 获取缩略图(可选,比较耗时)
+//         if (!isMinimized && info.isVisible) {
+//             info.thumbnail = ResourceManager::instance().getCachedThumbnail(basic.hwnd);
+//             if (info.thumbnail.isNull()) {
+//                 info.thumbnail = GetWindowThumbnail(basic.hwnd);
+//                 if (!info.thumbnail.isNull()) {
+//                     ResourceManager::instance().cacheThumbnail(basic.hwnd, info.thumbnail);
+//                 }
+//             }
+//         }
+
+//         result.append(info);
+//     }
+
+//     return result;
+// }
+
+// QIcon EnhancedWindowFinder::GetWindowIcon(HWND hwnd)
+// {
+//     HICON hIcon = GetWindowIconHandle(hwnd);
+//     if (hIcon) {
+//         // Qt5兼容的HICON转换
+//         QPixmap pixmap;
+//         ICONINFO iconInfo;
+//         if (GetIconInfo(hIcon, &iconInfo)) {
+//             // 获取位图信息
+//             BITMAP bmp;
+//             if (GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmp)) {
+//                 // 创建设备上下文
+//                 HDC hdc = CreateCompatibleDC(NULL);
+//                 if (hdc) {
+//                     // 准备位图信息头
+//                     BITMAPINFOHEADER bih = {0};
+//                     bih.biSize = sizeof(BITMAPINFOHEADER);
+//                     bih.biWidth = bmp.bmWidth;
+//                     bih.biHeight = -bmp.bmHeight;
+//                     bih.biPlanes = 1;
+//                     bih.biBitCount = 32;
+//                     bih.biCompression = BI_RGB;
+
+//                     // 分配内存
+//                     int dataSize = bmp.bmWidth * bmp.bmHeight * 4;
+//                     uchar* data = new uchar[dataSize];
+
+//                     // 获取位图数据
+//                     BITMAPINFO bi = {0};
+//                     bi.bmiHeader = bih;
+
+//                     if (GetDIBits(hdc, iconInfo.hbmColor, 0, bmp.bmHeight, data, &bi, DIB_RGB_COLORS)) {
+//                         // 创建QImage
+//                         QImage image(data, bmp.bmWidth, bmp.bmHeight, QImage::Format_ARGB32);
+//                         pixmap = QPixmap::fromImage(image.rgbSwapped());
+//                     }
+
+//                     delete[] data;
+//                     DeleteDC(hdc);
+//                 }
+//             }
+
+//             // 清理资源
+//             if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
+//             if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
+//         }
+
+//         DestroyIcon(hIcon);
+
+//         if (!pixmap.isNull()) {
+//             return QIcon(pixmap);
+//         }
+//     }
+
+//     // 使用默认图标
+//     return QApplication::style()->standardIcon(QStyle::SP_ComputerIcon);
+// }
+
+// HICON EnhancedWindowFinder::GetWindowIconHandle(HWND hwnd)
+// {
+//     // 尝试多种方式获取图标
+//     HICON hIcon = nullptr;
+
+//     // 方法1: 发送消息获取大图标
+//     hIcon = reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));
+//     if (hIcon) return hIcon;
+
+//     // 方法2: 发送消息获取小图标
+//     hIcon = reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
+//     if (hIcon) return hIcon;
+
+//     // 方法3: 从窗口类获取图标
+//     hIcon = reinterpret_cast<HICON>(GetClassLongPtr(hwnd, GCLP_HICON));
+//     if (hIcon) return hIcon;
+
+//     // 方法4: 从窗口类获取小图标
+//     hIcon = reinterpret_cast<HICON>(GetClassLongPtr(hwnd, GCLP_HICONSM));
+//     if (hIcon) return hIcon;
+
+//     return nullptr;
+// }
+
+// QPixmap EnhancedWindowFinder::GetWindowThumbnail(HWND hwnd, const QSize& size)
+// {
+//     return CaptureWindow(hwnd, size);
+// }
+
+// QPixmap EnhancedWindowFinder::CaptureWindow(HWND hwnd, const QSize& size)
+// {
+//     if (!IsWindow(hwnd) || !IsWindowVisible(hwnd)) {
+//         return QPixmap();
+//     }
+
+//     RECT rect;
+//     ::GetWindowRect(hwnd, &rect);
+//     int width = rect.right - rect.left;
+//     int height = rect.bottom - rect.top;
+
+//     if (width <= 0 || height <= 0) {
+//         return QPixmap();
+//     }
+
+//     // 使用PrintWindow API捕获窗口
+//     HDC hdcWindow = GetDC(hwnd);
+//     HDC hdcMemDC = CreateCompatibleDC(hdcWindow);
+//     HBITMAP hbmScreen = CreateCompatibleBitmap(hdcWindow, width, height);
+//     SelectObject(hdcMemDC, hbmScreen);
+
+//     // 尝试使用PrintWindow
+//     BOOL result = PrintWindow(hwnd, hdcMemDC, PW_CLIENTONLY);
+//     if (!result) {
+//         // 如果PrintWindow失败,尝试BitBlt
+//         BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
+//     }
+
+//     // 转换为QPixmap (Qt5兼容)
+//     QPixmap pixmap;
+
+//     // 获取位图信息
+//     BITMAP bmp;
+//     if (GetObject(hbmScreen, sizeof(BITMAP), &bmp)) {
+//         // 创建设备上下文
+//         HDC hdc = CreateCompatibleDC(NULL);
+//         if (hdc) {
+//             // 准备位图信息头
+//             BITMAPINFOHEADER bih = {0};
+//             bih.biSize = sizeof(BITMAPINFOHEADER);
+//             bih.biWidth = bmp.bmWidth;
+//             bih.biHeight = -bmp.bmHeight; // 负值表示自上而下
+//             bih.biPlanes = 1;
+//             bih.biBitCount = 32;
+//             bih.biCompression = BI_RGB;
+
+//             // 分配内存
+//             int dataSize = bmp.bmWidth * bmp.bmHeight * 4;
+//             uchar* data = new uchar[dataSize];
+
+//             // 获取位图数据
+//             BITMAPINFO bi = {0};
+//             bi.bmiHeader = bih;
+
+//             if (GetDIBits(hdc, hbmScreen, 0, bmp.bmHeight, data, &bi, DIB_RGB_COLORS)) {
+//                 // 创建QImage
+//                 QImage image(data, bmp.bmWidth, bmp.bmHeight, QImage::Format_ARGB32);
+//                 pixmap = QPixmap::fromImage(image.rgbSwapped());
+//             }
+
+//             delete[] data;
+//             DeleteDC(hdc);
+//         }
+//     }
+
+//     // 清理资源
+//     DeleteObject(hbmScreen);
+//     DeleteDC(hdcMemDC);
+//     ReleaseDC(hwnd, hdcWindow);
+
+//     // 缩放到指定尺寸
+//     if (!pixmap.isNull() && !size.isEmpty()) {
+//         pixmap = pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+//     }
+
+//     return pixmap;
+// }
+
+// bool EnhancedWindowFinder::IsWindowMinimized(HWND hwnd)
+// {
+//     return IsIconic(hwnd);
+// }
+
+// QString EnhancedWindowFinder::GetProcessName(HWND hwnd)
+// {
+//     DWORD processId = GetProcessId(hwnd);
+//     HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
+//     if (!hProcess) {
+//         return QString();
+//     }
+
+//     wchar_t processName[MAX_PATH];
+//     DWORD size = MAX_PATH;
+//     if (QueryFullProcessImageNameW(hProcess, 0, processName, &size)) {
+//         CloseHandle(hProcess);
+//         QString fullPath = QString::fromWCharArray(processName);
+//         return QFileInfo(fullPath).baseName();
+//     }
+
+//     CloseHandle(hProcess);
+//     return QString();
+// }
+
+// DWORD EnhancedWindowFinder::GetProcessId(HWND hwnd)
+// {
+//     DWORD processId = 0;
+//     GetWindowThreadProcessId(hwnd, &processId);
+//     return processId;
+// }
+
+// RECT EnhancedWindowFinder::GetWindowRect(HWND hwnd)
+// {
+//     RECT rect = {0};
+//     ::GetWindowRect(hwnd, &rect);
+//     return rect;
+// }
+
+// // ============================================================================
+// // ResourceManager Implementation
+// // ============================================================================
+
+// ResourceManager& ResourceManager::instance()
+// {
+//     static ResourceManager instance;
+//     return instance;
+// }
+
+// bool ResourceManager::canStartCapture() const
+// {
+//     return m_activeSessions.size() < MAX_CONCURRENT_CAPTURES;
+// }
+
+// void ResourceManager::addCaptureSession(HWND hwnd)
+// {
+//     m_activeSessions.insert(hwnd);
+// }
+
+// void ResourceManager::removeCaptureSession(HWND hwnd)
+// {
+//     m_activeSessions.remove(hwnd);
+// }
+
+// void ResourceManager::cacheThumbnail(HWND hwnd, const QPixmap& thumbnail)
+// {
+//     m_thumbnailCache.insert(hwnd, new QPixmap(thumbnail));
+// }
+
+// QPixmap ResourceManager::getCachedThumbnail(HWND hwnd) const
+// {
+//     QPixmap* cached = m_thumbnailCache.object(hwnd);
+//     return cached ? *cached : QPixmap();
+// }
+
+// void ResourceManager::cleanup()
+// {
+//     m_activeSessions.clear();
+//     m_thumbnailCache.clear();
+// }

+ 273 - 0
ScreenWall/screenwall_widget.h

@@ -0,0 +1,273 @@
+// #ifndef SCREENWALL_WIDGET_H
+// #define SCREENWALL_WIDGET_H
+
+// #include <QWidget>
+// #include <QVBoxLayout>
+// #include <QHBoxLayout>
+// #include <QGridLayout>
+// #include <QScrollArea>
+// #include <QLabel>
+// #include <QPushButton>
+// #include <QTimer>
+// #include <QPixmap>
+// #include <QIcon>
+// #include <QCache>
+// #include <QMap>
+// #include <QVector>
+// #include <Windows.h>
+
+// #include "../AvRecorder/ui/opengl_video_widget.h"
+// #include "../AvRecorder/recorder/video_recorder.h"
+// #include "../AvRecorder/capturer/finder.h"
+
+// class DesktopPreviewWidget;
+// class WindowIconListWidget;
+// class WindowPreviewWidget;
+// class EnhancedWindowFinder;
+
+// /**
+//  * 屏幕墙主组件
+//  * 提供桌面预览、窗口列表和实时窗口预览功能
+//  */
+// class ScreenWallWidget : public QWidget
+// {
+//     Q_OBJECT
+
+// public:
+//     struct ScreenWallConfig {
+//         int desktopFrameRate = 15;          // 桌面预览帧率
+//         int windowFrameRate = 30;           // 窗口预览帧率
+//         QSize thumbnailSize = QSize(200, 150); // 缩略图尺寸
+//         int maxConcurrentCaptures = 6;      // 最大同时捕获数
+//         bool enableMinimizedPreview = true; // 启用最小化窗口预览
+//         int updateInterval = 1000;          // 窗口列表更新间隔(ms)
+//     };
+
+//     explicit ScreenWallWidget(QWidget* parent = nullptr);
+//     ~ScreenWallWidget();
+
+//     void setConfig(const ScreenWallConfig& config);
+//     void startScreenWall();
+//     void stopScreenWall();
+//     bool isRunning() const { return m_isRunning; }
+
+// public slots:
+//     void refreshWindowList();
+//     void onWindowSelected(HWND hwnd);
+//     void onDesktopClicked();
+
+// signals:
+//     void windowSelected(HWND hwnd, const QString& title);
+//     void desktopSelected();
+
+// protected:
+//     void resizeEvent(QResizeEvent* event) override;
+//     void showEvent(QShowEvent* event) override;
+//     void hideEvent(QHideEvent* event) override;
+
+// private slots:
+//     void updatePreviews();
+//     void onWindowStateChanged();
+
+// private:
+//     void setupUI();
+//     void setupConnections();
+//     void optimizePerformance();
+//     void cleanupResources();
+
+//     // UI组件
+//     QVBoxLayout* m_mainLayout;
+//     DesktopPreviewWidget* m_desktopPreview;
+//     WindowIconListWidget* m_windowList;
+//     WindowPreviewWidget* m_windowPreview;
+
+//     // 控制组件
+//     QTimer* m_updateTimer;
+//     QTimer* m_performanceTimer;
+
+//     // 配置和状态
+//     ScreenWallConfig m_config;
+//     bool m_isRunning;
+//     HWND m_selectedWindow;
+//     int m_activeCaptureCount;
+// };
+
+// /**
+//  * 桌面预览组件
+//  * 显示整个桌面的实时预览
+//  */
+// class DesktopPreviewWidget : public OpenGLVideoWidget
+// {
+//     Q_OBJECT
+
+// public:
+//     explicit DesktopPreviewWidget(QWidget* parent = nullptr);
+//     ~DesktopPreviewWidget();
+
+//     void startDesktopCapture(int frameRate = 15);
+//     void stopDesktopCapture();
+//     bool isCapturing() const { return m_isCapturing; }
+
+// protected:
+//     void mousePressEvent(QMouseEvent* event) override;
+//     void paintEvent(QPaintEvent* event) override;
+
+// signals:
+//     void clicked();
+
+// private slots:
+//     void captureDesktop();
+
+// private:
+//     VideoRecorder m_desktopRecorder;
+//     QTimer* m_captureTimer;
+//     bool m_isCapturing;
+//     int m_monitorIndex;
+// };
+
+// /**
+//  * 窗口图标列表组件
+//  * 显示所有可用窗口的图标和标题
+//  */
+// class WindowIconListWidget : public QScrollArea
+// {
+//     Q_OBJECT
+
+// public:
+//     struct WindowInfo {
+//         HWND hwnd;
+//         QString title;
+//         QString processName;
+//         QIcon icon;
+//         QPixmap thumbnail;
+//         bool isMinimized;
+//         bool isVisible;
+//         RECT rect;
+//         DWORD processId;
+//     };
+
+//     explicit WindowIconListWidget(QWidget* parent = nullptr);
+//     ~WindowIconListWidget();
+
+//     void refreshWindowList();
+//     void setThumbnailSize(const QSize& size);
+//     QVector<WindowInfo> getWindowList() const { return m_windows; }
+
+// signals:
+//     void windowSelected(HWND hwnd);
+//     void windowDoubleClicked(HWND hwnd);
+
+// protected:
+//     void resizeEvent(QResizeEvent* event) override;
+//     bool eventFilter(QObject* obj, QEvent* event) override;
+// private slots:
+//     void onWindowClicked() {}
+//     void onWindowDoubleClicked() {}
+
+// private:
+//     void setupLayout();
+//     void clearLayout();
+//     QWidget* createWindowIcon(const WindowInfo& info);
+//     void updateLayout();
+
+//     QWidget* m_contentWidget;
+//     QGridLayout* m_layout;
+//     QVector<WindowInfo> m_windows;
+//     QSize m_thumbnailSize;
+//     int m_columnsCount;
+// };
+
+// /**
+//  * 窗口实时预览组件
+//  * 显示选中窗口的实时内容
+//  */
+// class WindowPreviewWidget : public OpenGLVideoWidget
+// {
+//     Q_OBJECT
+
+// public:
+//     explicit WindowPreviewWidget(QWidget* parent = nullptr);
+//     ~WindowPreviewWidget();
+
+//     void setTargetWindow(HWND hwnd);
+//     void startPreview(int frameRate = 30);
+//     void stopPreview();
+//     bool isPreviewActive() const { return m_isPreviewActive; }
+
+//     // 最小化窗口支持
+//     void setLastFrame(const QPixmap& frame);
+//     QPixmap getLastFrame() const { return m_lastFrame; }
+
+// protected:
+//     void paintEvent(QPaintEvent* event) override;
+
+// private slots:
+//     void captureWindow();
+//     void checkWindowState();
+
+// private:
+//     void handleMinimizedWindow();
+//     void handleRestoredWindow();
+
+//     VideoRecorder m_windowRecorder;
+//     QTimer* m_captureTimer;
+//     QTimer* m_stateTimer;
+
+//     HWND m_targetHwnd;
+//     bool m_isPreviewActive;
+//     bool m_isWindowMinimized;
+//     QPixmap m_lastFrame;
+//     QString m_windowTitle;
+// };
+
+// /**
+//  * 增强的窗口查找器
+//  * 扩展现有WindowFinder功能,增加图标和缩略图获取
+//  */
+// class EnhancedWindowFinder : public WindowFinder
+// {
+// public:
+//     using ExtendedInfo = WindowIconListWidget::WindowInfo;
+
+//     static QVector<ExtendedInfo> GetExtendedList(bool includeMinimized = true);
+//     static QIcon GetWindowIcon(HWND hwnd);
+//     static QPixmap GetWindowThumbnail(HWND hwnd, const QSize& size = QSize(200, 150));
+//     static bool IsWindowMinimized(HWND hwnd);
+//     static QString GetProcessName(HWND hwnd);
+//     static DWORD GetProcessId(HWND hwnd);
+//     static RECT GetWindowRect(HWND hwnd);
+
+// private:
+//     static QPixmap CaptureWindow(HWND hwnd, const QSize& size);
+//     static HICON GetWindowIconHandle(HWND hwnd);
+// };
+
+// /**
+//  * 资源管理器
+//  * 管理捕获会话和内存使用
+//  */
+// class ResourceManager
+// {
+// public:
+//     static ResourceManager& instance();
+
+//     bool canStartCapture() const;
+//     void addCaptureSession(HWND hwnd);
+//     void removeCaptureSession(HWND hwnd);
+
+//     void cacheThumbnail(HWND hwnd, const QPixmap& thumbnail);
+//     QPixmap getCachedThumbnail(HWND hwnd) const;
+
+//     void cleanup();
+
+// private:
+//     ResourceManager() = default;
+
+//     static const int MAX_CONCURRENT_CAPTURES = 6;
+//     static const int MAX_THUMBNAIL_CACHE = 50;
+
+//     QSet<HWND> m_activeSessions;
+//     QCache<HWND, QPixmap> m_thumbnailCache;
+// };
+
+// #endif // SCREENWALL_WIDGET_H

+ 24 - 0
api/xmake.lua

@@ -0,0 +1,24 @@
+-- API 模块配置
+-- 此文件被主项目通过 includes("api") 引入
+
+-- API 库
+target("api_lib")
+    add_rules("qt.shared")
+    set_kind("static")
+    
+    -- 所有源文件
+    add_files("*.h", {rules = "qt.moc"})
+    add_files("*.cpp")
+    add_headerfiles("*.h")
+    
+    -- 包含目录
+    add_includedirs(".", {public = true})
+    add_includedirs("..", {public = true})
+
+    add_deps("jsonserializer")
+    -- Windows 特定链接库
+    if is_plat("windows") then
+        add_syslinks("user32", "gdi32", "ole32")
+    end
+    add_frameworks("QtCore", "QtGui", "QtWidgets", "QtNetwork", "QtMultimedia")
+target_end()

BIN
bin/2025-08-26-21-44-41.mp4


BIN
bin/LearningSmartClient.exe


BIN
bin/LearningSmartClient.exp


BIN
bin/LearningSmartClient.lib


BIN
bin/LearningSmartClient.pdb


BIN
bin/bin_0.1.2.7z


BIN
bin/bin_0.1.3.7z


BIN
bin/bin_0.2.1.7z


BIN
bin/bin_0.3.1.7z


+ 0 - 0
AvPlayer2/AvPlayer2.pri → libs/AVPlayer2/AvPlayer2.pri


+ 0 - 0
AvPlayer2/PlayWidget.cpp → libs/AVPlayer2/PlayWidget.cpp


+ 0 - 0
AvPlayer2/PlayWidget.h → libs/AVPlayer2/PlayWidget.h


+ 0 - 0
AvPlayer2/ThreadBase.h → libs/AVPlayer2/ThreadBase.h


+ 0 - 0
AvPlayer2/Visual Leak Detector/AUTHORS.txt → libs/AVPlayer2/Visual Leak Detector/AUTHORS.txt


+ 0 - 0
AvPlayer2/Visual Leak Detector/CHANGES.txt → libs/AVPlayer2/Visual Leak Detector/CHANGES.txt


+ 0 - 0
AvPlayer2/Visual Leak Detector/COPYING.txt → libs/AVPlayer2/Visual Leak Detector/COPYING.txt


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win32/Microsoft.DTfW.DHL.manifest → libs/AVPlayer2/Visual Leak Detector/bin/Win32/Microsoft.DTfW.DHL.manifest


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win32/dbghelp.dll → libs/AVPlayer2/Visual Leak Detector/bin/Win32/dbghelp.dll


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win32/vld_x86.dll → libs/AVPlayer2/Visual Leak Detector/bin/Win32/vld_x86.dll


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win64/Microsoft.DTfW.DHL.manifest → libs/AVPlayer2/Visual Leak Detector/bin/Win64/Microsoft.DTfW.DHL.manifest


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win64/dbghelp.dll → libs/AVPlayer2/Visual Leak Detector/bin/Win64/dbghelp.dll


+ 0 - 0
AvPlayer2/Visual Leak Detector/bin/Win64/vld_x64.dll → libs/AVPlayer2/Visual Leak Detector/bin/Win64/vld_x64.dll


+ 0 - 0
AvPlayer2/Visual Leak Detector/include/vld.h → libs/AVPlayer2/Visual Leak Detector/include/vld.h


+ 0 - 0
AvPlayer2/Visual Leak Detector/include/vld_def.h → libs/AVPlayer2/Visual Leak Detector/include/vld_def.h


+ 0 - 0
AvPlayer2/Visual Leak Detector/lib/Win32/vld.lib → libs/AVPlayer2/Visual Leak Detector/lib/Win32/vld.lib


+ 0 - 0
AvPlayer2/Visual Leak Detector/lib/Win64/vld.lib → libs/AVPlayer2/Visual Leak Detector/lib/Win64/vld.lib


+ 0 - 0
AvPlayer2/Visual Leak Detector/unins000.dat → libs/AVPlayer2/Visual Leak Detector/unins000.dat


+ 0 - 0
AvPlayer2/Visual Leak Detector/unins000.exe → libs/AVPlayer2/Visual Leak Detector/unins000.exe


+ 0 - 0
AvPlayer2/Visual Leak Detector/vld.ini → libs/AVPlayer2/Visual Leak Detector/vld.ini


+ 0 - 0
AvPlayer2/app_settings.cpp → libs/AVPlayer2/app_settings.cpp


+ 0 - 0
AvPlayer2/app_settings.h → libs/AVPlayer2/app_settings.h


+ 0 - 0
AvPlayer2/audio_decode_thread.cpp → libs/AVPlayer2/audio_decode_thread.cpp


+ 0 - 0
AvPlayer2/audio_decode_thread.h → libs/AVPlayer2/audio_decode_thread.h


+ 0 - 0
AvPlayer2/audio_effect_gl.cpp → libs/AVPlayer2/audio_effect_gl.cpp


+ 0 - 0
AvPlayer2/audio_effect_gl.h → libs/AVPlayer2/audio_effect_gl.h


+ 0 - 0
AvPlayer2/audio_effect_helper.cpp → libs/AVPlayer2/audio_effect_helper.cpp


+ 0 - 0
AvPlayer2/audio_effect_helper.h → libs/AVPlayer2/audio_effect_helper.h


+ 3 - 1
AvPlayer2/audio_play_thread.cpp → libs/AVPlayer2/audio_play_thread.cpp

@@ -1,5 +1,7 @@
 #include "audio_play_thread.h"
-#include "AVPlayer2/playercontroller.h"
+
+#include "playercontroller.h"
+
 #include <utility>
 #include <QLoggingCategory>
 Q_LOGGING_CATEGORY(playerControllerAudioPlayThread, "player.controller.AudioPlayThread")

+ 0 - 0
AvPlayer2/audio_play_thread.h → libs/AVPlayer2/audio_play_thread.h


+ 0 - 0
AvPlayer2/clickable_slider.cpp → libs/AVPlayer2/clickable_slider.cpp


+ 0 - 0
AvPlayer2/clickable_slider.h → libs/AVPlayer2/clickable_slider.h


+ 0 - 0
AvPlayer2/common.cpp → libs/AVPlayer2/common.cpp


+ 0 - 0
AvPlayer2/common.h → libs/AVPlayer2/common.h


+ 0 - 0
AvPlayer2/ffmpeg_init.cpp → libs/AVPlayer2/ffmpeg_init.cpp


+ 0 - 0
AvPlayer2/ffmpeg_init.h → libs/AVPlayer2/ffmpeg_init.h


+ 0 - 0
AvPlayer2/log.cpp → libs/AVPlayer2/log.cpp


+ 0 - 0
AvPlayer2/log.h → libs/AVPlayer2/log.h


+ 0 - 0
AvPlayer2/mainwindowa.cpp → libs/AVPlayer2/mainwindowa.cpp


+ 1 - 1
AvPlayer2/mainwindowa.h → libs/AVPlayer2/mainwindowa.h

@@ -16,11 +16,11 @@
 #include <QThread>
 #include <QTimer>
 
-#include "AVPlayer2/playercontroller.h"
 #include "app_settings.h"
 #include "audio_effect_gl.h"
 #include "network_url_dlg.h"
 #include "play_control_window.h"
+#include "playercontroller.h"
 #include "playlist_window.h"
 // #include "read_thread.h"
 // #include "start_play_thread.h"

+ 0 - 0
AvPlayer2/network_url_dlg.cpp → libs/AVPlayer2/network_url_dlg.cpp


+ 0 - 0
AvPlayer2/network_url_dlg.h → libs/AVPlayer2/network_url_dlg.h


+ 0 - 0
AvPlayer2/network_url_dlg.ui → libs/AVPlayer2/network_url_dlg.ui


+ 0 - 0
AvPlayer2/packets_sync.cpp → libs/AVPlayer2/packets_sync.cpp


+ 1 - 1
AvPlayer2/packets_sync.h → libs/AVPlayer2/packets_sync.h

@@ -5,7 +5,7 @@
 #include <QMutex>
 #include <QThread>
 #include <QWaitCondition>
-#include "AVPlayer2/ThreadBase.h"
+#include "ThreadBase.h"
 
 // only need to open audio filter, video will be synced
 #define USE_AVFILTER_AUDIO 1

+ 0 - 0
AvPlayer2/play_control_window.cpp → libs/AVPlayer2/play_control_window.cpp


+ 0 - 0
AvPlayer2/play_control_window.h → libs/AVPlayer2/play_control_window.h


+ 0 - 0
AvPlayer2/playercontroller.cpp → libs/AVPlayer2/playercontroller.cpp


+ 3 - 1
AvPlayer2/playercontroller.h → libs/AVPlayer2/playercontroller.h

@@ -14,8 +14,10 @@
 #include <memory>
 #include <unordered_map>
 
+#include "audio_play_thread.h"
+
 #include <QLoggingCategory>
-#include "AVPlayer2/audio_play_thread.h"
+
 Q_DECLARE_LOGGING_CATEGORY(playerControllerLog)
 
 // 前置声明

+ 0 - 0
AvPlayer2/playlist_window.cpp → libs/AVPlayer2/playlist_window.cpp


+ 0 - 0
AvPlayer2/playlist_window.h → libs/AVPlayer2/playlist_window.h


+ 0 - 0
AvPlayer2/playlist_window.ui → libs/AVPlayer2/playlist_window.ui


+ 0 - 0
AvPlayer2/qimage_operation.cpp → libs/AVPlayer2/qimage_operation.cpp


+ 0 - 0
AvPlayer2/qimage_operation.h → libs/AVPlayer2/qimage_operation.h


+ 0 - 0
AvPlayer2/qmake_qmake_qm_files.qrc → libs/AVPlayer2/qmake_qmake_qm_files.qrc


+ 0 - 0
AvPlayer2/read_thread.cpp → libs/AVPlayer2/read_thread.cpp


+ 0 - 0
AvPlayer2/read_thread.h → libs/AVPlayer2/read_thread.h


+ 0 - 0
AvPlayer2/res/QSS-master.zip → libs/AVPlayer2/res/QSS-master.zip


+ 0 - 0
AvPlayer2/res/QSS/AMOLED.qss → libs/AVPlayer2/res/QSS/AMOLED.qss


+ 0 - 0
AvPlayer2/res/QSS/Aqua.qss → libs/AVPlayer2/res/QSS/Aqua.qss


+ 0 - 0
AvPlayer2/res/QSS/ConsoleStyle.qss → libs/AVPlayer2/res/QSS/ConsoleStyle.qss


+ 0 - 0
AvPlayer2/res/QSS/ElegantDark.qss → libs/AVPlayer2/res/QSS/ElegantDark.qss


+ 0 - 0
AvPlayer2/res/QSS/LICENSE → libs/AVPlayer2/res/QSS/LICENSE


+ 0 - 0
AvPlayer2/res/QSS/MacOS.qss → libs/AVPlayer2/res/QSS/MacOS.qss


+ 0 - 0
AvPlayer2/res/QSS/ManjaroMix.qss → libs/AVPlayer2/res/QSS/ManjaroMix.qss


+ 0 - 0
AvPlayer2/res/QSS/MaterialDark.qss → libs/AVPlayer2/res/QSS/MaterialDark.qss


+ 0 - 0
AvPlayer2/res/QSS/NeonButtons.qss → libs/AVPlayer2/res/QSS/NeonButtons.qss


+ 0 - 0
AvPlayer2/res/QSS/QSS_IMG/go-down-symbolic.symbolic.png → libs/AVPlayer2/res/QSS/QSS_IMG/go-down-symbolic.symbolic.png


+ 0 - 0
AvPlayer2/res/QSS/QSS_IMG/go-next-symbolic.symbolic.png → libs/AVPlayer2/res/QSS/QSS_IMG/go-next-symbolic.symbolic.png


+ 0 - 0
AvPlayer2/res/QSS/QSS_IMG/go-previous-symbolic.symbolic.png → libs/AVPlayer2/res/QSS/QSS_IMG/go-previous-symbolic.symbolic.png


+ 0 - 0
AvPlayer2/res/QSS/QSS_IMG/go-up-symbolic.symbolic.png → libs/AVPlayer2/res/QSS/QSS_IMG/go-up-symbolic.symbolic.png


Някои файлове не бяха показани, защото твърде много файлове са промени