细节优化

This commit is contained in:
Xu Liu 2021-06-14 13:41:53 +08:00
commit 42088d9261
9 changed files with 89 additions and 42 deletions

View file

@ -64,11 +64,22 @@ namespace Magpie {
return;
}
IntPtr hwndSrc = NativeMethods.GetForegroundWindow();
if (!NativeMethods.IsWindow(hwndSrc)
|| !NativeMethods.IsWindowVisible(hwndSrc)
|| NativeMethods.GetWindowShowCmd(hwndSrc) != NativeMethods.SW_NORMAL
) {
// 不合法的源窗口
return;
}
Status = MagWindowStatus.Starting;
// 使用 WinRT Capturer API 需要在 MTA 中
// C# 窗体必须使用 STA因此将全屏窗口创建在新的线程里
magThread = new Thread(() => {
NativeMethods.RunMagWindow(
(int status, IntPtr errorMsg) => StatusEvent(status, Marshal.PtrToStringUni(errorMsg)),
hwndSrc, // 源窗口句柄
scaleModel, // 缩放模式
captureMode, // 抓取模式
showFPS, // 显示 FPS
@ -79,7 +90,7 @@ namespace Magpie {
magThread.Start();
if (hookCursorAtRuntime) {
HookCursorAtRuntime();
HookCursorAtRuntime(hwndSrc);
}
}
@ -93,8 +104,7 @@ namespace Magpie {
NativeMethods.BroadcastMessage(NativeMethods.MAGPIE_WM_DESTORYMAG);
}
private void HookCursorAtRuntime() {
IntPtr hwndSrc = NativeMethods.GetForegroundWindow();
private void HookCursorAtRuntime(IntPtr hwndSrc) {
int pid = NativeMethods.GetWindowProcessId(hwndSrc);
if (pid == 0 || pid == Process.GetCurrentProcess().Id) {
// 不能 hook 本进程

View file

@ -191,39 +191,44 @@ namespace Magpie {
}
private void StartScaleTimer() {
if (timerScale.Enabled) {
// 已经开始倒计时
return;
}
countDownNum = DOWN_COUNT;
btnScale.Text = countDownNum.ToString();
btnScale.Enabled = false;
tsmiScale.Text = btnScale.Text = countDownNum.ToString();
timerScale.Interval = 1000;
timerScale.Enabled = true;
timerScale.Start();
}
private void StopScaleTimer() {
timerScale.Stop();
tsmiScale.Text = btnScale.Text = "5秒后放大";
}
private void ToggleScaleTimer() {
if (timerScale.Enabled) {
StopScaleTimer();
} else {
StartScaleTimer();
}
}
private void BtnScale_Click(object sender, EventArgs e) {
StartScaleTimer();
ToggleScaleTimer();
}
private void TimerScale_Tick(object sender, EventArgs e) {
if(--countDownNum != 0) {
btnScale.Text = countDownNum.ToString();
tsmiScale.Text = btnScale.Text = countDownNum.ToString();
return;
}
// 计时结束
timerScale.Enabled = false;
btnScale.Text = "5秒后放大";
btnScale.Enabled = true;
StopScaleTimer();
ToggleMagWindow();
}
private void TsmiScale_Click(object sender, EventArgs e) {
StartScaleTimer();
ToggleScaleTimer();
}
}
}

View file

@ -10,12 +10,20 @@ namespace Magpie {
static class NativeMethods {
public static readonly int MAGPIE_WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
public static readonly int MAGPIE_WM_DESTORYMAG = RegisterWindowMessage("MAGPIE_WM_DESTORYMAG");
public static readonly int SW_NORMAL = 1;
// 获取用户当前正在使用的窗体的句柄
[DllImport("user32", CharSet = CharSet.Unicode)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
@ -45,16 +53,52 @@ namespace Magpie {
return processId;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT {
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct RECT {
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
struct WINDOWPLACEMENT {
public uint length;
public uint flags;
public uint showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
public static int GetWindowShowCmd(IntPtr hWnd) {
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
wp.length = (uint)Marshal.SizeOf(wp);
if(!GetWindowPlacement(hWnd, ref wp)) {
return -1;
}
return (int)wp.showCmd;
}
/*
* Runtime.dll
*/
public delegate void ReportStatus(int status, IntPtr errorMsg);
[DllImport("Runtime", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.U1)]
public static extern void RunMagWindow(
ReportStatus reportStatus,
IntPtr hwndSrc,
[MarshalAs(UnmanagedType.LPUTF8Str)] string scaleModel,
int captureMode,
[MarshalAs(UnmanagedType.U1)] bool showFPS,

View file

@ -2,7 +2,7 @@
窗口放大镜!
可以将任意窗口全屏显示,支持高级缩放算法,包括 Jinc、[Anime4K](https://github.com/bloc97/Anime4K)本项目包含一个Direct2D Effect移植、Lanczos等。
可以将任意窗口全屏显示,支持高级缩放算法,包括[Anime4K](https://github.com/bloc97/Anime4K)本项目包含一个Direct2D移植、Lanczos等。
主要用于游戏窗口的放大显示,适用于那些不支持全屏模式,或者游戏自带的全屏模式会使画面模糊的情况。

View file

@ -32,27 +32,25 @@ BOOL APIENTRY DllMain(
API_DECLSPEC void WINAPI RunMagWindow(
void reportStatus(int status, const wchar_t* errorMsg),
HWND hwndSrc,
const char* scaleModel,
int captureMode,
bool showFPS,
bool noDisturb
) {
reportStatus(1, nullptr);
Debug::ThrowIfComFailed(
CoInitializeEx(NULL, COINIT_MULTITHREADED),
L"初始化 COM 出错"
);
try {
HWND hwndSrc = GetForegroundWindow();
Debug::ThrowIfWin32Failed(
hwndSrc,
L"获取前台窗口失败"
Debug::Assert(
IsWindow(hwndSrc) && IsWindowVisible(hwndSrc) && Utils::GetWindowShowCmd(hwndSrc) == SW_NORMAL,
L"不合法的源窗口"
);
Debug::Assert(
Utils::GetWindowShowCmd(hwndSrc) == SW_NORMAL,
L"该窗口当前已最大化或最小化"
captureMode >= 0 && captureMode <= 1,
L"非法的抓取模式"
);
Env::CreateInstance(hInst, hwndSrc, scaleModel, captureMode, showFPS, noDisturb);

View file

@ -28,8 +28,6 @@ public:
_d2dFactory = d2dFactory;
_d2dDevice = d2dDevice;
_d2dDC = d2dDC;
}
void SetHwndHost(HWND hwndHost) {
@ -135,12 +133,9 @@ private:
int captureMode,
bool showFPS,
bool noDisturb
) : _hInst(hInst), _hwndSrc(hwndSrc), _scaleModel(scaleModel), _captureMode(captureMode), _showFPS(showFPS), _noDisturb(noDisturb) {
Debug::Assert(
captureMode >= 0 && captureMode <= 1,
L"非法的抓取模式"
);
) : _hInst(hInst), _hwndSrc(hwndSrc), _scaleModel(scaleModel),
_captureMode(captureMode), _showFPS(showFPS), _noDisturb(noDisturb)
{
Utils::GetClientScreenRect(_hwndSrc, _srcClient);
}

View file

@ -59,12 +59,6 @@ private:
Debug::Assert(false, L"已存在全屏窗口");
}
HWND hwndSrc = Env::$instance->GetHwndSrc();
Debug::Assert(
IsWindow(hwndSrc) && IsWindowVisible(hwndSrc),
L"hwndSrc 不合法"
);
_RegisterHostWndClass();
_CreateHostWnd();

View file

@ -10,6 +10,7 @@ public:
assert(hwnd != NULL);
WINDOWPLACEMENT wp{};
wp.length = sizeof(wp);
Debug::ThrowIfWin32Failed(
GetWindowPlacement(hwnd, &wp),
L"GetWindowPlacementʧ°Ü"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Before After
Before After