diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0953674 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# ignore +bin/ +.vs/ +obj/ +main.resx +MouseClickTool.csproj.user \ No newline at end of file diff --git a/MouseClickTool.Designer.cs b/MouseClickTool.Designer.cs new file mode 100644 index 0000000..cb5ac6a --- /dev/null +++ b/MouseClickTool.Designer.cs @@ -0,0 +1,218 @@ +namespace def +{ + partial class MouseClickTool + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btnUrl = new System.Windows.Forms.Label(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.delayVal = new System.Windows.Forms.TextBox(); + this.hotkeys = new System.Windows.Forms.ComboBox(); + this.label3 = new System.Windows.Forms.Label(); + this.clickType = new System.Windows.Forms.ComboBox(); + this.label4 = new System.Windows.Forms.Label(); + this.btnStart = new System.Windows.Forms.Button(); + this.btnClose = new System.Windows.Forms.Label(); + this.btnHide = new System.Windows.Forms.Label(); + this.groupBox1.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.btnUrl); + this.groupBox1.Location = new System.Drawing.Point(10, 62); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(337, 67); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "说明"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 21); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(217, 15); + this.label1.TabIndex = 0; + this.label1.Text = "本软件为开源软件,欢迎使用!"; + // + // btnUrl + // + this.btnUrl.AutoSize = true; + this.btnUrl.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnUrl.Font = new System.Drawing.Font("Calibri", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnUrl.ForeColor = System.Drawing.SystemColors.HotTrack; + this.btnUrl.Location = new System.Drawing.Point(9, 41); + this.btnUrl.Name = "btnUrl"; + this.btnUrl.Size = new System.Drawing.Size(272, 18); + this.btnUrl.TabIndex = 2; + this.btnUrl.Text = "https://github.com/lalakii/MouseClickTool"; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.delayVal); + this.groupBox3.Controls.Add(this.hotkeys); + this.groupBox3.Controls.Add(this.label3); + this.groupBox3.Controls.Add(this.clickType); + this.groupBox3.Controls.Add(this.label4); + this.groupBox3.Controls.Add(this.btnStart); + this.groupBox3.Location = new System.Drawing.Point(10, 135); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(337, 104); + this.groupBox3.TabIndex = 2; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "功能"; + // + // delayVal + // + this.delayVal.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.delayVal.Location = new System.Drawing.Point(126, 24); + this.delayVal.MaxLength = 10; + this.delayVal.Name = "delayVal"; + this.delayVal.Size = new System.Drawing.Size(75, 27); + this.delayVal.TabIndex = 1; + this.delayVal.Text = "1000"; + // + // hotkeys + // + this.hotkeys.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.hotkeys.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.hotkeys.FormattingEnabled = true; + this.hotkeys.Location = new System.Drawing.Point(126, 62); + this.hotkeys.Name = "hotkeys"; + this.hotkeys.Size = new System.Drawing.Size(75, 28); + this.hotkeys.TabIndex = 5; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label3.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; + this.label3.Location = new System.Drawing.Point(45, 65); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(84, 20); + this.label3.TabIndex = 6; + this.label3.Text = "全局热键:"; + // + // clickType + // + this.clickType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.clickType.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.clickType.FormattingEnabled = true; + this.clickType.Items.AddRange(new object[] { + "左键(Left)", + "右键(Right)"}); + this.clickType.Location = new System.Drawing.Point(212, 24); + this.clickType.Name = "clickType"; + this.clickType.Size = new System.Drawing.Size(119, 28); + this.clickType.TabIndex = 4; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label4.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; + this.label4.Location = new System.Drawing.Point(5, 27); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(121, 20); + this.label4.TabIndex = 3; + this.label4.Text = "间隔(毫秒/ms):"; + // + // btnStart + // + this.btnStart.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnStart.Location = new System.Drawing.Point(212, 53); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(119, 47); + this.btnStart.TabIndex = 0; + this.btnStart.Text = "开始"; + this.btnStart.UseVisualStyleBackColor = true; + // + // btnClose + // + this.btnClose.AutoSize = true; + this.btnClose.Font = new System.Drawing.Font("宋体", 16.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnClose.Location = new System.Drawing.Point(312, 21); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(40, 28); + this.btnClose.TabIndex = 3; + this.btnClose.Text = "×"; + // + // btnHide + // + this.btnHide.AutoSize = true; + this.btnHide.Font = new System.Drawing.Font("宋体", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnHide.Location = new System.Drawing.Point(270, 16); + this.btnHide.Name = "btnHide"; + this.btnHide.Size = new System.Drawing.Size(37, 40); + this.btnHide.TabIndex = 5; + this.btnHide.Text = "-"; + // + // MouseClickTool + // + this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.SystemColors.Window; + this.ClientSize = new System.Drawing.Size(358, 243); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.btnHide); + this.Controls.Add(this.btnClose); + this.Controls.Add(this.groupBox3); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "MouseClickTool"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "MouseClickTool"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label btnUrl; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox delayVal; + private System.Windows.Forms.Button btnStart; + private System.Windows.Forms.ComboBox clickType; + private System.Windows.Forms.Label btnClose; + private System.Windows.Forms.Label btnHide; + private System.Windows.Forms.ComboBox hotkeys; + private System.Windows.Forms.Label label3; + } +} + diff --git a/MouseClickTool.cs b/MouseClickTool.cs new file mode 100644 index 0000000..383cb39 --- /dev/null +++ b/MouseClickTool.cs @@ -0,0 +1,233 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using System.Windows.Forms; + +[assembly: AssemblyVersion("1.7.0.3")] +[assembly: AssemblyFileVersion("1.7.0.3")] +[assembly: AssemblyTitle("MouseClickTool")] +[assembly: AssemblyProduct("MouseClickTool")] +[assembly: AssemblyCopyright("Copyright (C) 2024 lalaki.cn")] + +namespace def +{ /// + /// 怎么简单怎么来了 + /// + public partial class MouseClickTool : Form + { + private Input input; + private bool running = false; + private const int waitSeconds = 3; + private const int hotkeyId = 0x233; + private TaskCompletionSource source; + private readonly string[] config = { "F1", "1000", "0" }; + + [DllImport("user32.dll")] + private static extern bool SetProcessDPIAware(); + + //参考:https://stackoverflow.com/questions/5094398/how-to-programmatically-mouse-move-click-right-click-and-keypress-etc-in-winfo + [DllImport("user32.dll")] + private static extern uint SendInput(uint nInputs, ref Input pInputs, int cbSize); + + [StructLayout(LayoutKind.Sequential)] + private struct Input + { + public int type; + public MouseKeybdhardwareInputUnion mkhi; + } + + [StructLayout(LayoutKind.Explicit)] + private struct MouseKeybdhardwareInputUnion + { + [FieldOffset(0)] + public MouseInput mi; + } + + [Flags] + private enum MouseEventFlag : uint + { + MOUSEEVENTF_LEFTDOWN = 0x0002, + MOUSEEVENTF_LEFTUP = 0x0004, + MOUSEEVENTF_RIGHTDOWN = 0x0008, + MOUSEEVENTF_RIGHTUP = 0x0010, + } + + [StructLayout(LayoutKind.Sequential)] + private struct MouseInput + { + public int dx; + public int dy; + public uint mouseData; + public MouseEventFlag dwFlags; + public uint time; + public unsafe ulong* dwExtraInfo; + } + + [DllImport("user32.dll")] + private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); + + [DllImport("user32.dll")] + private static extern bool UnregisterHotKey(IntPtr hWnd, int id); + + protected override void WndProc(ref Message m) + { + if (m.Msg == 0x0312 && (int)m.WParam == hotkeyId) + { + btnStart.PerformClick(); + } + base.WndProc(ref m); + } + + private void UpdateBtnStartText() + { + btnStart.Text = (running ? "停止" : "开始") + "(" + config[0] + ")"; + } + + public MouseClickTool() + { + InitializeComponent(); + var configFile = Path.Combine(Path.GetTempPath(), "lalaki_mouse_click_tool.ini"); + if (File.Exists(configFile)) + { + var tempConfig = File.ReadAllLines(configFile); + if (tempConfig.Length > 2) + { + config = tempConfig; + } + } + for (int i = 1; i < 13; i++) + { + hotkeys.Items.Add("F" + i); + } + hotkeys.SelectedIndexChanged += (_, __) => + { + UnregisterHotKey(Handle, hotkeyId); + Enum.TryParse(hotkeys.Text, out Keys key); + RegisterHotKey(Handle, hotkeyId, 0x4000, (uint)key); + var keyStr = key.ToString(); + config[0] = keyStr; + UpdateBtnStartText(); + }; + delayVal.TextChanged += (_, __) => config[1] = delayVal.Text; + clickType.SelectedIndexChanged += (_, __) => config[2] = clickType.SelectedIndex == 0 ? "0" : "1"; + hotkeys.SelectedItem = config[0]; + delayVal.Text = config[1]; + int.TryParse(config[2], out int clickTypeIndex); + clickType.SelectedIndex = clickTypeIndex; + btnUrl.Click += (__, _) => Process.Start(btnUrl.Text); + btnClose.Click += (__, _) => + { + Hide(); + running = false; + Application.Exit(); + }; + FormClosing += (__, _) => File.WriteAllLines(configFile, config); + btnHide.Click += (__, _) => WindowState = FormWindowState.Minimized; + btnClose.MouseHover += (__, _) => btnClose.ForeColor = Color.IndianRed; + btnHide.MouseHover += (__, _) => btnHide.ForeColor = Color.MediumPurple; + EventHandler leave = delegate (object o, EventArgs __) { ((Control)o).ForeColor = DefaultForeColor; }; + btnHide.MouseLeave += leave; + btnClose.MouseLeave += leave; + Resize += (_, __) => WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : WindowState; + MouseUp += (_, __) => Cursor = Cursors.Default; + MouseDown += (_, e) => Tag = (e.Button == MouseButtons.Left) ? e.Location : null; + MouseMove += (_, e) => + { + if (e.Button == MouseButtons.Left && Tag is Point offset) + { + Cursor = Cursors.SizeAll; + var location = PointToScreen(e.Location); + location.Offset(-offset.X, -offset.Y); + Location = location; + } + }; + Paint += (_, e) => + { + var g = e.Graphics; + using (var pen = new Pen(Color.MediumPurple, 7f)) + g.DrawLine(pen, Width, 0, 0, 0); + using (var border = new Pen(Color.FromArgb(60, 0, 0, 0))) + g.DrawRectangle(border, 0, 0, Width - 1, Height - 1); + g.DrawString(Text, new Font("Consolas", 16f), Brushes.DimGray, 15, 20); + }; + btnStart.Click += (__, _) => + { + if (!running && clickType.Enabled) + { + if (int.TryParse(delayVal.Text, out int delay) && delay > -1) + { + delayVal.ReadOnly = running = true; + btnStart.Enabled = clickType.Enabled = false; + Task.Run(async () => + { + for (int i = 1; i < waitSeconds; i++) + { + btnStart.Text = string.Format("{0}", waitSeconds - i); + await Task.Delay(1000); + } + btnStart.Enabled = true; + UpdateBtnStartText(); + var downFlag = MouseEventFlag.MOUSEEVENTF_LEFTDOWN; + var upFlag = MouseEventFlag.MOUSEEVENTF_LEFTUP; + if (clickType.SelectedIndex == 1) + { + downFlag = MouseEventFlag.MOUSEEVENTF_RIGHTDOWN; + upFlag = MouseEventFlag.MOUSEEVENTF_RIGHTUP; + } + var size = Marshal.SizeOf(input); + source = new TaskCompletionSource(); + while (running) + { + await Task.Run(async () => + { + input.mkhi.mi.dwFlags = downFlag; + SendInput(1, ref input, size); + input.mkhi.mi.dwFlags = upFlag; + SendInput(1, ref input, size); + if (delay != 0) + { + await Task.WhenAny(Task.Delay(delay), source.Task); + } + }); + } + if (delay == 0) + { + await Task.Delay(1000); + } + UpdateBtnStartText(); + delayVal.ReadOnly = false; + btnStart.Enabled = clickType.Enabled = true; + }); + } + else + { + MessageBox.Show("鼠标点击间隔,必须是等于或大于0的整数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + btnStart.Enabled = running = false; + try + { + source.SetCanceled(); + } + catch + { + } + } + }; + } + + [STAThread] + public static void Main() + { + SetProcessDPIAware(); + Application.EnableVisualStyles(); + Application.Run(new MouseClickTool()); + } + } +} \ No newline at end of file diff --git a/MouseClickTool.csproj b/MouseClickTool.csproj new file mode 100644 index 0000000..1e59090 --- /dev/null +++ b/MouseClickTool.csproj @@ -0,0 +1,71 @@ + + + + + preview + {64FA4132-AC70-4006-9495-F974EE2DD808} + WinExe + def + MouseClickTool + v4.8.1 + 512 + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + OnOutputUpdated + true + + + x86 + obj\ + 5 + Off + none + 512 + false + true + true + false + true + AllRules.ruleset + none + False + IDE0039;S2486;S108 + + + + + + + + Form + + + MouseClickTool.cs + + + False + Microsoft .NET Framework 4.8.1 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/MouseClickTool.jpg b/MouseClickTool.jpg new file mode 100644 index 0000000..cef442e Binary files /dev/null and b/MouseClickTool.jpg differ diff --git a/MouseClickTool.sln b/MouseClickTool.sln new file mode 100644 index 0000000..794b2f5 --- /dev/null +++ b/MouseClickTool.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34408.163 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MouseClickTool", "MouseClickTool.csproj", "{64FA4132-AC70-4006-9495-F974EE2DD808}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Default|Windows = Default|Windows + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {64FA4132-AC70-4006-9495-F974EE2DD808}.Default|Windows.ActiveCfg = Default|x64 + {64FA4132-AC70-4006-9495-F974EE2DD808}.Default|Windows.Build.0 = Default|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E084C909-99EC-4CA3-A898-31D8F2905EB7} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md new file mode 100644 index 0000000..c168d0f --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# MouseClickTool + +[![Latest Version](https://img.shields.io/github/v/release/lalakii/MouseClickTool?logo=github)](https://github.com/lalakii/MouseClickTool/releases) +[![Windows .exe program](https://img.shields.io/badge/windows-.exe-0078D4?logo=windows)](https://www.bilibili.com/opus/956151293127163924) + +简单好用的鼠标连点器,因为玩游戏需要连点,在网上找了好多连点器,有的居然还要收费... + +一向穷苦的我感觉为此花钱很不值得,索性自己写了个。。。 + +最新版会记忆配置,支持设置热键,优化了性能 + +## 下载 + +[本地下载](https://github.com/lalakii/MouseClickTool/releases) | [123 云盘](https://www.123pan.com/s/jE3Sjv-IWExd.html) | [蓝奏云](https://a01.lanzout.com/b0hc64t7g) **密码:d59m** + +## 使用帮助 + +如何退出?如果鼠标点击频率过快无法停下来,请先让程序窗口到前台(ALT+TAB),然后按 ALT+F4 关闭程序。 + +如果有软件无法被点击,尝试以管理员身份运行此软件。 + +设置热键时留意是否会和其他程序冲突。 + +如果需要测试连点器速度,我知道这些网站:[点击速度测试 10 秒](https://cps-check.com/cn/) | [CPS 測試 (CPS Test) 手速測試 - 測手速](https://cpstest.org/zh/) | [CPS 测试 - 鼠标点击速度测试](https://www.arealme.com/click-speed-test/cn/) + +## 界面预览 + + + +## By lalaki.cn