首页
社区
课程
招聘
[求助]getpixel小问题
发表于: 2007-12-29 11:04 5336

[求助]getpixel小问题

2007-12-29 11:04
5336
我在做一个flash益智游戏的辅助工具(算不同的时候应该怎么走)
现在策略算法已经搞定了,就差棋盘的输入。

我打算用取向素的方法来录入棋盘。
代码如下:

POINT Point1,Point2;
HDC hdc;
COLORREF color;
HWND hwnd;
GetCursorPos( &Point1);
hwnd=FindWindowA(NULL,"ccc");(iexplorer的窗口名)
if(hwnd)
            MessageBoxA(NULL,"found","info",0);
SetForegroundWindow(hwnd);
hdc=GetDC(hwnd);
if(hdc)
            MessageBoxA(NULL,"found hdc","info",0);
color=GetPixel(hdc,Point1.x ,Point1.y);
printf("%x",color);

问题1:Findwindow中如果我调用FindWindowA(NULL,"C\a.swf");返回值是NULL(这个窗口却是开着的),不知为何?
问题2:找到窗口,取得hdc后color=GetPixel(hdc,Point1.x ,Point1.y); 之后printf("%x",color);得到的结果竟然是0xffffffff.
不知为何?
是iexplorer不支持getpixel还是什么?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 214
活跃值: (11)
能力值: ( 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);
        }

=====================================================
平时在学校里没网线,可能要长期潜水了。

希望能给楼主带来帮助
2007-12-30 14:05
0
雪    币: 257
活跃值: (56)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
谢谢,已经搞定。
经实验证明getdc(NULL)就可以了-_-!!并不用取什么窗口的句柄(我感觉在opengl绘图类程序理才须取窗口句柄)。
现在的问题就是这个象素点实在不好确定,棋盘读取的判断老实有失误!:0
2007-12-31 02:58
0
雪    币: 324
活跃值: (91)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
4
多取几个点,每个棋子取2个点不够就取三个点。。。取的点要是每个棋子最有“特色”的,HOHO
2007-12-31 11:47
0
雪    币: 257
活跃值: (56)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
我不仅要取点,而且要判断棋盘位置(flash游戏,棋盘不规则)。我索性写了个修正函数,判断测了修正就得了。
最嘛分的还是深层搜索问题。我现在这点时间只写了搜索一层。要写多层恐怕要双倍的时间-_-!!
2008-1-1 18:23
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
6
完全不懂得说 . 学习. 不知道SWF有没有调试API用.
2008-1-3 00:10
0
游客
登录 | 注册 方可回帖
返回
//