首先介绍下要用到的几个API函数

1、通过标题获取窗口句柄

HWND hGame=FindWindow(NULL,_T("QQ游戏 - 连连看角色版"));

2、 获得游戏窗口的位置信息

RECT gameRect

GetWindowRect(hGame,&gameRect);

3、改变鼠标位置坐标

SetCursorPos(x,y);

4、得到鼠标的位置坐标

POINT ps;

GetCursorPos(&ps);

5、获得窗口进程ID

DWORD processid ;

GetWindowThreadProcessId(hGame,&processid);

6、打开指定进程

HANDLE processH=OpenProcess(PROCESS_ALL_ACCESS,false,processid);

7、读取指定进程内存数据

DWORD byread;
 LPCVOID pStear=(LPCVOID)0x00189F78; 
 LPVOID nBuff[11][19];//读取的数据存入缓冲区
 ReadProcessMemory(processH,pStear,nBuff,11*19,&byread);

在VS2008下新建个MFC的对话框项目

1、打开对话框,拖一个Edit Control进来用来显示游戏读取过来的数据

属性Vertical Scroll设为true,want return设为true,Multiline设为true

右击Edit添加变量,类型为CString,类别为value变量名m_edit1

再往窗体上托两个按钮

2、练练看游戏如图

其实这是一个11*19 的矩阵,在内存中每个棋子占用一个字节(8位),一共能表示256个结果

首先要找左上角棋子的地址,然后就能推算出其他棋子的位置地址,打开CE多点几次就能把第一个棋子的地址找到,我找到的是0x00189F78,每个电脑基本都一样,因为这个是程序的虚拟地址

使用OD查看这短内存区域的数据如下图

然后对应的游戏界面

可以观察出,为值为00的表示没有棋子,非零的表示有棋子,数值相同表示棋子一样。

经过上面分析,我们开始把棋盘数据读入到自己的程序里

首先定义一个存放数据的全局变量,和窗口句柄

byte chessdata[11][19];

HWND hGame;//游戏窗口句柄

左击清除按钮给按钮添加事件

HWND hGame;
byte chessdata[11][19];///*****棋盘的数据**************/
void Cyh_llkwgDlg::OnBnClickedButton1()
{///1获取窗口句柄hGame =::FindWindow(NULL,_T("QQ游戏 - 连连看角色版"));//2 获取窗口进程DWORD processid ;::GetWindowThreadProcessId(hGame,&processid);//3打开指定进程HANDLE processH=::OpenProcess(PROCESS_ALL_ACCESS,false,processid);//读取指定内存地址的数据DWORD byread;LPCVOID pStear=(LPCVOID)0x00189F78; //连连看基址LPVOID nBuff=(LPVOID)chessdata; //存放棋盘的数据::ReadProcessMemory(processH,pStear,nBuff,11*19,&byread);//显示数据char buf[16];m_edit1 = "";//清空棋盘for(int y=0;y<11;y++){for(int x=0;x<19;x++){_itoa_s(chessdata[y][x],buf,16);//字节转换成字符串m_edit1 += buf;m_edit1 +=" ";}m_edit1 +="\r\n";}UpdateData(false);
}

然后打开游戏,点击清除按钮

这是读取的数据,个棋盘界面,自己看看 是不是发现跟棋盘是一一对应。哈哈到这步,我们已经把重要的工作都完成了,现在我们只要分析棋盘,写个算法模拟鼠标点击同样的棋子我们就成功了!

如果有兴趣的可以自己写算法,不想写的可以使用这个

//检查两点能否消除

//检查亮点能否消除
bool Check2p(POINT a,POINT b)
{CChessPoint p1(a),p2(b);POINT  pa,pb;//转角点int x,y;// 如果2点为同一点 则返回假if ((a.x==b.x) && (a.y==b.y ))  { return false;} elseif ((chessdata[a.y][a.x]==0) || (chessdata[b.y][b.x]==0))    { return false;} elseif (chessdata[a.y][a.x]!=chessdata[b.y][b.x])   { return false;}pa=a;pb=b;// 在横向一条线上 y坐标 相同if (a.y==b.y)  {     // 2点在y轴相邻if ((p1.right.x==p2.p.x) || (p1.left.x==p2.p.x))      { return true;   }//检测 这条线是否有一条路径相通if (CheckLine(p1.right,p2.left )) {return true; }//检测 上下//y 上pa=a;pb=b;if ((p1.up.y >=0) && (p1.up.y<=10)) for ( y=0 ;y<=p1.up.y;y++){pa.y=y;pb.y=y;if (CheckLine(pa,p1.up) && CheckLine(pb,p2.up ) && CheckLine(pa,pb))  { return true; }}// y下pa=a;pb=b;if ((p1.down.y >=0)&& (p1.down.y <=10)) for ( y=p1.down.y;y<=10;y++){pa.y=y;pb.y=y;if (CheckLine(pa,p1.down ) && CheckLine(pb,p2.down ) && CheckLine(pa,pb))  { return true; }                                                }//检测 左右    因为 y轴相等,所以不存在左右路径} else//纵向一条线  x 坐标 相同if (a.x==b.x){//x下上 相邻不if ((p1.down.y==p2.p.y ) || (p1.up.y==p2.p.y))   { return true;   }//检测 这条线是否有一条路径相通if (CheckLine(p1.down,p2.up) )  { return true;    }//检测 上下   国为x 轴相等 所以不存在路径//检测 左右//x左pa=a;pb=b;for (x=0 ;x<=p1.left.x ;x++){pa.x=x;pb.x=x;if (CheckLine(pa,p1.left) && CheckLine(pb,p2.left ) && CheckLine(pa,pb))  { return true;  }}//x右pa=a;pb=b;for (x=p1.right.x;x<=18;x++){pa.x=x;pb.x=x;if (CheckLine(pa,p1.right ) && CheckLine(pb,p2.right ) && CheckLine(pa,pb))  { return true;  }}} else//xy 坐标 都不相同 {{{{{{{pa=a;pb=b;if (a.x>b.x)  {   // p2点 在 左 leftxxxxxxxxxxxxxxxxx  找x轴路径for (x=0;x<=p2.left.x;x++){pa.x=x;pb.x=x;if (CheckLine(pa,p1.left) && CheckLine(pa,pb) && CheckLine(pb,p2.left))  {return true; }} // end forfor (x=p2.right.x ;x<= p1.left.x;x++){pa.x=x;pb.x=x;if (CheckLine(p2.right,pb) && CheckLine(pa,pb)&& CheckLine(pa,p1.left))  {return true; }}for (x=p2.right.x;x<=18;x++){pa.x=x;pb.x=x;if (CheckLine(p1.right ,pa)&& CheckLine(p2.right ,pb) && CheckLine(pa,pb))  { return true; }}/yyyyyyyyyyyyyyyyyyyy 找y轴路径 由于是从上向下 搜索 所以p1.y>p2.ypa.x=a.x;   pb.x=b.x; //初始化坐标 y軕渐变for ( y=0 ;y<=p1.up.y;y++)    //1段{pa.y=y;pb.y=y;if (CheckLine(pb,pa) && CheckLine(pa,p1.up) && CheckLine(pb,p2.up))      { return true;}}for (y=p1.down.y ;y<=p2.up.y;y++)//2段{pa.y=y;pb.y=y;if (CheckLine(pb,pa)&& CheckLine(p1.down,pa) && CheckLine(pb,p2.up))   {return true;}}///for (y=p2.down.y ;y<=10 ;y++) //3段{///pa.y=y;pb.y=y;if (CheckLine(pb,pa) && CheckLine(p1.down,pa) && CheckLine(p2.down,pb))   { return true;   }}} elsep2点  在 右 right a.x>b.x{pa.y=a.y;   pb.y=b.y; //初始化坐标for (x=0 ;x<= p1.left.x ;x++);{pa.x=x;pb.x=x;if (CheckLine(pa,pb)&& CheckLine(pa,p1.left)&& CheckLine(pb,p2.left))  {return true;}}/for (x=p1.right.x ;x<=p2.left.x;x++){pa.x=x;pb.x=x;if (CheckLine(pa,pb)&& CheckLine(p1.right,pa)&& CheckLine(pb,p2.left))  { return true;}}///for (x=p2.right.x ;x<=18;x++){pa.x=0;pb.x=x;if (CheckLine(pa,pb) && CheckLine(p1.right,pa)&& CheckLine(p2.right,pb)) {return true; }}///yyyyyyyyyyyyyyyyyy   y轴渐变pa.x =a.x;   pb.x =b.x ; //初始化坐标if ((p1.up.y>=0) && (p1.up.y<=10)){for (y=0 ;y<=p1.up.y ;y++)    //1段{pa.y=y;pb.y=y;if (CheckLine(pa,pb)&& CheckLine(pa,p1.up) && CheckLine(pb,p2.up))  { return true; }}}//pa.x =a.x;   pb.x =b.x ; //初始化坐标if ((p1.down.y<=10) && (p2.up.y>=0)) {for (y=p1.down.y ;y<=p2.up.y;y++)  //2段{pa.y=y;pb.y=y;if (CheckLine(pa,pb)&& CheckLine(p1.down,pa) && CheckLine(pb,p2.up))  { return true;}                                                                          }}pa.x =a.x;   pb.x =b.x ; //初始化坐标if (p2.down.y <=10) {for ( y=p2.down.y;y<=10;y++)           //3段{pa.y=y;pb.y=y;if (CheckLine(pa,pb) && CheckLine(p1.down,pa)&& CheckLine(p2.down ,pb))  { return true; }}                                                                          }}}//xy 坐标 都不相同 }}}}}}}}}return false;
}
bool CheckLine(  POINT p1,POINT p2)
{int x,y,t;    //同一线上的两点间 全为0 则返回真 //如果 p1==p2 也返回真if ((p1.x==p2.x)&&(p1.y==p2.y) && (chessdata[p1.y][p1.x]==0) && (chessdata[p2.y][p2.x]==0))  {return  true;   }elseif ((p1.x<0) || (p1.x>18) || (p1.y<0) || (p1.y>10) ||(p2.x<0) || (p2.x>18) || (p2.y<0) || (p2.y>10) )  {return  false; }if (p1.x==p2.x)     //如果X轴相等则 比较{if (p1.y>p2.y) {t=p1.y;p1.y=p2.y;p2.y=t;}for (y=p1.y;y<=p2.y;y++){if (chessdata[y][p1.x]!=0 ) {return false;}}} if (p1.y==p2.y) {    //如果Y轴相等 则比较if (p1.x > p2.x)  {t=p1.x;p1.x=p2.x ;p2.x=t;}for(x=p1.x;x<=p2.x;x++){if (chessdata[p1.y][x]!=0 ) {return  false;}};};return  true;
};

修改消除按钮时间里面的代码如下

void Cyh_llkwgDlg::OnBnClickedButton1()
{///1获取窗口句柄hGame =::FindWindow(NULL,_T("QQ游戏 - 连连看角色版"));//2 获取窗口进程DWORD processid ;::GetWindowThreadProcessId(hGame,&processid);//3打开指定进程HANDLE processH=::OpenProcess(PROCESS_ALL_ACCESS,false,processid);//读取指定内存地址的数据DWORD byread;LPCVOID pStear=(LPCVOID)0x00189F78; //连连看基址LPVOID nBuff=(LPVOID)chessdata; //存放棋盘的数据::ReadProcessMemory(processH,pStear,nBuff,11*19,&byread);//显示数据char buf[16];m_edit1 = "";//清空棋盘for(int y=0;y<11;y++){for(int x=0;x<19;x++){_itoa_s(chessdata[y][x],buf,16);//字节转换成字符串m_edit1 += buf;m_edit1 +=" ";}m_edit1 +="\r\n";}UpdateData(false);//chessdataPOINT p1,p2;int x1,y1,x2,y2;for(y1=0;y1<11;y1++){  //列for(x1=0;x1<19;x1++){ //行for(y2=y1;y2<11;y2++){ //第二次列for(x2=0;x2<19;x2++){ //第二次行if((chessdata[y1][x1]==chessdata[y2][x2])){  //判断 第二次跟第一次数值是否相同//检测这两个棋子能否消除p1.y=y1;p1.x=x1;p2.y=y2;p2.x=x2;if(Check2p(p1,p2)){//检测两点是否能消除click2p(p1,p2);}}}}}}
}

完成,编译,打开游戏,进入一个房间,点击消除~~~~

哈哈,瞬间秒杀,是不是感觉自己好腻害~~后面的自动消除可以加个定时器自己来完成

下面是源程序代码和编译好的程序

http://download.csdn.net/detail/u010852544/8600323

用MFC开发1连连看辅助器相关推荐

  1. MFC+DuiVision结合VLC播放器开发直播客户端

    MFC+DuiVision结合VLC播放器开发直播客户端 说明:windows 10 VS2015社区版 关键字:c++ VisualStudio DuiVision VLC播放器 开发这个视频播放器 ...

  2. VC,MFC开发技巧收集

    (mainmenu->GetSubMenu (0))->DeleteMenu(i,MF_BYPOSITION); break; } } 十五.改变应用程序的图标 缺 十六.另一种改变窗口标 ...

  3. 【Visual Studio 2019】创建 MFC 桌面程序 ( 安装 MFC 开发组件 | 创建 MFC 应用 | MFC 应用窗口编辑 | 为按钮添加点击事件 | 修改按钮文字 | 打开应用 )

    文章目录 一.安装 MFC 开发组件 二.创建 MFC 应用 三.MFC 应用窗口编辑 四.为按钮添加点击事件 五.修改按钮文字 六.打开系统其它应用 七.博客源码 一.安装 MFC 开发组件 打开 ...

  4. 编程开发使用的辅助软件大全

    (今天太晚了,以后再慢慢写) 说明: 本文提及的所有软件都至少是笔者曾经使用过的,而不是阅自其它文献. 对于其中的某些软件,笔者也编写过其完整的安装教程,可阅读笔者编写的其它博客. 本文只是给出编程人 ...

  5. C++ MFC实现基于RFID读写器的上位机软件

    C++ MFC实现基于RFID读写器的上位机软件 该博客涉及的完整工程托管在https://github.com/Wsine/UpperMonitor,觉得好请给个Star (/▽\=) 运行和测试环 ...

  6. QT开发和MFC开发的经典案例

     大家来欣赏下Qt写的程序(摘自百度百科) 3DSlicer, a free open source software for visualization and medical image co ...

  7. MFC开发——卡拉OK字幕制作

    依然是为了赶老师作业,又去学了点东西,然后做了个小项目.首先在开始做项目之前,说一下整体思路,要实现卡拉OK字幕效果,就要对文本类与定时器有一定的掌握,通过定时器的更新,可以实现字体颜色的变化,与字幕 ...

  8. 痞子衡嵌入式:飞思卡尔Kinetis开发板OpenSDA调试器那些事(上)- 背景与架构

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis MCU开发板板载OpenSDA调试器(上篇). 众所周知,嵌入式软件开发几乎离不开调试器,因为写一个稍有代码规模 ...

  9. android图库实现,Android实现简单图库辅助器

    写在前面 实际开发经常会遇到读取相册或者拍照功能,网上也很非常多图库框架,都各有风格,也因此与自己的项目格格不入.再者,框架api太多,需要的配置太多,还要吃力研究.所以,本人摸索大多图库框架,提炼核 ...

  10. 200行Python 实现的qq连连看辅助, 用于学习, 请不要拿去伤害玩家们

    Linux编程点击右侧关注,免费入门到精通! 作者丨Laziji https://laboo.top/2018/11/07/lianliankan/ 前言 Python 实现的qq连连看辅助, 仅用于 ...

最新文章

  1. mysql 按条件导出数据_mysql命令行按任意查询条件导出指定数据
  2. 数学之美 系列九 -- 如何确定网页和查询的相关性
  3. NB-IOT终端技术新突破 中兴微电子加快IoT布局
  4. java jdbc数据库五种连接方式
  5. UVa OJ 128 - Software CRC (软件CRC)
  6. 1.在c 语言中字符型占,C程序设计试题1.doc
  7. js 动态创建注释节点 createComment
  8. bootstrap-multiselect加载本地数据
  9. 解决xhost:unable to open display的问题
  10. jenkins-系统管理-节点管理进去报错
  11. 随心所欲的DateTime显示格式
  12. C语言学习系列(六)基本语法
  13. ASP.NET MVC Framework体验(1):从一个简单实例开始(转)
  14. python平均分计算器_招募:基于python的召唤师全时段全技能(含均值AI)计算器全程测试...
  15. Eviews(8)进行线性回归(ols一元)与格兰杰(Granger)因果关系检验操作步骤
  16. uni-app商城源码/公众号/小程序/APP多端适配
  17. IntelliJ IDEA设置豆沙绿背景
  18. 天津财经大学珠江学院考计算机二级,【2019年12月天津计算机二级考试报名入口已开通】- 环球网校...
  19. 高版本node,无法编译程序,删除所有文件
  20. ABAP Enhancement

热门文章

  1. 【分享】班组5S管理实践办法
  2. win11怎么隐藏任务栏图标?
  3. 怎样用计算机计算矩阵,【活用工具】教你如何用卡西欧fx82es计算机计算复数 矩阵等...
  4. 人工智能数学基础——贝叶斯分析
  5. 贝叶斯决策(Bayesian Decision Theory)
  6. 手写linux系统,在Linux操作系统中使用手写板
  7. C++复习笔记3——类与对象(赋值重载、临时对象、const、static)
  8. Android第四次作业
  9. fcm算法matlab实现,fcm算法matlab
  10. 我能够入职世界顶尖的卡巴斯基,却被国内的安全公司拒之门外