private void CheckScreenThread(object args) { int n, last_n, cb_n; last_n = (int)args; while (true) { n = ScreenShots.GetScreens().Length; if (n != last_n) { last_n = n; cb_n = (int)this.Invoke((Func <object>)(() => { return(comboBox_SelectScreen.Items.Count); })); if (n > cb_n) { this.Invoke((Action)(() => { for (int i = comboBox_SelectScreen.Items.Count; i < n; i++) { comboBox_SelectScreen.Items.Add(i.ToString()); } })); } else if (n < cb_n) { this.Invoke((Action)(() => { int temp = -1; bool errFlag = false; bool stoppedThread = false; if (int.Parse(Config.Get(Config.Name_ScreenIndex)) >= n) { Config.Set(Config.Name_ScreenIndex, Config.DefalutScreenIndex.ToString(), true); temp = comboBox_SelectScreen.SelectedIndex; comboBox_SelectScreen.SelectedIndex = Config.DefalutScreenIndex; if (clickThread != null && clickThread.IsAlive) { AbortClickThread(); stoppedThread = true; } errFlag = true; } for (int i = comboBox_SelectScreen.Items.Count - 1; i >= n; i--) { comboBox_SelectScreen.Items.Remove(i.ToString()); } if (errFlag) { ShowError("已丢失序号为" + temp.ToString() + "的屏幕。" + (stoppedThread ? "线程已经被终止。" : "")); } })); } } Thread.Sleep(1000); } }
public Form1() { InitializeComponent(); if (Program.ProgramArguments.HideWhenBoot) { //this.Hide(); this.WindowState = this.FormWindowState.Minimized; } //初始化空控件 lastTabIndexControl.Visible = true; lastTabIndexControl.TabIndex = int.MaxValue; this.Controls.Add(lastTabIndexControl); //初始化点击窗口 clicker.Show(); clicker.Visible = false; //初始化设置面板数据 //模板路径 //FileInfo templateFile = new FileInfo(Config.Get(Config.Name_TemplatePath)); //if (!templateFile.Exists) //{ // Config.Set(Config.Name_TemplatePath, templateFile.FullName, true); // templateFile = new FileInfo(Config.Get(Config.Name_TemplatePath)); //} if (!Utility.CheckMatSource(Config.Get(Config.Name_TemplatePath))) { ShowError("当前模板图片不存在或无法打开或不支持。\n" + Config.Get(Config.Name_TemplatePath)); } label_TemplatePath.Text = Config.Get(Config.Name_TemplatePath); //阈值 trackBar_SetThreshold.Value = byte.Parse(Config.Get(Config.Name_Threshold)); textBox_SetThreshold.Text = byte.Parse(Config.Get(Config.Name_Threshold)).ToString(); //计时器 trackBar_SetTimer.Value = SetTimerPanel_TextToValue(Config.Get(Config.Name_Delay)); textBox_SetTimer.Text = int.Parse(Config.Get(Config.Name_Delay)).ToString(); //屏幕序号 int screenNumber = ScreenShots.GetScreens().Length; for (int i = 0; i < screenNumber; i++) { comboBox_SelectScreen.Items.Add(i.ToString()); } int screenIndex = int.Parse(Config.Get(Config.Name_ScreenIndex)); if (screenIndex >= screenNumber) { Config.Set(Config.Name_ScreenIndex, Config.DefalutScreenIndex.ToString(), true); comboBox_SelectScreen.SelectedIndex = Config.DefalutScreenIndex; } else { comboBox_SelectScreen.SelectedIndex = screenIndex; } StartCheckScreenThread(screenNumber); //启动初始化线程 Thread InitThread = new Thread((ThreadStart)(() => { while (!this.IsHandleCreated) { ; } this.BeginInvoke((Action)(() => { InitHotKey(); this.MinimumSize = this.Size; this.MaximumSize = this.Size; if (Program.ProgramArguments.StartThreadDirectly) { StartClickThread(); } })); })); InitThread.IsBackground = true; InitThread.Start(); }
private void ClickThread(object args) { //初始化 ClickThreadArguments cta = new ClickThreadArguments(); ClickThreadInfoSave ctis = new ClickThreadInfoSave(); void UpdateAndGetClickThreadArguments() { cta = (ClickThreadArguments)this.Invoke((Func <object>)(() => { clickThreadArguments.screen = Screen.AllScreens[int.Parse(Config.Get(Config.Name_ScreenIndex))]; clickThreadArguments.templatePath = Config.Get(Config.Name_TemplatePath); clickThreadArguments.threshold = byte.Parse(Config.Get(Config.Name_Threshold)); clickThreadArguments.delay = int.Parse(Config.Get(Config.Name_Delay)); return(this.clickThreadArguments); })); } DateTime begin = new DateTime(0); DateTime timer = new DateTime(0); void WaitTimer() { TimeSpan subResult; TimeSpan delayTime; while (true) { //更新配置 UpdateAndGetClickThreadArguments(); delayTime = new TimeSpan(0, 0, 0, 0, cta.delay); //计算时差 subResult = DateTime.Now.Subtract(timer); StatusStrip_Set_toolStripStatusLabel_TotalRunningTime(DateTime.Now.Subtract(begin)); if (subResult < delayTime) { StatusStrip_Set_toolStripProgressBar_Timer_Value((int)(100 * (subResult.TotalMilliseconds / delayTime.TotalMilliseconds))); //UI StatusStrip_Set_toolStripLabel_Timer_Value((int)subResult.TotalMilliseconds, cta.delay); //UI } else { StatusStrip_Set_toolStripProgressBar_Timer_Value(100); StatusStrip_Set_toolStripLabel_Timer_Value((int)delayTime.TotalMilliseconds, cta.delay);//UI break; } //防卡停顿 Thread.Sleep(100); } } ScreenShots screenShots = new ScreenShots(); Mat screenShot = new Mat(); Mat template = new Mat(); Mat result = new Mat(); //恢复线程状态 if (args != null) { ctis = (ClickThreadInfoSave)args; begin = DateTime.Now.Subtract(ctis.totalRunningTime); timer = DateTime.Now.Subtract(ctis.timer); } else { ctis.timer = new TimeSpan(0); ctis.totalRunningTime = new TimeSpan(0); ctis.lastLocation = new System.Drawing.Point(0, 0); ctis.lastValue = 0; ctis.clickCount = 0; ctis.scanedCount = 0; begin = DateTime.Now; } try { if (args != null) { WaitTimer(); } while (true) { //获取配置 UpdateAndGetClickThreadArguments(); //开始计时 timer = DateTime.Now; StatusStrip_Set_toolStripProgressBar_Timer_Value(0); //UI StatusStrip_Set_toolStripLabel_Timer_Value(0, cta.delay); //UI //获取并保存截屏 screenShots.ScreenShotDefault(cta.screen); screenShots.LastScreenShot.Save(Config.ScreenShotPath); //初始化图片 screenShot = new Mat(Config.ScreenShotPath); template = new Mat(Config.Get(Config.Name_TemplatePath)); result = new Mat();//Mat(new OpenCvSharp.Size(screenShots.LastScreenShot.Width, screenShots.LastScreenShot.Height), MatType.CV_32SC1) //比对 Cv2.MatchTemplate(InputArray.Create(screenShot), InputArray.Create(template), OutputArray.Create(result), TemplateMatchModes.CCoeffNormed, null); //查找最佳匹配 OpenCvSharp.Point maxLoc = new OpenCvSharp.Point(0, 0); double maxVal = 0; Cv2.MinMaxLoc(InputArray.Create(result), out _, out maxVal, out _, out maxLoc); //记录结果值 ctis.lastValue = (byte)(maxVal * 255); StatusStrip_Set_toolStripLabel_LastValue_Value(ctis.lastValue);//UI //记录扫描 ctis.scanedCount++; StatusStrip_Set_toolStripStatusLabel_ScanedCount(ctis.scanedCount);//UI //检查阀值 if (maxVal >= cta.threshold / (double)255) { //计算实际中心位置 int realX = cta.screen.WorkingArea.X + maxLoc.X + template.Width / 2; int realY = cta.screen.WorkingArea.Y + maxLoc.Y + template.Height / 2; //模拟点击 SimClick(realX, realY); StatusStrip_Set_toolStripLabel_LastLocation_Value(realX, realY);//UI //记录点击 ctis.lastLocation = new System.Drawing.Point(realX, realY); ctis.clickCount++; StatusStrip_Set_toolStripStatusLabel_ClickCount(ctis.clickCount);//UI //检查是否完成退出计数 if (Program.ProgramArguments.ExitClickCount > 0 && Program.ProgramArguments.ExitClickCount <= ctis.clickCount) { this.Invoke((Action)(() => { Program.Exit(0); })); } } //清理内存 GC.Collect(); //延时 WaitTimer(); } } catch (ThreadAbortException taEx) { //处理线程终止 //清理 result.Dispose(); template.Dispose(); screenShot.Dispose(); screenShots.Clear(); if (taEx.ExceptionState != null && (string)taEx.ExceptionState == "pause") { if (timer != new DateTime(0)) { ctis.timer = DateTime.Now.Subtract(timer); } if (begin != new DateTime(0)) { ctis.totalRunningTime = DateTime.Now.Subtract(begin); } this.BeginInvoke((Action)(() => { lastClickThreadInfoSave = ctis; })); } //else //{ // //清除状态栏信息 // StatusStrip_Set_toolStripProgressBar_Timer_Value(0);//UI // StatusStrip_Set_toolStripLabel_Timer_Value(0, cta.delay);//UI //} //阻塞UI,不可使用,请在调用终止代码后方添加状态调整 //this.BeginInvoke((Action)(() => //{ // SetThreadStatus(false);//UI //})); } }