能力值:
( LV6,RANK:90 )
|
-
-
2 楼
这个问题比较复杂。
我没有推敲过这方面,但上个暑假写过类似的程序,希望可以提供lz一点参考
不好意思的的是,我没有调试过lz上面的程序,但按照我自己的经验+感觉,那样子getpixel确实可以得到正确的像素,是不是Point1要用相对的坐标?似乎要查msdn了
还有一个问题getpixel在vista下支持得不是很好(速度奇慢;且不是实时,而是从缓冲区读取).
用其他办法来代替:
把整个desktophwnd的图形截取下来,再一次性全保存到位图数组里,通过窗口的坐标找到屏幕(位图)的坐标,通过实验证实这样一次的速度肯定比64次getpixel快。
这种基于像素的游戏辅助工具我可以给个例子:
(游戏是类似国际象棋的棋盘式的,在每个格子上取两个像素点,进行hash编号……其中calc函数对游戏的下步操作进行运算)
直接getpixel的代码:
//一些申明
extern int __cdecl Calc(COLORREF [PoolSizeX][PoolSizeY][2],long*,long*,long*,long*);
char temp[100];
BITMAPINFO BitmapInfo;
long PoolBitmap[384][384];
COLORREF PoolPixel[384][384];
……………………
COLORREF OrgMap[PoolSizeX][PoolSizeY][2];
int i,j;
POINT Point1,Point2;
HWND hTarget;
#ifndef AERO
HDC hdcTarget;
#else
HWND hDesktop;
HDC hdcDesktop;
HDC hdc,hdcMem;
HBITMAP hBitmap;
HBITMAP hOldBitmap;
#endif
//相对坐标
enum{PoolSizeX=8,PoolSizeY=8};
enum{PoolBaseX=270,PoolBaseY=96,PoolHeight=48,PoolWidth=48};
//程序的消息处理函数
switch (message)
{
case WM_CREATE: /*V键不常用……寿命也比较长*/
if(RegisterHotKey(hWnd,1,/*MOD_CONTROL*/0,'V')==0)MessageBox(hWnd,"热键注册失败","错误",MB_OK);
break;
case WM_HOTKEY:
hTarget=GetForegroundWindow();
hdcTarget=GetWindowDC(hTarget);
InvalidateRect(hTarget,NULL,1);
for(j=0;j<PoolSizeY;j++){ /*注意扫描顺序*/
for(i=0;i<PoolSizeX;i++){
/*经试验证实,需要用两个像素来确定棋子*/
OrgMap[i][j][0]=GetPixel(hdcTarget,PoolBaseX+PoolWidth*i+PoolWidth/2-3,PoolBaseY+PoolHeight*j+PoolHeight/2);
OrgMap[i][j][1]=GetPixel(hdcTarget,PoolBaseX+PoolWidth*i+PoolWidth/2,PoolBaseY+PoolHeight*j+PoolHeight/2-3);
}
}
ReleaseDC(hTarget,hdcTarget);
/* 返回第几个格子之间交换,并不返回坐标 */
i=Calc(OrgMap,&Point1.x,&Point1.y,&Point2.x,&Point2.y);
//if(i<=0)break;
//For debug...
if(i==-1){
SetWindowText(hWnd,"Hash Error!");
break;
}
if(i==0){
SetWindowText(hWnd,"Can not find!");
break;
}
wsprintf(temp,"(%d,%d)<->(%d,%d)",Point1.x,Point1.y,Point2.x,Point2.y);
SetWindowText(hWnd,temp);
Point1.x=PoolBaseX+PoolWidth*Point1.x+PoolWidth/2;
Point1.y=PoolBaseY+PoolHeight*Point1.y+PoolHeight/2;
MapWindowPoints(hTarget,NULL,&Point1,1);
SetCursorPos(Point1.x,Point1.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
Point2.x=PoolBaseX+PoolWidth*Point2.x+PoolWidth/2;
Point2.y=PoolBaseY+PoolHeight*Point2.y+PoolHeight/2;
MapWindowPoints(hTarget,NULL,&Point2,1);
SetCursorPos(Point2.x,Point2.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
==========================================================
为了适应vista,原来代码改为截屏并保存位图:
switch (message)
{
case WM_CREATE: /*V键不常用……寿命也比较长*/
if(RegisterHotKey(hWnd,1,/*MOD_CONTROL*/0,'V')==0){
MessageBox(hWnd,"热键注册失败","错误",MB_OK);
SendMessage(hWnd,WM_CLOSE,0,0);
}
break;
case WM_HOTKEY:
hTarget=GetForegroundWindow();
#ifndef AERO
hdcTarget=GetWindowDC(hTarget);
#else
hdc=GetDC(hWnd);
hDesktop=GetDesktopWindow();
hdcDesktop=GetWindowDC(hDesktop);
hdcMem=CreateCompatibleDC(hdcDesktop);
hBitmap=CreateCompatibleBitmap(hdcDesktop,384,384);
//hBitmap=GetSrcBit(hdcDesktop,1034,1024);
Point1.x=PoolBaseX;Point1.y=PoolBaseY;
MapWindowPoints(hTarget,NULL,&Point1,1);
hOldBitmap=(HBITMAP)SelectObject(hdcMem,hBitmap);
BitBlt(hdcMem,0,0,384,384,hdcDesktop,Point1.x-2,Point1.y-2,SRCCOPY);
hBitmap=(HBITMAP)SelectObject(hdcMem,hOldBitmap);
BitmapInfo.bmiHeader.biSize = sizeof(BitmapInfo.bmiHeader);
BitmapInfo.bmiHeader.biWidth = 384;
BitmapInfo.bmiHeader.biHeight = 384;
BitmapInfo.bmiHeader.biPlanes = 1;
BitmapInfo.bmiHeader.biBitCount = 32;
BitmapInfo.bmiHeader.biCompression = BI_RGB;
BitmapInfo.bmiHeader.biSizeImage = 384 * 32 * 384;
BitmapInfo.bmiHeader.biClrUsed = 32;
BitmapInfo.bmiHeader.biXPelsPerMeter=1;
BitmapInfo.bmiHeader.biYPelsPerMeter=1;
BitmapInfo.bmiHeader.biClrImportant = 0;
GetDIBits(hdcMem,hBitmap,0,384,&PoolBitmap[0][0],&BitmapInfo,DIB_RGB_COLORS);
for(i=0;i<384;i++)
for(j=0;j<384;j++)
PoolPixel[j][383-i]=RGB(((PoolBitmap[i][j]>>16)&0xff),((PoolBitmap[i][j]>>8)&0xff),((PoolBitmap[i][j]>>0)&0xff));
/* for(i=0;i<384;i++)
for(j=0;j<384;j++){
SetPixel(hdc,i+10,j+10,PoolPixel[i][j]);
}*/
#endif
for(j=0;j<PoolSizeY;j++){ /*注意扫描顺序*/
for(i=0;i<PoolSizeX;i++){
/*经试验证实,需要用两个像素来确定棋子*/
#ifdef AERO
OrgMap[i][j][0]=PoolPixel[PoolWidth*i+PoolWidth/2-3][PoolHeight*j+PoolHeight/2];
OrgMap[i][j][1]=PoolPixel[PoolWidth*i+PoolWidth/2][PoolHeight*j+PoolHeight/2-3];
#else
OrgMap[i][j][0]=GetPixel(hdcTarget,PoolBaseX+PoolWidth*i+PoolWidth/2-3,PoolBaseY+PoolHeight*j+PoolHeight/2);
OrgMap[i][j][1]=GetPixel(hdcTarget,PoolBaseX+PoolWidth*i+PoolWidth/2,PoolBaseY+PoolHeight*j+PoolHeight/2-3);
#endif
}
}
#ifndef AERO
ReleaseDC(hTarget,hdcTarget);
#else
ReleaseDC(hWnd,hdc);
ReleaseDC(hDesktop,hdcDesktop);
DeleteDC(hdcMem);
DeleteObject(hBitmap);
#endif
/* 返回第几个格子之间交换,并不返回坐标 */
i=Calc(OrgMap,&Point1.x,&Point1.y,&Point2.x,&Point2.y);
//if(i<=0)break;
//For debug...
if(i==-1){
SetWindowText(hWnd,"Hash Error!");
break;
}
if(i==0){
SetWindowText(hWnd,"Can not find!");
break;
}
wsprintf(temp,"(%d,%d)<->(%d,%d)",Point1.x,Point1.y,Point2.x,Point2.y);
SetWindowText(hWnd,temp);
Point1.x=PoolBaseX+PoolWidth*Point1.x+PoolWidth/2;
Point1.y=PoolBaseY+PoolHeight*Point1.y+PoolHeight/2;
MapWindowPoints(hTarget,NULL,&Point1,1);
SetCursorPos(Point1.x,Point1.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
Point2.x=PoolBaseX+PoolWidth*Point2.x+PoolWidth/2;
Point2.y=PoolBaseY+PoolHeight*Point2.y+PoolHeight/2;
MapWindowPoints(hTarget,NULL,&Point2,1);
SetCursorPos(Point2.x,Point2.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
=====================================================
平时在学校里没网线,可能要长期潜水了。
希望能给楼主带来帮助
|