在培训上网课,时不时弹出对话框要点击“确认”按钮。恩,考虑弄个自动点击的软件,自动点击“确认”按钮,刷网课。
思路是每10秒屏幕自动截图,然后搜索是否有“确认”按钮,找到屏幕上的坐标,然后模拟鼠标点击。
一、屏幕截图代码
GetDesktopWindow是Windows操作系统提供的应用程序接口函数,用于获取代表整个屏幕的桌面窗口句柄。
GetDC通过HWND窗口句柄获取窗口客户区或整个屏幕的设备上下文(HDC)。
BitBlt函数通过目标/源设备环境句柄、矩形区域坐标及尺寸参数定义操作范围,并利用光栅操作代码(如SRCCOPY、SRCAND)控制像素合成逻辑,支持图像复制、合成与逻辑运算。
//name:保存的文件名 //hWnd:要截图的窗口句柄,NULL表示对桌面截图 bool CsimmouseDlg::SavePic(std::string name, HWND hWnd) { HDC hDc = NULL; if ((hWnd == NULL)) hWnd = ::GetDesktopWindow(); //else hWnd; //判断窗口句柄是否为NULL hDc = ::GetDC(hWnd); //获取DC if (hDc == NULL) return false; int bitOfPix = GetDeviceCaps(hDc, BITSPIXEL); //获取DC像素的大小 int width = GetDeviceCaps(hDc, HORZRES); //获取DC宽度 int hight = GetDeviceCaps(hDc, VERTRES); //获取DC高度 UINT dpi = GetDpiForWindow(hWnd); //获取dpi m_x = 0; m_y = 0;CImage image; image.Create(width, hight, bitOfPix); //为图像类创建与窗口DC相同大小的DC BitBlt(image.GetDC(), 0, 0, width, hight, hDc, 0, 0, SRCCOPY); //将窗口DC图 image.Save(name.data(), Gdiplus::ImageFormatBMP);// Gdiplus::ImageFormatPNG); //保存为png格式图片文件 image.ReleaseDC(); //释放DC ::ReleaseDC(hWnd, hDc); //释放DC资源 }
二、搜索“确定”按钮代码
先保存的“确定”按钮保存为”confirm.bmp”,作为搜索的模板,二值化模板,找出最大的面积抠出原图作为halcon模型,在屏幕截取的图中搜索坐标。
CreateScaledShapeModel是HALCON机器视觉软件中用于生成可缩放形状模型的算子,主要用于模板匹配场景,通过等轴性缩放提升匹配精度。该算子通过指定缩放比例范围、角度范围和优化参数,自动生成不同尺度的形状模型,适用于印刷品套色检测、工业检测等需要高精度定位的场景。
FindScaledShapeModel是HALCON中用于搜索已知形状模型实例的算子,支持尺度、旋转和位置变化。
void CsimmouseDlg::myfind()// { HObject ho_Image; ReadImage(&ho_Image, "app.bmp");HTuple hv_ResultData;// Local iconic variables HObject ho_shapeImage, ho_ImageGray, ho_Region; HObject ho_ConnectedRegions, ho_SelectedRegions, ho_ImageReduced; HObject ho_Model, ho_ModelAtNewPosition;// Local control variables HTuple hv_Width, hv_Height, hv_ModelID, hv_Row; HTuple hv_Column, hv_Angle, hv_Scale, hv_Score, hv_I, hv_MoveAndScalingOfObject; HTuple hv_Exception;(hv_ResultData) = HTuple(5, 0); try { ReadImage(&ho_shapeImage, "confirm");Rgb3ToGray(ho_shapeImage, ho_shapeImage, ho_shapeImage, &ho_ImageGray);GetImageSize(ho_shapeImage, &hv_Width, &hv_Height); //dev_close_window () //dev_open_window (0, 0, Width, Height, 'black', WindowHandle) //dev_set_color ('red') //dev_display (Image) Threshold(ho_ImageGray, &ho_Region, 0, 100); Connection(ho_Region, &ho_ConnectedRegions); SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 100, 8000); //fill_up (SelectedRegions, RegionFillUp) //dilation_circle (RegionFillUp, RegionDilation, 5.5) ReduceDomain(ho_shapeImage, ho_SelectedRegions, &ho_ImageReduced);CreateScaledShapeModel(ho_ImageReduced, 5, HTuple(-45).TupleRad(), HTuple(90).TupleRad(), "auto", 0.8, 1.0, "auto", "none", "ignore_global_polarity", 40, 10, &hv_ModelID); GetShapeModelContours(&ho_Model, hv_ModelID, 1);FindScaledShapeModel(ho_Image, hv_ModelID, HTuple(-45).TupleRad(), HTuple(90).TupleRad(), 0.8, 1.0, 0.9, 0, 0.5, "least_squares", 5, 0.8, &hv_Row, &hv_Column, &hv_Angle, &hv_Scale, &hv_Score);TupleReplace((hv_ResultData), 0, hv_Score.TupleLength(), &(hv_ResultData));{ HTuple end_val41 = (hv_Score.TupleLength()) - 1; HTuple step_val41 = 1; for (hv_I = 0; hv_I.Continue(end_val41, step_val41); hv_I += step_val41) {TupleReplace((hv_ResultData), 1, HTuple(hv_Row[hv_I]), &(hv_ResultData)); TupleReplace((hv_ResultData), 2, HTuple(hv_Column[hv_I]), &(hv_ResultData));m_y = hv_Row[hv_I].D(); m_x = hv_Column[hv_I].D();m_savePT.x = m_x; m_savePT.y = m_y;CString str; str.Format("%.0f", m_x); SetDlgItemText(IDC_EDITX, str);str.Format("%.0f", m_y); SetDlgItemText(IDC_EDITY, str);} }} // catch (Exception) catch (HException& HDevExpDefaultException) { HDevExpDefaultException.ToHTuple(&hv_Exception);TupleReplace((hv_ResultData), 0, -1, &(hv_ResultData)); //tuple_replace (ResultData, 4, InputParams[0], ResultData) }return; }
三、模拟鼠标点击代码
用SendInput模拟鼠标点击
void mouseClick(int x, int y) { // 设置鼠标位置 SetCursorPos(x, y); // 定义鼠标事件结构体 INPUT input[3]; ZeroMemory(input, sizeof(input));input[0].type = INPUT_MOUSE; input[0].mi.dwFlags = MOUSEEVENTF_MOVE; // 鼠标左键按下 input[1].type = INPUT_MOUSE; input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;// 鼠标左键释放 input[2].type = INPUT_MOUSE; input[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;// 发送鼠标事件 SendInput(3, input, sizeof(INPUT));}
四、定时器
在定时器中完成自动截图、搜索坐标、模拟鼠标操作。
void CsimmouseDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nIDEvent == 1) { CString str; POINT pt; ::GetCursorPos(&pt);m_autocnt++; if (m_autoclick) { if (m_autocnt > 10) { m_savePT.x = -1; m_savePT.y = -1;SavePic("app.bmp", NULL); if(m_autoclick) myfind(); if (m_savePT.x >= 0 && m_savePT.y >= 0) { mouseClick(m_savePT.x, m_savePT.y);m_cnt++;TCHAR sz[512]; SYSTEMTIME st; GetLocalTime(&st);memset(sz, 0, sizeof(sz)); sprintf_s(sz, "%d-%d-%d %d:%d:%d pt=(%d,%d)\r\n",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond, m_savePT.x, m_savePT.y);SetDlgItemText(IDC_EDITInfo, sz); }m_autocnt = 0; } }str.Format("x=%d y=%d cnt=%d auto=%d (%.2f %.2f)", pt.x, pt.y, m_cnt, m_autocnt, m_x, m_y); SetWindowText(str); } CDialogEx::OnTimer(nIDEvent); }
五、其他
1)在软件初始化处添加创建定时器SetTimer(1, 1000,NULL);
2)声明的变量
bool m_autoclick;
int m_autocnt;
bool SavePic(std::string name, HWND hWnd);
double m_x, m_y;
void myfind();
POINT m_savePT;
3) 添加的控件
Edit控件IDC_EDITX, IDC_EDITY,IDC_EDITInfo
CheckBox控件IDC_CHECKAutoClick