From 75414fe1c820d421c4493c6bbe251f33aeb65bce Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 3 Jan 2017 00:22:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A1=8C=E9=9D=A2=E9=81=AE?= =?UTF-8?q?=E6=8C=A1=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CustomDesktop/CDAPI.cpp | 1 + CustomDesktop/CDEvents.cpp | 4 + CustomDesktop/CheckCovered.cpp | 92 +++++++++++++++++++++ CustomDesktop/CheckCovered.h | 33 ++++++++ CustomDesktop/CustomDesktop.vcxproj | 2 + CustomDesktop/CustomDesktop.vcxproj.filters | 6 ++ CustomDesktop/PluginManager.cpp | 7 +- CustomDesktop/dllmain.cpp | 8 +- Include/CDEvents.h | 2 + Plugin/VideoDesktop/VideoDesktop.cpp | 2 + 10 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 CustomDesktop/CheckCovered.cpp create mode 100644 CustomDesktop/CheckCovered.h diff --git a/CustomDesktop/CDAPI.cpp b/CustomDesktop/CDAPI.cpp index c1d058e..e90f521 100644 --- a/CustomDesktop/CDAPI.cpp +++ b/CustomDesktop/CDAPI.cpp @@ -57,6 +57,7 @@ namespace cd } + // 实现ExecInMainThread static bool OnFileListWndProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_EXEC_FUNCTION) diff --git a/CustomDesktop/CDEvents.cpp b/CustomDesktop/CDEvents.cpp index c6fee9f..c511b43 100644 --- a/CustomDesktop/CDEvents.cpp +++ b/CustomDesktop/CDEvents.cpp @@ -8,6 +8,8 @@ namespace cd #define DEF_VARIABLE(name) decltype(name) name CD_API DEF_VARIABLE(g_preUnloadEvent); + CD_API DEF_VARIABLE(g_desktopCoveredEvent); + CD_API DEF_VARIABLE(g_desktopUncoveredEvent); CD_API DEF_VARIABLE(g_preDrawBackgroundEvent); CD_API DEF_VARIABLE(g_postDrawBackgroundEvent); @@ -25,6 +27,8 @@ namespace cd // 外部模块可注册的事件集合,用来自动卸载外部listener std::vector g_externalEvents{ &g_preUnloadEvent, + &g_desktopCoveredEvent, + &g_desktopUncoveredEvent, &g_preDrawBackgroundEvent, &g_postDrawBackgroundEvent, diff --git a/CustomDesktop/CheckCovered.cpp b/CustomDesktop/CheckCovered.cpp new file mode 100644 index 0000000..0c7e36c --- /dev/null +++ b/CustomDesktop/CheckCovered.cpp @@ -0,0 +1,92 @@ +#include "stdafx.h" +#include "CheckCovered.h" +#include +#include +#include + + +namespace cd +{ + CheckCovered::CheckCovered() + { + Init(); + } + + CheckCovered::~CheckCovered() + { + Uninit(); + } + + bool CheckCovered::Init() + { + m_runThreadFlag = true; + ExecInMainThread([this]{ m_thread = std::make_unique(&CheckCovered::CheckCoveredThread, this); }); + return true; + } + + bool CheckCovered::Uninit() + { + m_runThreadFlag = false; + if (m_thread != nullptr && m_thread->joinable()) + m_thread->join(); + m_thread = nullptr; + return true; + } + + + void CheckCovered::CheckCoveredThread() + { + while (m_runThreadFlag) + { + if (IsDesktopCovered()) + { + if (!m_isCovered) + { + m_isCovered = true; + ExecInMainThread([]{ g_desktopCoveredEvent(); }); + +#ifdef _DEBUG + WCHAR windowName[100], className[100]; + GetWindowTextW(m_coveredByHwnd, windowName, _countof(windowName)); + GetClassNameW(m_coveredByHwnd, className, _countof(className)); + _RPTW2(_CRT_WARN, L"桌面被 %s (%s) 遮挡\n", windowName, className); +#endif + } + } + else + { + if (m_isCovered) + { + m_isCovered = false; + ExecInMainThread([]{ g_desktopUncoveredEvent(); }); + + _RPT0(_CRT_WARN, "桌面从被遮挡恢复\n"); + } + } + + for (int i = 0; i < 10; i++) + { + if (!m_runThreadFlag) + break; + Sleep(100); + } + } + } + + bool CheckCovered::IsDesktopCovered() + { + m_coveredByHwnd = NULL; + + EnumWindows([](HWND hwnd, LPARAM pCoveredByHwnd)->BOOL{ + if (IsZoomed(hwnd) && IsWindowVisible(hwnd)) + { + + *(HWND*)pCoveredByHwnd = hwnd; + return FALSE; + } + return TRUE; + }, (LPARAM)&m_coveredByHwnd); + + return m_coveredByHwnd != NULL; + } +} diff --git a/CustomDesktop/CheckCovered.h b/CustomDesktop/CheckCovered.h new file mode 100644 index 0000000..39079a0 --- /dev/null +++ b/CustomDesktop/CheckCovered.h @@ -0,0 +1,33 @@ +#pragma once +#include "Singleton.h" +#include +#include + + +namespace cd +{ + // 检测桌面是否被遮挡了 + class CheckCovered final : public Singleton + { + DECL_SINGLETON(CheckCovered); + public: + bool IsReady() { return m_runThreadFlag; } + + bool Init(); + bool Uninit(); + + private: + CheckCovered(); + ~CheckCovered(); + + + std::unique_ptr m_thread; + bool m_runThreadFlag = true; + bool m_isCovered = false; + HWND m_coveredByHwnd = NULL; + + + void CheckCoveredThread(); + bool IsDesktopCovered(); + }; +} diff --git a/CustomDesktop/CustomDesktop.vcxproj b/CustomDesktop/CustomDesktop.vcxproj index a83b501..6df26c1 100644 --- a/CustomDesktop/CustomDesktop.vcxproj +++ b/CustomDesktop/CustomDesktop.vcxproj @@ -161,6 +161,7 @@ + @@ -173,6 +174,7 @@ + diff --git a/CustomDesktop/CustomDesktop.vcxproj.filters b/CustomDesktop/CustomDesktop.vcxproj.filters index 888e0be..a145bca 100644 --- a/CustomDesktop/CustomDesktop.vcxproj.filters +++ b/CustomDesktop/CustomDesktop.vcxproj.filters @@ -75,6 +75,9 @@ 头文件\Helper + + 头文件\Module + @@ -104,5 +107,8 @@ 源文件\Helper + + 源文件\Module + \ No newline at end of file diff --git a/CustomDesktop/PluginManager.cpp b/CustomDesktop/PluginManager.cpp index 23b55e6..aab9c6a 100644 --- a/CustomDesktop/PluginManager.cpp +++ b/CustomDesktop/PluginManager.cpp @@ -1,9 +1,9 @@ #include "stdafx.h" #include "PluginManager.h" -#include #include "Global.h" #include #include +#include namespace cd @@ -20,7 +20,10 @@ namespace cd plugin.m_module = LoadLibraryW(path); if (plugin.m_module == NULL) { - _RPTFW1(_CRT_ERROR, L"加载插件失败:%s\n", path); + _RPTFW1(_CRT_WARN, L"加载插件失败:%s\n", path); + std::wostringstream oss; + oss << L"加载插件失败" << path; + MessageBoxW(NULL, oss.str().c_str(), L"CustomDesktop", MB_OK); return false; } diff --git a/CustomDesktop/dllmain.cpp b/CustomDesktop/dllmain.cpp index 902fbad..35f04ae 100644 --- a/CustomDesktop/dllmain.cpp +++ b/CustomDesktop/dllmain.cpp @@ -6,6 +6,7 @@ #include "BufferedRendering.h" #include "CDAPIModule.h" #include "PluginManager.h" +#include "CheckCovered.h" #include using namespace cd; @@ -46,6 +47,8 @@ namespace _RPTF0(_CRT_WARN, "HookDesktop::GetInstance().Uninit();\n"); HookDesktop::GetInstance().Uninit(); + CheckCovered::GetInstance().Uninit(); + _RPTF0(_CRT_WARN, "g_preUnloadEvent();\n"); g_preUnloadEvent(); // 卸载本模块之前要释放所有插件否则卸载不掉 @@ -76,12 +79,13 @@ namespace if (pos != std::string::npos) g_global.m_cdDir.resize(pos + 1); + g_fileListWndProcEvent.AddListener(OnFileListWndProc); + InitModule(BufferedRendering) InitModule(HookDesktop) InitModule(CDAPIModule) InitModule(PluginManager) - - g_fileListWndProcEvent.AddListener(OnFileListWndProc); + InitModule(CheckCovered) return true; } diff --git a/Include/CDEvents.h b/Include/CDEvents.h index a7c0648..4c40117 100644 --- a/Include/CDEvents.h +++ b/Include/CDEvents.h @@ -6,6 +6,8 @@ namespace cd { extern CD_API PostEvent<> g_preUnloadEvent; // 准备卸载,在处理消息时触发 + extern CD_API PostEvent<> g_desktopCoveredEvent; // 桌面被遮挡了,在处理消息时触发 + extern CD_API PostEvent<> g_desktopUncoveredEvent; // 桌面从被遮挡恢复,在处理消息时触发 extern CD_API PreEvent g_preDrawBackgroundEvent; // 画桌面背景前被调用,用来取消画背景节省CPU,参数:目标DC extern CD_API PostEvent g_postDrawBackgroundEvent; // 画完桌面背景后被调用,参数:目标DC diff --git a/Plugin/VideoDesktop/VideoDesktop.cpp b/Plugin/VideoDesktop/VideoDesktop.cpp index ed50c55..b988f3b 100644 --- a/Plugin/VideoDesktop/VideoDesktop.cpp +++ b/Plugin/VideoDesktop/VideoDesktop.cpp @@ -10,6 +10,8 @@ VideoDesktop::VideoDesktop(HMODULE hModule) : WM_GRAPHNOTIFY(cd::GetCustomMessageID()) { // 监听事件 + cd::g_desktopCoveredEvent.AddListener([this]{ m_curPlayer->PauseVideo(); return true; }, m_module); + cd::g_desktopUncoveredEvent.AddListener([this]{ m_curPlayer->RunVideo(); return true; }, m_module); cd::g_preDrawBackgroundEvent.AddListener([](HDC&){ return false; }, m_module); cd::g_postDrawBackgroundEvent.AddListener(std::bind(&VideoDesktop::OnDrawBackground, this, std::placeholders::_1), m_module); cd::g_fileListWndProcEvent.AddListener(std::bind(&VideoDesktop::OnFileListWndProc, this, std::placeholders::_1,