mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
62 lines
1.9 KiB
C++
62 lines
1.9 KiB
C++
#include "pch.h"
|
|
#include "ExclModeHack.h"
|
|
#include "App.h"
|
|
#include <shellapi.h>
|
|
|
|
|
|
// 模拟 D3D 独占全屏模式,以起到免打扰的效果
|
|
// SHQueryUserNotificationState 通常被用来检测是否有 D3D 游戏独占全屏,以确定是否应该向用户推送通知/弹窗
|
|
// 此函数内部使用名为 __DDrawExclMode__ 的 mutex 检测独占全屏,因此这里直接获取该 mutex 以模拟独占全屏
|
|
// 感谢 @codehz 提供的思路 https://github.com/Blinue/Magpie/issues/245
|
|
ExclModeHack::ExclModeHack() {
|
|
if (!App::GetInstance().IsSimulateExclusiveFullscreen()) {
|
|
return;
|
|
}
|
|
|
|
QUERY_USER_NOTIFICATION_STATE state;
|
|
HRESULT hr = SHQueryUserNotificationState(&state);
|
|
if (FAILED(hr)) {
|
|
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("SHQueryUserNotificationState 失败", hr));
|
|
return;
|
|
}
|
|
if (state != QUNS_ACCEPTS_NOTIFICATIONS) {
|
|
SPDLOG_LOGGER_INFO(logger, "已处于免打扰状态");
|
|
return;
|
|
}
|
|
|
|
_exclModeMutex.reset(Utils::SafeHandle(
|
|
OpenMutex(SYNCHRONIZE, FALSE, L"__DDrawExclMode__")));
|
|
if (!_exclModeMutex) {
|
|
SPDLOG_LOGGER_ERROR(logger, MakeWin32ErrorMsg("OpenMutex 失败"));
|
|
return;
|
|
}
|
|
|
|
DWORD result = WaitForSingleObject(_exclModeMutex.get(), 0);
|
|
if (result != WAIT_OBJECT_0) {
|
|
SPDLOG_LOGGER_ERROR(logger, "获取 __DDrawExclMode__ 失败");
|
|
_exclModeMutex.reset();
|
|
return;
|
|
}
|
|
|
|
hr = SHQueryUserNotificationState(&state);
|
|
if (FAILED(hr)) {
|
|
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("SHQueryUserNotificationState 失败", hr));
|
|
ReleaseMutex(_exclModeMutex.get());
|
|
_exclModeMutex.reset();
|
|
return;
|
|
}
|
|
if (state != QUNS_RUNNING_D3D_FULL_SCREEN) {
|
|
SPDLOG_LOGGER_INFO(logger, "模拟独占全屏失败");
|
|
ReleaseMutex(_exclModeMutex.get());
|
|
_exclModeMutex.reset();
|
|
return;
|
|
}
|
|
|
|
SPDLOG_LOGGER_INFO(logger, "模拟独占全屏成功");
|
|
}
|
|
|
|
ExclModeHack::~ExclModeHack() {
|
|
if (_exclModeMutex) {
|
|
ReleaseMutex(_exclModeMutex.get());
|
|
}
|
|
}
|