Skip to content

Commit

Permalink
细节优化
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Jun 14, 2021
1 parent 1727dd1 commit 42088d9
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 42 deletions.
16 changes: 13 additions & 3 deletions Magpie/MagWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,22 @@ public void Create(
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
Expand All @@ -79,7 +90,7 @@ public void Create(
magThread.Start();

if (hookCursorAtRuntime) {
HookCursorAtRuntime();
HookCursorAtRuntime(hwndSrc);
}
}

Expand All @@ -93,8 +104,7 @@ public void Destory() {
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 本进程
Expand Down
33 changes: 19 additions & 14 deletions Magpie/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,39 +191,44 @@ private void CbbCaptureMode_SelectedIndexChanged(object sender, EventArgs e) {
}

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();
}
}
}
Expand Down
48 changes: 46 additions & 2 deletions Magpie/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -45,16 +53,52 @@ public static int GetWindowProcessId(IntPtr hWnd) {
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,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

窗口放大镜!

可以将任意窗口全屏显示,支持高级缩放算法,包括 Jinc、[Anime4K](https://github.com/bloc97/Anime4K)本项目包含一个Direct2D Effect移植)、Lanczos等。
可以将任意窗口全屏显示,支持高级缩放算法,包括[Anime4K](https://github.com/bloc97/Anime4K)本项目包含一个Direct2D移植)、Lanczos等。

主要用于游戏窗口的放大显示,适用于那些不支持全屏模式,或者游戏自带的全屏模式会使画面模糊的情况。

Expand Down
14 changes: 6 additions & 8 deletions Runtime/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 3 additions & 8 deletions Runtime/Env.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class Env {
_d2dFactory = d2dFactory;
_d2dDevice = d2dDevice;
_d2dDC = d2dDC;


}

void SetHwndHost(HWND hwndHost) {
Expand Down Expand Up @@ -135,12 +133,9 @@ class Env {
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);
}

Expand Down
6 changes: 0 additions & 6 deletions Runtime/MagWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ class MagWindow {
Debug::Assert(false, L"已存在全屏窗口");
}

HWND hwndSrc = Env::$instance->GetHwndSrc();
Debug::Assert(
IsWindow(hwndSrc) && IsWindowVisible(hwndSrc),
L"hwndSrc 不合法"
);

_RegisterHostWndClass();
_CreateHostWnd();

Expand Down
1 change: 1 addition & 0 deletions Runtime/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Utils {
assert(hwnd != NULL);

WINDOWPLACEMENT wp{};
wp.length = sizeof(wp);
Debug::ThrowIfWin32Failed(
GetWindowPlacement(hwnd, &wp),
L"GetWindowPlacement失败"
Expand Down
Binary file modified img/高DPI设置.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 42088d9

Please sign in to comment.