11#include " HutaoNativeHotKeyAction.h"
2+ #include " HutaoNativeHotKeyActionCallback.h"
23#include " Error.h"
34#include < Windows.h>
5+ #include < chrono>
6+ #include < thread>
47
58const wchar_t * WINDOW_CLASS_NAME = L" HutaoNativeHotKeyActionWindowClass" ;
69const UINT WM_HOTKEY_MESSAGE = WM_APP + 2 ;
710
811UINT 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-
3427HutaoNativeHotKeyAction::~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+
120204HRESULT 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;
0 commit comments