Skip to content

Commit

Permalink
feat: 实现 TouchHelper 的功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Apr 25, 2024
1 parent 9a38cac commit 893557f
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 21 deletions.
2 changes: 0 additions & 2 deletions publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,5 +226,3 @@ def remove_file(file):
p = subprocess.run(f'"{windowsSdkDir}\\x64\\signtool.exe" sign /fd SHA256 /a /f "{pfxPath}" /p "{pfxPassword}" TouchHelper.exe')
if p.returncode != 0:
raise Exception("makepri 失败")

print("已签名", flush=True)
17 changes: 17 additions & 0 deletions src/Magpie.App/ScalingService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Logger.h"
#include "EffectsService.h"
#include <Magpie.Core.h>
#include "CommonSharedConstants.h"

using namespace ::Magpie::Core;
using namespace winrt;
Expand Down Expand Up @@ -239,6 +240,22 @@ bool ScalingService::_StartScale(HWND hWnd, const Profile& profile) {
}
}
}

{
wil::unique_mutex_nothrow hSingleInstanceMutex;

bool alreadyExists = false;
if (hSingleInstanceMutex.try_create(
CommonSharedConstants::TOUCH_HELPER_SINGLE_INSTANCE_MUTEX_NAME,
CREATE_MUTEX_INITIAL_OWNER,
MUTEX_ALL_ACCESS,
nullptr,
&alreadyExists
) && !alreadyExists) {
hSingleInstanceMutex.ReleaseMutex();
Win32Utils::ShellOpen(L"C:\\Windows\\System32\\Magpie\\TouchHelper.exe");
}
}

options.graphicsCard = profile.graphicsCard;
options.captureMethod = profile.captureMethod;
Expand Down
11 changes: 6 additions & 5 deletions src/Magpie.Core/ScalingWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

namespace Magpie::Core {

static UINT WM_MAGPIE_SCALING_CHANGED;
static UINT WM_MAGPIE_SCALINGCHANGED;

static void InitMessage() noexcept {
static Utils::Ignore _ = []() {
WM_MAGPIE_SCALING_CHANGED =
RegisterWindowMessage(CommonSharedConstants::WM_MAGPIE_SCALING_CHANGED);
WM_MAGPIE_SCALINGCHANGED =
RegisterWindowMessage(CommonSharedConstants::WM_MAGPIE_SCALINGCHANGED);
return Utils::Ignore();
}();
}
Expand Down Expand Up @@ -249,6 +249,7 @@ bool ScalingWindow::Create(
}
}

// 在显示前设置窗口属性,其他程序应在缩放窗口显示后再检索窗口属性
_SetWindowProps();

// 缩放窗口可能有 WS_MAXIMIZE 样式,因此使用 SetWindowsPos 而不是 ShowWindow
Expand Down Expand Up @@ -290,7 +291,7 @@ bool ScalingWindow::Create(
};

// 广播开始缩放
PostMessage(HWND_BROADCAST, WM_MAGPIE_SCALING_CHANGED, 1, (LPARAM)_hWnd);
PostMessage(HWND_BROADCAST, WM_MAGPIE_SCALINGCHANGED, 1, (LPARAM)_hWnd);

return true;
}
Expand Down Expand Up @@ -418,7 +419,7 @@ LRESULT ScalingWindow::_MessageHandler(UINT msg, WPARAM wParam, LPARAM lParam) n
timeEndPeriod(1);

// 广播停止缩放
PostMessage(HWND_BROADCAST, WM_MAGPIE_SCALING_CHANGED, 0, 0);
PostMessage(HWND_BROADCAST, WM_MAGPIE_SCALINGCHANGED, 0, 0);
break;
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/Magpie/NotifyIconService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ namespace Magpie {

// 当任务栏被创建时会广播此消息。用于在资源管理器被重新启动时重新创建托盘图标
// https://learn.microsoft.com/en-us/windows/win32/shell/taskbar#taskbar-creation-notification
const UINT NotifyIconService::_WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
static UINT WM_TASKBARCREATED;

void NotifyIconService::Initialize() noexcept {
WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");

_nid.cbSize = sizeof(_nid);
_nid.uVersion = 0; // 不使用 NOTIFYICON_VERSION_4
_nid.uCallbackMessage = CommonSharedConstants::WM_NOTIFY_ICON;
Expand Down Expand Up @@ -151,7 +153,7 @@ LRESULT NotifyIconService::_NotifyIconWndProc(HWND hWnd, UINT message, WPARAM wP
}
default:
{
if (message == _WM_TASKBARCREATED) {
if (message == WM_TASKBARCREATED) {
if (_shouldShow) {
// 重新创建任务栏图标
IsShow(true);
Expand Down
1 change: 0 additions & 1 deletion src/Magpie/NotifyIconService.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class NotifyIconService {
NOTIFYICONDATA _nid{};
bool _isShow = false;
bool _shouldShow = false;
static const UINT _WM_TASKBARCREATED;
};

}
4 changes: 2 additions & 2 deletions src/Magpie/XamlApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,11 @@ void XamlApp::_MainWindow_Destoryed() {

void XamlApp::_ReleaseMutexes() noexcept {
if (_hSingleInstanceMutex) {
ReleaseMutex(_hSingleInstanceMutex.get());
_hSingleInstanceMutex.ReleaseMutex();
_hSingleInstanceMutex.reset();
}
if (_hElevatedMutex) {
ReleaseMutex(_hElevatedMutex.get());
_hElevatedMutex.ReleaseMutex();
_hElevatedMutex.reset();
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/Shared/CommonSharedConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

struct CommonSharedConstants {
static constexpr const wchar_t* SINGLE_INSTANCE_MUTEX_NAME = L"{4C416227-4A30-4A2F-8F23-8701544DD7D6}";
static constexpr const wchar_t* TOUCH_HELPER_SINGLE_INSTANCE_MUTEX_NAME = L"{BD7A3F98-F4A9-44B6-9C8A-17B8DE00FEC3}";

static constexpr const wchar_t* MAIN_WINDOW_CLASS_NAME = L"Magpie_Main";
static constexpr const wchar_t* TITLE_BAR_WINDOW_CLASS_NAME = L"Magpie_TitleBar";
static constexpr const wchar_t* NOTIFY_ICON_WINDOW_CLASS_NAME = L"Magpie_NotifyIcon";
static constexpr const wchar_t* HOTKEY_WINDOW_CLASS_NAME = L"Magpie_Hotkey";
static constexpr const wchar_t* SCALING_WINDOW_CLASS_NAME = L"Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22";
static constexpr const wchar_t* DDF_WINDOW_CLASS_NAME = L"Window_Magpie_C322D752-C866-4630-91F5-32CB242A8930";
static constexpr const wchar_t* TOUCH_HELPER_WINDOW_CLASS_NAME = L"Magpie_TouchHelper";

#ifndef NOGDI
static constexpr COLORREF LIGHT_TINT_COLOR = RGB(243, 243, 243);
Expand Down Expand Up @@ -37,7 +39,7 @@ struct CommonSharedConstants {

static constexpr const wchar_t* WM_MAGPIE_SHOWME = L"WM_MAGPIE_SHOWME";
static constexpr const wchar_t* WM_MAGPIE_QUIT = L"WM_MAGPIE_QUIT";
static constexpr const wchar_t* WM_MAGPIE_SCALING_CHANGED = L"MagpieScalingChanged";
static constexpr const wchar_t* WM_MAGPIE_SCALINGCHANGED = L"MagpieScalingChanged";

static constexpr const wchar_t* APP_RESOURCE_MAP_ID = L"Magpie.App/Resources";
};
148 changes: 140 additions & 8 deletions src/TouchHelper/main.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,155 @@
#include "pch.h"
#include <magnification.h>
#include "../Shared/CommonSharedConstants.h"

static UINT WM_MAGPIE_SCALINGCHANGED;
static HWND curHwndScaling = NULL;

static void UpdateInputTransform(HWND hwndScaling) noexcept {
if (curHwndScaling == hwndScaling) {
return;
}
curHwndScaling = hwndScaling;

if (hwndScaling == NULL) {
RECT ununsed{};
MagSetInputTransform(FALSE, &ununsed, &ununsed);
return;
}

RECT srcRect{
.left = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcLeft"),
.top = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcTop"),
.right = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcRight"),
.bottom = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcBottom")
};

RECT destRect{
.left = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestLeft"),
.top = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestTop"),
.right = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestRight"),
.bottom = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestBottom")
};

MagSetInputTransform(TRUE, &srcRect, &destRect);
}

static LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_MAGPIE_SCALINGCHANGED) {
if (wParam == 0) {
// 缩放结束
UpdateInputTransform(NULL);
} else if (wParam == 1) {
// 缩放开始
UpdateInputTransform((HWND)lParam);
}

return 0;
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}

static wil::unique_mutex_nothrow CheckSingleInstance() noexcept {
wil::unique_mutex_nothrow hSingleInstanceMutex;

bool alreadyExists = false;
if (!hSingleInstanceMutex.try_create(
CommonSharedConstants::TOUCH_HELPER_SINGLE_INSTANCE_MUTEX_NAME,
CREATE_MUTEX_INITIAL_OWNER,
MUTEX_ALL_ACCESS,
nullptr,
&alreadyExists
) || alreadyExists) {
hSingleInstanceMutex.reset();
}

return hSingleInstanceMutex;
}

int APIENTRY wWinMain(
_In_ HINSTANCE /*hInstance*/,
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE /*hPrevInstance*/,
_In_ LPWSTR /*lpCmdLine*/,
_In_ int /*nCmdShow*/
) {
// 确保单例
wil::unique_mutex_nothrow hSingleInstanceMutex = CheckSingleInstance();
if (!hSingleInstanceMutex) {
MessageBox(NULL, L"已有实例", L"消息", MB_OK);
return 0;
}
auto se = hSingleInstanceMutex.ReleaseMutex_scope_exit();

wil::unique_mutex_nothrow hMagpieMutex;
if (!hMagpieMutex.try_create(CommonSharedConstants::SINGLE_INSTANCE_MUTEX_NAME)) {
return 1;
}

if (wil::handle_wait(hMagpieMutex.get(), 0)) {
// Magpie 未启动
hMagpieMutex.ReleaseMutex();
return 0;
}

if (!MagInitialize()) {
MessageBox(NULL, L"失败", L"消息", MB_OK);
return 1;
}

RECT srcRect{ 0,0,100,100 };
RECT destRect{ 10,10,210,210 };
if (!MagSetInputTransform(TRUE, &srcRect, &destRect)) {
MessageBox(NULL, L"失败", L"消息", MB_OK);
WM_MAGPIE_SCALINGCHANGED =
RegisterWindowMessage(CommonSharedConstants::WM_MAGPIE_SCALINGCHANGED);
// 防止消息被 UIPI 过滤
ChangeWindowMessageFilter(WM_MAGPIE_SCALINGCHANGED, MSGFLT_ADD);

// 创建一个隐藏窗口用于接收广播消息
{
WNDCLASSEXW wcex{
.cbSize = sizeof(wcex),
.lpfnWndProc = WndProc,
.hInstance = hInstance,
.lpszClassName = CommonSharedConstants::TOUCH_HELPER_WINDOW_CLASS_NAME
};
RegisterClassEx(&wcex);
}

wil::unique_hwnd hWnd(CreateWindow(
CommonSharedConstants::TOUCH_HELPER_WINDOW_CLASS_NAME,
nullptr,
WS_OVERLAPPEDWINDOW | WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
0
));
if (!hWnd) {
return 1;
}

return 0;

{
// 检查 Magpie 是否正在缩放,注意如果缩放窗口尚未显示视为没有缩放,
// 此时缩放窗口正在初始化,会在完成后广播 WM_MAGPIE_SCALINGCHANGED 消息
HWND hwndScaling = FindWindow(CommonSharedConstants::SCALING_WINDOW_CLASS_NAME, nullptr);
if (hwndScaling && IsWindowVisible(hwndScaling)) {
UpdateInputTransform(hwndScaling);
}
}

MSG msg;
while (true) {
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
}

// 等待新消息或 Magpie 退出
if (MsgWaitForMultipleObjectsEx(1, hMagpieMutex.addressof(),
INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_OBJECT_0) {
// Magpie 已退出
hMagpieMutex.ReleaseMutex();
return 0;
}
}
}

0 comments on commit 893557f

Please sign in to comment.