共有回帖数 0 个
- windows编程入门三:鼠标消息和打豆豆外挂(玩不赢你咱写外挂!)
-
只看楼主
收藏
回复
-
windows是基于消息机制的多任务抢占式操作系统,对于我们广大用户来说,鼠标消息无疑是非常重要的消息。
鼠标消息共有二十一种,我们一般只需要了解其中的一些。分别对应左右键的点击,释放,双击。还有就是鼠标的移动。他们分别是
左
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
右
WM_RBUTTONDOWN
WM_RBUTTONUP
WM_RBUTTONDBLCLK
还有鼠标移动WM_MOUSEMOVE。
对于这些消息,我们还需要了解的是他们的lParam,这里存放着鼠标的位置,我们用宏LOWORD取lParam的低字得到相对于窗口的x坐标,用HIWORD取lParam的高字得到相对于窗口的y坐标。
对于我们的程序,我们可以在窗口过程中增加对鼠标消息的响应。像这样:
switch(message)
{
case WM_LBUTTONDOWN
{
//这里做处理
}
}
我在后面会给出一个小工具的源码来具体告诉大家对这个的处理。
接下来的内容对写这种外挂非常重要了。那就是对鼠标消息的模拟。
所谓模拟,就是自己发送鼠标消息。
一般有两种模拟方法,第一种是用mouse_event函数。我们在外挂中将采用这种方法。
mouse_event有五个参数,第一个是我们的动作,比方说MOUSEEVENTF_LEFTDOWN,MOUSEEVENTF_LEFTUP。就相当于WM_LBUTTONDOWN,WM_LBUTTONUP。
第二第三是鼠标的位置,不过是相对于当前鼠标的位置。
第四第五不管他们,都置0。
第二种方法就是发送鼠标消息给固定的窗口了,比方说我想让某个窗口产生鼠标在某位置点击一下的效果,我们可以先用FindWindow取得目标窗口的句柄,然后
SendMessage(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
SendMessage(hwnd,WM_LBUTTONUP,MK_LBUTTON,lParam);
其中wParam标志的是还有什么键按下了。比方说还按着ctrl,这里就必须是MK_CONTROL。
对lParam可以用MAKELPARAM(低字(表示x),高字(表示y))。
那我们先来看外挂是如何的吧!外挂的界面很简单,是一个对话框,上面只有一个确定的按钮。我就不贴图了。大家看了“一”,很容易就作出来了。下面代码。
#include windows.h
#include "resource.h"
#define LIGHTBLUE 13684850
#define BLUE 16740884
#define GREEN 1363988
#define PURPLE 13660880
#define BROWN 1340112
#define ORANGE 1352191
#define RED 7434751
#define GREY 10592673
#define LIGHTBROWN 7524560
#define PINK 16691709
#define BLANKWHITE 16777215
#define BLANKGREY 15592941
BOOL CALLBACK DlgMain(HWND,UINT,WPARAM,LPARAM);
HDC hScrnDC;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgMain);
return 0;
}
BOOL CALLBACK DlgMain(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
{
hScrnDC = CreateDC("DISPLAY",NULL,NULL,NULL);
return TRUE;
}
case WM_CLOSE:
{
DeleteDC(hScrnDC);
EndDialog(hwnd,0);
return TRUE;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:
{
COLORREF map[15][23];
COLORREF Color[4];
int i,j,s,t;
for(i = 0;i 15;i++)
{
for(j = 0;j 23;j++)
{
map[j] = GetPixel(hScrnDC,150+j*25+12,295+i*25+12);
}
}
for(i = 0;i 15;i++)
{
for(j = 0;j 23;j++)
{
switch(map[j])
{
case BLANKWHITE:
case BLANKGREY:
{
for(s = 1;i-s = 0;s++)
{
if(map[i-s][j] != BLANKWHITE && map[i-s][j] != BLANKGREY)
{
Color[0] = map[i-s][j]; //top
break;
}
}
if(i-s 0)
Color[0] = 0;
for(s = 1;j-s = 0;s++)
{
if(map[j-s] != BLANKWHITE && map[j-s] != BLANKGREY)
{
Color[1] = map[j-s]; //left
break;
}
}
if(j-s 0)
Color[1] = 1;
for(s = 1;i+s 15;s++)
{
if(map[i+s][j] != BLANKWHITE && map[i+s][j] != BLANKGREY)
{
Color[2] = map[i+s][j]; //botton
break;
}
}
if(i+s = 15)
Color[2] = 2;
for(s = 1;j+s 23;s++)
{
if(map[j+s] != BLANKWHITE && map[j+s] != BLANKGREY)
{
Color[3] = map[j+s]; //right
break;
}
}
if(j+s = 23)
Color[3] = 3;
for(s = 0;s 4;s++)
{
for(t = s+1;t 4;t++)
{
if(Color[s] == Color[t])
{
POINT position;
GetCursorPos(&position);
SetCursorPos(150+j*25+12,295+i*25+12);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
SetCursorPos(position.x,position.y);
SetWindowPos(hwnd,HWND_TOPMOST,0,0,200,100,SWP_SHOWWINDOW);
goto END;
}
}
}
break;
}
}
}
}
END:
return TRUE;
}
}
}
}
return FALSE;
}
大家最好先看看代码。
不过我这个代码有点小失误,最好把IDOK中的处理封装到一个或几个函数中,我直接在里面写了一大堆,搞得下面一大堆“}”,我都不知道到哪里break了,没办法,直接用goto!大家千万别学我,要引以为戒。
关于开头的一些define,是我用下面要给大家的小工具取得的豆豆的颜色。那些豆豆格子的位置,也是我用这个工具取得的。我采用的是硬编码的方式,对于不同屏幕的电脑,这个程序不具有通用性,大家可以自己用下面的小工具取得这些后修改。我电脑中第一个格子的位置是150,295,大小是25*25。
程序开始,把格子遍历了一遍,取每个格子中间的色彩标示这个格子。保存在一个二维数组中。
然后遍历格子,得到没有豆豆的格子,判断它可不可以点击。这些都不用我多说。
取得适当格子后,我们就要模拟鼠标消息了。
我们先用GetCursorPos取得当前鼠标位置,以便模拟后恢复。这个函数把位置返回在POINT的结构体中。POINT里面就两个东西,一个是x,一个是y,都是int型的。
然后设置鼠标位置,SetCursorPos。
模拟鼠标消息。由于我们已经设置好了鼠标位置,所以我们对mouse_event第二三个参数就直接赋零了。
然后恢复鼠标位置。(大家可以用这个做点坏事,比方说:点击开始,关闭计算机……你懂的)。
由于我们相当于在浏览器窗口中点击了,所以这之后对话框就最小化了,我们用 SetWindowPos(hwnd,HWND_TOPMOST,0,0,200,100,SWP_SHOWWINDOW);恢复它。这个函数怎么用,大家去查msdn。
这样,一个外挂就完成了。我这个是一步一步来的,点一下确定消除一次。大家完全可以做一个秒杀的!
接下来是小工具了,大家看代码。
我讲讲两个函数,大家就应该能看懂了。
SetCapture(hwnd)函数,本来鼠标消息只能发送给你鼠标下面的窗口的,这个函数把鼠标抓住,所有的鼠标消息就发给hwnd标志的窗口了。当然,之后便要ReleaseCapture了!
vc6里面的小工具spy++中findwindow应该就是用了这个。
大家现在应该能看懂代码了,我也不多说,收工!有问题下面问。
#include windows.h
#include "resource.h"
BOOL CALLBACK DlgMain(HWND,UINT,WPARAM,LPARAM);
HDC hScrnDC;
BOOL bCapture;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgMain);
return 0;
}
BOOL CALLBACK DlgMain(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
{
hScrnDC = CreateDC("DISPLAY",NULL,NULL,NULL);
return TRUE;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_OK:
{
int x = GetDlgItemInt(hwnd,IDC_XPOSITION,NULL,FALSE);
int y = GetDlgItemInt(hwnd,IDC_YPOSITION,NULL,FALSE);
COLORREF color = GetPixel(hScrnDC,x,y);
SetDlgItemInt(hwnd,IDC_PIXEL,(UINT)color,FALSE);
int error = GetLastError();
return TRUE;
}
}
}
case WM_LBUTTONDOWN:
{
bCapture = TRUE;
SetCapture(hwnd);
return TRUE;
}
case WM_MOUSEMOVE:
{
if(bCapture)
{
POINT position;
GetCursorPos(&position);
SetDlgItemInt(hwnd,IDC_XPOSITION,position.x,FALSE);
SetDlgItemInt(hwnd,IDC_YPOSITION,position.y,FALSE);
}
return TRUE;
}
case WM_LBUTTONUP:
{
bCapture = FALSE;
ReleaseCapture();
return TRUE;
}
case WM_CLOSE:
{
DeleteDC(hScrnDC);
EndDialog(hwnd,0);
return TRUE;
}
}
return FALSE;
}
楼主 2015-12-05 14:15 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知