@@ -17,13 +17,138 @@ bool g_IsPaused = false; // 暂停状态
1717int g_CurrentClick = 0 ; // 当前点击类型 0:无 1:左键 2:右键
1818int g_Interval = 0 ; // 点击间隔
1919WCHAR g_szInterval[100 ] = { 0 }; // 保存合法的间隔值文本
20+ HWND g_hTargetWnd = NULL ;
21+ bool g_UseForceFocus = true ; // 是否启用强制焦点
2022
2123// 此代码模块中包含的函数的前向声明:
2224ATOM MyRegisterClass (HINSTANCE hInstance);
2325BOOL InitInstance (HINSTANCE, int );
2426LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
2527INT_PTR CALLBACK About (HWND, UINT, WPARAM, LPARAM);
2628
29+ bool IsRunAsAdmin () {
30+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
31+ PSID AdministratorsGroup;
32+ BOOL isAdmin = FALSE ;
33+
34+ if (AllocateAndInitializeSid (&NtAuthority, 2 , SECURITY_BUILTIN_DOMAIN_RID,
35+ DOMAIN_ALIAS_RID_ADMINS, 0 , 0 , 0 , 0 , 0 , 0 , &AdministratorsGroup)) {
36+ CheckTokenMembership (NULL , AdministratorsGroup, &isAdmin);
37+ FreeSid (AdministratorsGroup);
38+ }
39+ return isAdmin;
40+ }
41+
42+ // 窗口焦点处理函数
43+ bool EnsureTargetFocus (HWND hDlg) {
44+ // 获取当前前景窗口
45+ HWND hForeground = GetForegroundWindow ();
46+
47+ // 如果已经是目标窗口且未启用强制聚焦
48+ if (hForeground == g_hTargetWnd && !g_UseForceFocus)
49+ return true ;
50+
51+ // 使用更精确的窗口匹配算法
52+ DWORD dwForegroundPID;
53+ GetWindowThreadProcessId (hForeground, &dwForegroundPID);
54+
55+ // 检查窗口有效性
56+ if (!IsWindowVisible (hForeground) || IsIconic (hForeground)) {
57+ MessageBox (hDlg, L" 目标窗口不可用\n 错误描述:目标窗口不可见或最小化。" , L" 错误" , MB_ICONERROR);
58+ return false ;
59+ }
60+
61+ // 使用AttachThreadInput实现精确输入控制
62+ DWORD dwCurrentThread = GetCurrentThreadId ();
63+ DWORD dwTargetThread = GetWindowThreadProcessId (hForeground, NULL );
64+
65+ if (dwCurrentThread != dwTargetThread) {
66+ AttachThreadInput (dwCurrentThread, dwTargetThread, TRUE );
67+ }
68+
69+ // 使用渐进式聚焦策略
70+ SetWindowPos (hForeground, HWND_TOPMOST, 0 , 0 , 0 , 0 ,
71+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
72+ SetWindowPos (hForeground, HWND_NOTOPMOST, 0 , 0 , 0 , 0 ,
73+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
74+
75+ // 发送扩展聚焦消息(绕过某些应用程序的限制)
76+ SendMessageTimeout (hForeground, WM_MOUSEACTIVATE, 0 , 0 ,
77+ SMTO_NORMAL, 100 , NULL );
78+
79+ // 使用低级别键盘事件触发聚焦
80+ INPUT input[4 ] = { 0 };
81+ input[0 ].type = INPUT_KEYBOARD;
82+ input[0 ].ki .wVk = VK_MENU;
83+ input[1 ].type = INPUT_KEYBOARD;
84+ input[1 ].ki .wVk = VK_TAB;
85+ input[2 ].type = INPUT_KEYBOARD;
86+ input[2 ].ki .wVk = VK_TAB;
87+ input[2 ].ki .dwFlags = KEYEVENTF_KEYUP;
88+ input[3 ].type = INPUT_KEYBOARD;
89+ input[3 ].ki .wVk = VK_MENU;
90+ input[3 ].ki .dwFlags = KEYEVENTF_KEYUP;
91+ SendInput (4 , input, sizeof (INPUT));
92+
93+ // 解除线程绑定
94+ if (dwCurrentThread != dwTargetThread) {
95+ AttachThreadInput (dwCurrentThread, dwTargetThread, FALSE );
96+ }
97+
98+ return (GetForegroundWindow () == hForeground);
99+ }
100+
101+ // 定时器处理函数
102+ VOID CALLBACK EnhancedTimerProc (HWND hwnd, UINT msg, UINT_PTR id, DWORD time) {
103+ static bool bFocusEnsured = false ;
104+
105+ // 首次尝试聚焦
106+ if (!bFocusEnsured) {
107+ if (!EnsureTargetFocus (GetParent (hwnd))) {
108+ KillTimer (hwnd, id);
109+ MessageBox (GetParent (hwnd), L" 无法获取窗口焦点\n 错误描述:你的程序不支持此工具。" , L" 错误" , MB_ICONERROR);
110+ return ;
111+ }
112+ bFocusEnsured = true ;
113+ }
114+
115+ // 获取窗口实际位置(考虑DPI缩放)
116+ RECT rcWindow;
117+ if (!GetWindowRect (g_hTargetWnd, &rcWindow)) {
118+ KillTimer (hwnd, id);
119+ MessageBox (GetParent (hwnd), L" 无法获取窗口尺寸\n 错误描述:你的程序不支持此工具。" , L" 错误" , MB_ICONERROR);
120+ return ;
121+ }
122+
123+ // 生成智能点击坐标(避开边缘区域)
124+ int x = rcWindow.left + (rcWindow.right - rcWindow.left ) * 0.5 ;
125+ int y = rcWindow.top + (rcWindow.bottom - rcWindow.top ) * 0.5 ;
126+
127+ // 使用混合输入法发送事件
128+ INPUT inputs[4 ] = { 0 };
129+
130+ // 鼠标按下
131+ inputs[0 ].type = INPUT_MOUSE;
132+ inputs[0 ].mi .dx = x * (65535 / GetSystemMetrics (SM_CXSCREEN));
133+ inputs[0 ].mi .dy = y * (65535 / GetSystemMetrics (SM_CYSCREEN));
134+ inputs[0 ].mi .dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
135+
136+ inputs[1 ].type = INPUT_MOUSE;
137+ inputs[1 ].mi .dwFlags = (g_CurrentClick == 1 ) ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
138+
139+ // 鼠标释放
140+ inputs[2 ].type = INPUT_MOUSE;
141+ inputs[2 ].mi .dwFlags = (g_CurrentClick == 1 ) ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
142+
143+ // 添加随机移动防止检测
144+ inputs[3 ].type = INPUT_MOUSE;
145+ inputs[3 ].mi .dx = (x + rand () % 5 - 2 ) * (65535 / GetSystemMetrics (SM_CXSCREEN));
146+ inputs[3 ].mi .dy = (y + rand () % 5 - 2 ) * (65535 / GetSystemMetrics (SM_CYSCREEN));
147+ inputs[3 ].mi .dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
148+
149+ SendInput (4 , inputs, sizeof (INPUT));
150+ }
151+
27152void LeftClick () {
28153 // 创建一个INPUT结构体用于发送鼠标事件
29154 INPUT input;
@@ -58,7 +183,7 @@ void RightClick() {
58183 SendInput (1 , &input, sizeof (INPUT));
59184}
60185
61- // 修改后的对话框消息处理函数
186+ // 对话框消息处理函数
62187INT_PTR CALLBACK MainDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
63188{
64189 switch (message)
@@ -73,11 +198,12 @@ INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
73198 MAKEINTRESOURCE (IDD_ABOUTBOX),
74199 hDlg, About);
75200 break ;
76-
201+ case IDM_UPDATE:
202+ ShellExecuteW (NULL , L" open" , L" https://github.com/xystudio889/ClickMouse/releases/latest" , NULL , NULL , SW_SHOWNORMAL);
203+ break ;
77204 case IDM_EXIT:
78205 SendMessage (hDlg, WM_CLOSE, 0 , 0 );
79206 break ;
80-
81207 case IDC_LEFT: // 左键连点按钮
82208 case IDC_RIGHT: // 右键连点按钮
83209 {
@@ -101,7 +227,7 @@ INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
101227 }
102228
103229 if (!valid || wcslen (szInterval) == 0 ) {
104- MessageBox (hDlg, L" 请输入有效的数字间隔" , L" 错误" , MB_ICONERROR);
230+ MessageBox (hDlg, L" 请输入有效的数字间隔\n 错误描述:你的程序不支持此工具。 " , L" 错误" , MB_ICONERROR);
105231 return TRUE ;
106232 }
107233
@@ -113,7 +239,7 @@ INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar
113239 g_CurrentClick = (wmId == IDC_LEFT) ? 1 : 2 ;
114240
115241 // 启动定时器
116- g_TimerId = SetTimer (hDlg, 1 , g_Interval, NULL );
242+ g_TimerId = SetTimer (hDlg, 1 , g_Interval, EnhancedTimerProc); // 使用回调函数
117243 SetDlgItemText (hDlg, IDC_PAUSE, L" 暂停" );
118244 break ;
119245 }
@@ -270,6 +396,12 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
270396 switch (message)
271397 {
272398 case WM_INITDIALOG:
399+ // 启用DPI感知
400+ SetProcessDpiAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
401+ // 申请管理员权限
402+ if (!IsRunAsAdmin ()) {
403+ ShellExecute (NULL , L" runas" , GetCommandLine (), NULL , NULL , SW_SHOWNORMAL);
404+ }
273405 return (INT_PTR)TRUE ;
274406
275407 case WM_COMMAND:
@@ -278,9 +410,9 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
278410 EndDialog (hDlg, LOWORD (wParam));
279411 return (INT_PTR)TRUE ;
280412 }
281- else if (LOWORD (wParam) == IDUPDATE )
413+ else if (LOWORD (wParam) == IDSTAR )
282414 {
283- ShellExecuteW (NULL , L" open" , L" https://github.com/xystudio889/ClickMouse/releases/latest " , NULL , NULL , SW_SHOWNORMAL);
415+ ShellExecuteW (NULL , L" open" , L" https://github.com/xystudio889/ClickMouse/" , NULL , NULL , SW_SHOWNORMAL);
284416 }
285417 break ;
286418 }
0 commit comments