Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit 8c745e7

Browse files
committed
1.0.1.0
1 parent d17a381 commit 8c745e7

17 files changed

Lines changed: 467 additions & 33 deletions

ClickMouse.sln

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ VisualStudioVersion = 17.14.36327.8
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClickMouse", "ClickMouse\ClickMouse.vcxproj", "{C6B296F0-8D36-4312-9E7D-DD7AE1381AF1}"
77
EndProject
8+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClickMouseLib", "ClickMouseLib\ClickMouseLib.vcxproj", "{4A81D072-07A7-4E48-908C-61F89B287014}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{9FA3D6BD-1EC1-3BA5-80CB-CE02773A58D5}"
11+
ProjectSection(SolutionItems) = preProject
12+
.gitattributes = .gitattributes
13+
.gitignore = .gitignore
14+
LICENSE = LICENSE
15+
README.md = README.md
16+
updates.md = updates.md
17+
EndProjectSection
18+
EndProject
819
Global
920
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1021
Debug|x64 = Debug|x64
@@ -21,6 +32,14 @@ Global
2132
{C6B296F0-8D36-4312-9E7D-DD7AE1381AF1}.Release|x64.Build.0 = Release|x64
2233
{C6B296F0-8D36-4312-9E7D-DD7AE1381AF1}.Release|x86.ActiveCfg = Release|Win32
2334
{C6B296F0-8D36-4312-9E7D-DD7AE1381AF1}.Release|x86.Build.0 = Release|Win32
35+
{4A81D072-07A7-4E48-908C-61F89B287014}.Debug|x64.ActiveCfg = Debug|x64
36+
{4A81D072-07A7-4E48-908C-61F89B287014}.Debug|x64.Build.0 = Debug|x64
37+
{4A81D072-07A7-4E48-908C-61F89B287014}.Debug|x86.ActiveCfg = Debug|Win32
38+
{4A81D072-07A7-4E48-908C-61F89B287014}.Debug|x86.Build.0 = Debug|Win32
39+
{4A81D072-07A7-4E48-908C-61F89B287014}.Release|x64.ActiveCfg = Release|x64
40+
{4A81D072-07A7-4E48-908C-61F89B287014}.Release|x64.Build.0 = Release|x64
41+
{4A81D072-07A7-4E48-908C-61F89B287014}.Release|x86.ActiveCfg = Release|Win32
42+
{4A81D072-07A7-4E48-908C-61F89B287014}.Release|x86.Build.0 = Release|Win32
2443
EndGlobalSection
2544
GlobalSection(SolutionProperties) = preSolution
2645
HideSolutionNode = FALSE

ClickMouse/ClickMouse.cpp

Lines changed: 139 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,138 @@ bool g_IsPaused = false; // 暂停状态
1717
int g_CurrentClick = 0; // 当前点击类型 0:无 1:左键 2:右键
1818
int g_Interval = 0; // 点击间隔
1919
WCHAR g_szInterval[100] = { 0 }; // 保存合法的间隔值文本
20+
HWND g_hTargetWnd = NULL;
21+
bool g_UseForceFocus = true; // 是否启用强制焦点
2022

2123
// 此代码模块中包含的函数的前向声明:
2224
ATOM MyRegisterClass(HINSTANCE hInstance);
2325
BOOL InitInstance(HINSTANCE, int);
2426
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
2527
INT_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+
27152
void LeftClick() {
28153
// 创建一个INPUT结构体用于发送鼠标事件
29154
INPUT input;
@@ -58,7 +183,7 @@ void RightClick() {
58183
SendInput(1, &input, sizeof(INPUT));
59184
}
60185

61-
// 修改后的对话框消息处理函数
186+
// 对话框消息处理函数
62187
INT_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
}

ClickMouse/ClickMouse.rc

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ BEGIN
3535
POPUP "帮助(&H)"
3636
BEGIN
3737
MENUITEM "关于(&A)", IDM_ABOUT
38+
MENUITEM "更新(&U)", IDM_UPDATE
3839
END
3940
MENUITEM "退出(&X)", IDM_EXIT
4041
END
@@ -57,15 +58,17 @@ END
5758
// Dialog
5859
//
5960

60-
IDD_ABOUTBOX DIALOGEX 0, 0, 170, 55
61-
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
61+
IDD_ABOUTBOX DIALOGEX 0, 0, 157, 106
62+
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
6263
CAPTION "关于 Clickmouse"
63-
FONT 9, "MS Shell Dlg", 0, 0, 0x1
64+
FONT 10, "Microsoft Sans Serif", 400, 0, 0x0
6465
BEGIN
65-
ICON IDI_CLICKMOUSE,IDC_STATIC,14,14,20,20
66-
DEFPUSHBUTTON "确定",IDOK,113,34,50,14,WS_GROUP
67-
LTEXT "Clickmouse 1.0.0.0",IDC_STATIC,38,17,114,8
68-
DEFPUSHBUTTON "更新",IDUPDATE,41,34,50,14
66+
ICON IDI_CLICKMOUSE,IDC_STATIC,14,14,16,16
67+
DEFPUSHBUTTON "确定",IDOK,100,85,50,14,WS_GROUP
68+
LTEXT "Clickmouse,版本1.0.1.0",IDC_STATIC,36,17,114,8
69+
LTEXT "一款轻便、快捷,使用C++制作的鼠标连点器",IDC_STATIC,31,38,119,18
70+
DEFPUSHBUTTON "支持作者",IDSTAR,7,85,50,14
71+
LTEXT "本软件完全开源,作者为xystudio。建议前往项目地址来个star!",IDC_STATIC,7,65,143,17
6972
END
7073

7174
IDD_MAIN_WINDOW DIALOGEX 0, 0, 300, 150
@@ -94,9 +97,9 @@ BEGIN
9497
IDD_ABOUTBOX, DIALOG
9598
BEGIN
9699
LEFTMARGIN, 7
97-
RIGHTMARGIN, 163
100+
RIGHTMARGIN, 150
98101
TOPMARGIN, 7
99-
BOTTOMMARGIN, 48
102+
BOTTOMMARGIN, 99
100103
END
101104

102105
IDD_MAIN_WINDOW, DIALOG
@@ -146,8 +149,8 @@ END
146149
//
147150

148151
VS_VERSION_INFO VERSIONINFO
149-
FILEVERSION 1,0,0,0
150-
PRODUCTVERSION 1,0,0,0
152+
FILEVERSION 1,0,1,1
153+
PRODUCTVERSION 1,0,1,0
151154
FILEFLAGSMASK 0x3fL
152155
#ifdef _DEBUG
153156
FILEFLAGS 0x1L
@@ -164,11 +167,11 @@ BEGIN
164167
BEGIN
165168
VALUE "CompanyName", "xystudio"
166169
VALUE "FileDescription", "鼠标连点器"
167-
VALUE "FileVersion", "1.0.0.0"
170+
VALUE "FileVersion", "1.0.1.1"
168171
VALUE "InternalName", "Clickmouse.exe"
169172
VALUE "OriginalFilename", "Clickmouse.exe"
170-
VALUE "ProductName", "TODO: Clickmouse"
171-
VALUE "ProductVersion", "1.0.0.0"
173+
VALUE "ProductName", "Clickmouse"
174+
VALUE "ProductVersion", "1.0.1.0"
172175
END
173176
END
174177
BLOCK "VarFileInfo"

ClickMouse/ClickMouse.vcxproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@
282282
</Link>
283283
</ItemDefinitionGroup>
284284
<ItemGroup>
285-
<ClInclude Include="ClickMouse.h" />
286285
<ClInclude Include="framework.h" />
287286
<ClInclude Include="Resource.h" />
288287
<ClInclude Include="targetver.h" />

ClickMouse/ClickMouse.vcxproj.filters

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
<ClInclude Include="Resource.h">
2525
<Filter>头文件</Filter>
2626
</ClInclude>
27-
<ClInclude Include="ClickMouse.h">
28-
<Filter>头文件</Filter>
29-
</ClInclude>
3027
</ItemGroup>
3128
<ItemGroup>
3229
<ClCompile Include="ClickMouse.cpp">

ClickMouse/resource.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
#define IDR_MAINFRAME 128
1414
#define IDD_MAIN_WINDOW 141
1515
#define IDI_ICON1 142
16-
#define IDUPDATE 1001
1716
#define IDC_RIGHT 1002
17+
#define IDSTAR 1002
1818
#define IDC_DELAY_TEXT 1003
1919
#define IDC_LEFT 1004
2020
#define IDC_DELAY_INPUT_BOX 1005
2121
#define IDC_PAUSE 1006
2222
#define IDC_STOP 1007
23+
#define IDM_UPDATE 32776
24+
#define IDM_UPDATE_LOG 32779
2325
#define IDC_STATIC -1
2426

2527
// Next default values for new objects
@@ -28,8 +30,8 @@
2830
#ifndef APSTUDIO_READONLY_SYMBOLS
2931
#define _APS_NO_MFC 1
3032
#define _APS_NEXT_RESOURCE_VALUE 143
31-
#define _APS_NEXT_COMMAND_VALUE 32775
32-
#define _APS_NEXT_CONTROL_VALUE 1006
33+
#define _APS_NEXT_COMMAND_VALUE 32780
34+
#define _APS_NEXT_CONTROL_VALUE 1008
3335
#define _APS_NEXT_SYMED_VALUE 110
3436
#endif
3537
#endif

0 commit comments

Comments
 (0)