Skip to content

Commit 80a8285

Browse files
committed
修改HotKey实现
1 parent 5e0b576 commit 80a8285

File tree

4 files changed

+131
-22
lines changed

4 files changed

+131
-22
lines changed

src/Snap.Hutao.Remastered.Native/HutaoNative.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ HRESULT STDMETHODCALLTYPE HutaoNative::MakeHotKeyAction(HutaoNativeHotKeyActionK
152152
AssertNonNullAndReturn(ppv);
153153

154154
// Convert nint to appropriate types
155-
WNDPROC wndProc = reinterpret_cast<WNDPROC>(callback);
155+
HutaoNativeHotKeyActionCallback actionCallback;
156+
actionCallback.value = reinterpret_cast<void (__stdcall *)(BOOL, LONG_PTR)>(callback);
156157
LONG_PTR userDataPtr = static_cast<LONG_PTR>(userData);
157158

158-
hutao::com_ptr<IHutaoNativeHotKeyAction> hotKeyAction = hutao::make_com_ptr<HutaoNativeHotKeyAction>(kind, wndProc, userDataPtr);
159+
hutao::com_ptr<IHutaoNativeHotKeyAction> hotKeyAction = hutao::make_com_ptr<HutaoNativeHotKeyAction>(kind, actionCallback, userDataPtr);
159160
*ppv = hotKeyAction.detach();
160161

161162
return S_OK;

src/Snap.Hutao.Remastered.Native/HutaoNativeHotKeyAction.cpp

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,34 @@
11
#include "HutaoNativeHotKeyAction.h"
2+
#include "HutaoNativeHotKeyActionCallback.h"
23
#include "Error.h"
34
#include <Windows.h>
5+
#include <chrono>
6+
#include <thread>
47

58
const wchar_t* WINDOW_CLASS_NAME = L"HutaoNativeHotKeyActionWindowClass";
69
const UINT WM_HOTKEY_MESSAGE = WM_APP + 2;
710

811
UINT HutaoNativeHotKeyAction::s_nextHotKeyId = 0x4000; // 从0x4000开始,避免与系统热键冲突
912

10-
HutaoNativeHotKeyAction::HutaoNativeHotKeyAction()
11-
: m_callback(nullptr)
13+
HutaoNativeHotKeyAction::HutaoNativeHotKeyAction(HutaoNativeHotKeyActionKind kind, HutaoNativeHotKeyActionCallback callback, nint userData)
14+
: m_kind(kind)
15+
, m_callback(callback)
16+
, m_userData(userData)
1217
, m_modifiers(0)
1318
, m_vk(0)
1419
, m_enabled(false)
1520
, m_hotKeyId(0)
1621
, m_hWnd(nullptr)
22+
, m_isRunning(false)
1723
{
1824
m_hotKeyId = static_cast<int>(++s_nextHotKeyId);
1925
}
2026

21-
HutaoNativeHotKeyAction::HutaoNativeHotKeyAction(HutaoNativeHotKeyActionKind kind, WNDPROC callback, LONG_PTR userData)
22-
: m_callback(callback)
23-
, m_modifiers(0)
24-
, m_vk(0)
25-
, m_enabled(false)
26-
, m_hotKeyId(0)
27-
, m_hWnd(nullptr)
28-
{
29-
m_hotKeyId = static_cast<int>(++s_nextHotKeyId);
30-
(void)kind;
31-
(void)userData;
32-
}
33-
3427
HutaoNativeHotKeyAction::~HutaoNativeHotKeyAction()
3528
{
3629
SetIsEnabled(FALSE);
30+
StopAction();
31+
3732
if (m_hWnd != nullptr)
3833
{
3934
DestroyWindow(m_hWnd);
@@ -89,9 +84,26 @@ LRESULT CALLBACK HutaoNativeHotKeyAction::WndProc(HWND hWnd, UINT message, WPARA
8984
HutaoNativeHotKeyAction* pThis = reinterpret_cast<HutaoNativeHotKeyAction*>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
9085
if (pThis != nullptr)
9186
{
92-
if (message == WM_HOTKEY && pThis->m_callback != nullptr)
87+
if (message == WM_HOTKEY)
9388
{
94-
pThis->m_callback(hWnd, message, wParam, lParam);
89+
// 热键被触发,切换动作状态
90+
bool wasRunning = pThis->m_isRunning.load();
91+
92+
if (wasRunning)
93+
{
94+
pThis->StopAction();
95+
}
96+
else
97+
{
98+
pThis->ExecuteAction();
99+
}
100+
101+
// 调用回调函数通知状态变化
102+
if (pThis->m_callback.value != nullptr)
103+
{
104+
pThis->m_callback.value(!wasRunning ? TRUE : FALSE, pThis->m_userData);
105+
}
106+
95107
return 0;
96108
}
97109
}
@@ -117,6 +129,78 @@ void HutaoNativeHotKeyAction::RegisterHotKey()
117129
::RegisterHotKey(m_hWnd, m_hotKeyId, m_modifiers, m_vk);
118130
}
119131

132+
void HutaoNativeHotKeyAction::ExecuteAction()
133+
{
134+
if (m_isRunning.load())
135+
{
136+
return; // 已经在运行
137+
}
138+
139+
m_isRunning.store(true);
140+
141+
// 启动新线程执行动作
142+
m_actionThread = std::thread([this]() {
143+
while (m_isRunning.load())
144+
{
145+
if (m_kind == MouseClickRepeatForever)
146+
{
147+
SimulateMouseClick();
148+
}
149+
else if (m_kind == KeyPressRepeatForever)
150+
{
151+
SimulateKeyPress();
152+
}
153+
154+
// 延迟一段时间(例如50ms,即每秒20次)
155+
std::this_thread::sleep_for(std::chrono::milliseconds(50));
156+
}
157+
});
158+
}
159+
160+
void HutaoNativeHotKeyAction::StopAction()
161+
{
162+
m_isRunning.store(false);
163+
164+
if (m_actionThread.joinable())
165+
{
166+
m_actionThread.join();
167+
}
168+
}
169+
170+
void HutaoNativeHotKeyAction::SimulateMouseClick()
171+
{
172+
// 模拟鼠标左键点击
173+
INPUT inputs[2] = {0};
174+
175+
// 按下左键
176+
inputs[0].type = INPUT_MOUSE;
177+
inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
178+
179+
// 释放左键
180+
inputs[1].type = INPUT_MOUSE;
181+
inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
182+
183+
SendInput(2, inputs, sizeof(INPUT));
184+
}
185+
186+
void HutaoNativeHotKeyAction::SimulateKeyPress()
187+
{
188+
// 模拟F键按下(VK_F为0x46)
189+
INPUT inputs[2] = {0};
190+
191+
// 按下F键
192+
inputs[0].type = INPUT_KEYBOARD;
193+
inputs[0].ki.wVk = 0x46; // VK_F
194+
inputs[0].ki.dwFlags = 0;
195+
196+
// 释放F键
197+
inputs[1].type = INPUT_KEYBOARD;
198+
inputs[1].ki.wVk = 0x46; // VK_F
199+
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
200+
201+
SendInput(2, inputs, sizeof(INPUT));
202+
}
203+
120204
HRESULT STDMETHODCALLTYPE HutaoNativeHotKeyAction::Update(int modifiers, uint vk)
121205
{
122206
bool wasEnabled = m_enabled;
@@ -177,6 +261,7 @@ HRESULT STDMETHODCALLTYPE HutaoNativeHotKeyAction::SetIsEnabled(BOOL isEnabled)
177261
{
178262
// 禁用热键
179263
UnregisterHotKey();
264+
StopAction();
180265
}
181266

182267
m_enabled = newEnabled;

src/Snap.Hutao.Remastered.Native/HutaoNativeHotKeyAction.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
#include "IHutaoNativeHotKeyAction_h.h"
44
#include "Types_h.h"
55
#include "CustomImplements.h"
6+
#include "HutaoNativeHotKeyActionCallback.h"
67
#include <Windows.h>
8+
#include <thread>
9+
#include <atomic>
710

811
class HutaoNativeHotKeyAction : public hutao::CustomImplements<
912
HutaoNativeHotKeyAction,
1013
IHutaoNativeHotKeyAction>
1114
{
1215
public:
13-
HutaoNativeHotKeyAction();
14-
HutaoNativeHotKeyAction(HutaoNativeHotKeyActionKind kind, WNDPROC callback, LONG_PTR userData);
16+
HutaoNativeHotKeyAction(HutaoNativeHotKeyActionKind kind, HutaoNativeHotKeyActionCallback callback, nint userData);
1517
~HutaoNativeHotKeyAction();
1618

1719
// IHutaoNativeHotKeyAction methods
@@ -20,17 +22,29 @@ class HutaoNativeHotKeyAction : public hutao::CustomImplements<
2022
virtual HRESULT STDMETHODCALLTYPE SetIsEnabled(BOOL isEnabled) override;
2123

2224
private:
23-
WNDPROC m_callback;
25+
HutaoNativeHotKeyActionKind m_kind;
26+
HutaoNativeHotKeyActionCallback m_callback;
27+
nint m_userData;
2428
int m_modifiers;
2529
uint m_vk;
2630
bool m_enabled;
2731
int m_hotKeyId;
2832
HWND m_hWnd;
33+
std::atomic<bool> m_isRunning;
34+
std::thread m_actionThread;
2935
static UINT s_nextHotKeyId;
3036

3137
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
3238
static ATOM RegisterWindowClass();
3339
HWND CreateMessageWindow();
3440
void UnregisterHotKey();
3541
void RegisterHotKey();
42+
43+
// 动作执行函数
44+
void ExecuteAction();
45+
void StopAction();
46+
47+
// 输入模拟函数
48+
void SimulateMouseClick();
49+
void SimulateKeyPress();
3650
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include "Types.h"
4+
#include <Windows.h>
5+
6+
struct HutaoNativeHotKeyActionCallback
7+
{
8+
void (__stdcall *value)(BOOL isOn, LONG_PTR userData);
9+
};

0 commit comments

Comments
 (0)