Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions source/MaaWin32ControlUnit/Base/ForegroundUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <chrono>
#include <thread>

#include "MaaUtils/SafeWindows.hpp"

#include "Common/Conf.h"

MAA_CTRL_UNIT_NS_BEGIN

inline void ensure_foreground_and_topmost(HWND hwnd)
{
if (!hwnd) {
return;
}

// 如果窗口不在前台,先将其置顶
if (hwnd != GetForegroundWindow()) {
// 将窗口移到 Z 序顶部
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
Comment thread
zmdyy0318 marked this conversation as resolved.

// 尝试设置为前台窗口
SetForegroundWindow(hwnd);
std::this_thread::sleep_for(std::chrono::milliseconds(10));

// 再次检查,如果仍然不在前台,再次置顶
if (hwnd != GetForegroundWindow()) {
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
}

inline bool ensure_foreground_with_cooldown(HWND hwnd)
{
constexpr DWORD kForegroundRecoveryInterval = 5000;
static DWORD last_foreground_attempt = 0;

Comment thread
zmdyy0318 marked this conversation as resolved.
if (!hwnd || !IsWindow(hwnd)) {
return false;
}

if (hwnd == GetForegroundWindow()) {
return true;
}

DWORD now = GetTickCount();
if (last_foreground_attempt != 0 && now - last_foreground_attempt < kForegroundRecoveryInterval) {
return hwnd == GetForegroundWindow();
}

last_foreground_attempt = now;
ensure_foreground_and_topmost(hwnd);
Comment thread
zmdyy0318 marked this conversation as resolved.
return hwnd == GetForegroundWindow();
}

MAA_CTRL_UNIT_NS_END
30 changes: 1 addition & 29 deletions source/MaaWin32ControlUnit/Input/InputUtils.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#pragma once

#include <chrono>
#include <thread>

#include "Base/ForegroundUtils.h"
#include "Common/Conf.h"
#include "MaaControlUnit/ControlUnitAPI.h"
#include "MaaUtils/SafeWindows.hpp"
Comment thread
zmdyy0318 marked this conversation as resolved.
Comment thread
zmdyy0318 marked this conversation as resolved.
Expand All @@ -27,32 +25,6 @@ inline void send_activate_message(HWND hwnd, bool use_post = false)
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

// 窗口激活并置顶工具函数(强化版本,用于需要前台的物理输入方式)
// 用于 LegacyEventInput 和 SeizeInput,因为它们使用 SendInput/mouse_event 等物理输入 API
inline void ensure_foreground_and_topmost(HWND hwnd)
{
if (!hwnd) {
return;
}

// 如果窗口不在前台,先将其置顶
if (hwnd != GetForegroundWindow()) {
// 将窗口移到 Z 序顶部
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
std::this_thread::sleep_for(std::chrono::milliseconds(5));

// 尝试设置为前台窗口
SetForegroundWindow(hwnd);
std::this_thread::sleep_for(std::chrono::milliseconds(10));

// 再次检查,如果仍然不在前台,再次置顶
if (hwnd != GetForegroundWindow()) {
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
}

// Contact 到 WM_* 消息的转换结果
struct MouseMessageInfo
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <algorithm>

#include "Base/ForegroundUtils.h"
#include "HwndUtils.hpp"
#include "MaaUtils/Logger.h"

Expand All @@ -14,6 +15,10 @@ std::optional<cv::Mat> DesktopDupWindowScreencap::screencap()
return std::nullopt;
}

if (!ensure_foreground_with_cooldown(hwnd_)) {
LogWarn << "Failed to ensure foreground window before screencap";
Comment thread
zmdyy0318 marked this conversation as resolved.
}
Comment thread
zmdyy0318 marked this conversation as resolved.

// Ensure the window is fully visible on the monitor before screencap
if (!ensure_window_on_screen(hwnd_)) {
LogWarn << "Failed to ensure window on screen";
Expand Down Expand Up @@ -110,4 +115,3 @@ RECT DesktopDupWindowScreencap::get_output_desktop_coordinates() const
}

MAA_CTRL_UNIT_NS_END

Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,3 @@ class DesktopDupWindowScreencap : public DesktopDupScreencap
};

MAA_CTRL_UNIT_NS_END

6 changes: 5 additions & 1 deletion source/MaaWin32ControlUnit/Screencap/ScreenDCScreencap.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "ScreenDCScreencap.h"

#include "Base/ForegroundUtils.h"
#include "HwndUtils.hpp"
#include "MaaUtils/Logger.h"

Expand All @@ -12,6 +13,10 @@ std::optional<cv::Mat> ScreenDCScreencap::screencap()
return std::nullopt;
}

if (!ensure_foreground_with_cooldown(hwnd_)) {
LogWarn << "Failed to ensure foreground window before screencap";
}
Comment thread
zmdyy0318 marked this conversation as resolved.
Comment thread
zmdyy0318 marked this conversation as resolved.

// Ensure the window is fully visible on the monitor before screencap
if (!ensure_window_on_screen(hwnd_)) {
LogWarn << "Failed to ensure window on screen";
Expand Down Expand Up @@ -107,4 +112,3 @@ std::optional<cv::Mat> ScreenDCScreencap::screencap()
}

MAA_CTRL_UNIT_NS_END

1 change: 0 additions & 1 deletion source/MaaWin32ControlUnit/Screencap/ScreenDCScreencap.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@ class ScreenDCScreencap : public ScreencapBase
};

MAA_CTRL_UNIT_NS_END

Loading