大家好.我的问题已经难倒我身边的VB高手了,朋友无奈之下把偶介绍到这里来.说可以问问别人..
我的问题是这样的.
屏幕上有某个坐标的颜色值是换色的.网页色.格式为000000(黑色)
我要在不知道坐标的前提下去搜索这个颜色.然后达到鼠标移过去的代码..虽然我朋友有给我了方法.但是不实用.我说说他给我的方法吧.
他是截取桌面的图象到PICTURE1的控件里.然后在控件里用GetPixel来搜索这个颜色值.在达到鼠标移过去的方法.但是我不是在静态的桌面上搜索的/.我要在游戏画面里搜索.画面的颜色一直在改变.我试过了用1毫秒截取图象.1毫秒进行颜色找查.但是都没有得到相应的回报..而且搜索的范围极小.虽然有时候会偶尔去找到那个颜色.但是CPU占用率适才是太高了.CPU到了100%..希望那个高手有什么好方法.或者可以把我说的这些内容改得精简点.以下是我的代码.高手见笑了
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Const theScreen = 1
Const theForm = 0
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_MOVE = &H1
Const MOUSEEVENTF_ABSOLUTE = &H8000
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10
Dim a!, x1!, y1!
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Long) As Integer
Private Function MyHotKey(vKeyCode) As Boolean
MyHotKey = (GetAsyncKeyState(vKeyCode) < 0)
End Function
Private Sub Timer2_Timer()
Call keybd_event(vbKeySnapshot, theForm, 0, 0)
DoEvents
Picture1.Picture = Clipboard.GetData(vbCFBitmap)
End Sub
Private Sub Timer3_Timer()
Dim dd As Long, dd1 As Long, dd2 As Long
dd = &H211C10
dd1 = &H211C18
dd2 = &H1028FF
For i = 300 To 800
For j = 180 To 650
If GetPixel(Picture1.hdc, i, j) = dd Then
SetCursorPos i, j
ElseIf GetPixel(Picture1.hdc, i, j) = dd1 Then
SetCursorPos i, j
ElseIf GetPixel(Picture1.hdc, i, j) = dd2 Then
End If
Next j
Next i
End Sub希望高手们不嫌弃小弟的代码.帮忙看看.偶一定会报答大家的!>..

解决方案 »

  1.   

    not in VB. use Assembly language, or C if you set the compiler option right.You need to inject your code into the target process or the display driver to get the speed you needed.
      

  2.   

    给你一个关于图像的文章,其中有你可借鉴之处:VB图像处理之像素的获取和输出 
     
       要处理一个图像,首先要获得该图像的像素值,而VB本身提供的PICTURE控件虽然可以打开很多类型的图片,但是它提供的那个POINT方法读取像素实在是太慢。而使用GetPixel这个API的速度也快不到哪里去,因为PIONT方法本身就是对于GetPixel的一个包装。    在VB中要快速获取一幅在PICTURE中打开的图像比较快速的方法是使用DIB方法,当然还有DDB方法,不过使用DDB方法还需要考虑不同颜色深度的图像的分别处理,在程序的实现上要相对复杂,而使用DIB方法则不必,并且在处理速度上比DDB方法也慢的有限。    过程一:获得一个在PICTURE控件中打开的图像的所有像素。 Public Sub DibGet(ByVal IdSource As Long, XBegin As Long, ByVal YBegin As Long, ByVal XEnd As Long, ByVal YEnd As Long) 
      Dim iBitmap As Long 
      Dim iDC As Long 
      Dim I As LongDim 
      Dim W As Long 
      Dim H As Long   On Error GoTo ErrLine 
      Done = False 
      TimeGet = timeGetTime 
      InPutWid = XEnd - XBegin 
      InPutHei = YEnd - YBegin 
      W = InPutWid + 1 
      H = InPutHei + 1   I = (Bits \ 8) - 1 
      ReDim ColVal(I, InPutWid, InPutHei) 
      With bi24BitInfo.bmiHeader 
       .biBitCount = Bits 
       .biCompression = 0& 
       .biPlanes = 1 
       .biSize = Len(bi24BitInfo.bmiHeader) 
       .biWidth = W 
       .biHeight = H 
      End With   iBitmap = GetCurrentObject(IdSource, 7&) 
      GetDIBits IdSource, iBitmap, 0&, H, ColVal(0, 0, 0), bi24BitInfo, 0& DeleteObject iBitmap 
      Done = True 
      TimeGet = timeGetTime - TimeGetExit Sub 
    ErrLine: 
      MsgBox "错误号:" & Err.Number & ":" & Err.Description 
    End Sub     在这个过程中所用到的只是一些参数的设定和API的调用,不涉及算法。    过程二:图像输出的过程: Public Sub DIBPut(ByVal IdDestination As Long) 
      Dim W As Long 
      Dim H As Long   On Error GoTo ErrLine 
      Done = False 
      TimePut = timeGetTime   W = OutPutWid + 1 
      H = OutPutHei + 1   With bi24BitInfo.bmiHeader 
       .biWidth = W 
       .biHeight = H 
       LineBytes = ((W * Bits + 31) And &HFFFFFFE0) \ 8 
       .biSizeImage = LineBytes * H 
      End With 
      SetDIBitsToDevice IdDestination, 0, 0, W, H, 0, 0, 0, H, ColOut(0, 0, 0), bi24BitInfo.bmiHeader, 0   Done = True 
      TimePut = timeGetTime - TimePut 
      Exit Sub 
    ErrLine: 
      MsgBox Err.Description 
    End Sub     下面解释一下在过程中到的全局变量和数据结构,以及API的定义。    API定义:    删除一个DC Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long     删除一个对象 Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long     选择当前对象 Private Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long     获取DIB Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BitMapInfo, ByVal wUsage As Long) As Long     获取系统时间 Private Declare Function timeGetTime Lib "winmm.dll" () As Long     数据结构定义: Private Type BitMapInfoHeader ''文件信息头——BITMAPINFOHEADER 
      biSize As Long 
      biWidth As Long 
      biHeight As Long 
      biPlanes As Integer 
      biBitCount As Integer 
      biCompression As Long 
      biSizeImage As Long 
      biXPelsPerMeter As Long 
      biYPelsPerMeter As Long 
      biClrUsed As Long 
      biClrImportant As Long 
    End Type Private Type RGBQuad 
      rgbBlue As Byte 
      rgbGreen As Byte 
      rgbRed As Byte 
      ''rgbReserved As Byte 
    End Type Private Type BitMapInfo 
      bmiHeader As BitMapInfoHeader 
      bmiColors As RGBQuad 
    End Type     这三个数据结构都是在DIB中不可缺少的。我们不必深究,只是按照顺序复制粘贴直接使用就是了。    过程中用到的全局变量: Private Const Bits As Long = 32 ''颜色深度,这里把所有图像都按照32位来处理 
    Public Done As Boolean ''用于标记一个过程是否结束 
    Public TimeGet As Long ''用于记录输入过程处理所花费的时间 
    Public TimePut As Long ''用于记录输出过程处理所花费的时间 
    Dim ColVal() As Byte ''用于存放从DIB输入的像素值 
    Dim ColOut() As Byte ''用于存放向DIB输出的像素值 
    Dim InPutHei As Long ''用于记录输入图像的高度 
    Dim InPutWid As Long ''用于记录输入图像的宽度 
    Dim bi24BitInfo As BitMapInfo ''定义BMP信息     可以看出,我在输入和输出中使用了两个不同的动态数组ColVal()和ColOut(),这么做是有道理的,因为我们不只是为了输入和输出图像,中间还要对像素进行处理。包括图像缩放、色彩调整、锐化、柔化等等处理,使用两个不同的数组来分别存放数据更有利于程序的实现。    有些性急的朋友说不定已经把程序贴到工程里试用了,可是会发现根本不能输出图像。这是因为当你用DIBGET获得的图像还在ColVal() 中呢,需要把它们放到ColOut()这个数组中去,DIBPUT这个过程才能起作用。    这里再给出一个用于数组整体移动数据的过程: Public Sub CopyData(ByVal W As Long, ByVal H As Long) 
      Dim Length As Long 
      Dim I As Long 
      Dim L As Long 
      I = Bits \ 8 
      L = I - 1 
      Length = (W + 1&) * (H + 1&) * I 
      ReDim ColOut(L, W, H) 
      CopyMemory ColOut(0, 0, 0), ColVal(0, 0, 0), Length 
    End sub     API定义: Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)     这时,我们就可以来试一下效果了:    把你的显示器调到32位色。    将前面的所有API和变量定义全部贴到一个新建的模块里    新建一个窗体,加两个PICTURE控件:pictrue1 ,picture2 一个按钮command1    在pictrue1中加载一个图片    在command1中写如下代码: sub command1_click() 
      With picture1 
       .ScaleMode=3 
       .BorderStyle=0 
       DibGet .hdc,0,0,.scalewidth,.scaleheight 
      End With 
      CopyData InPutHei ,InPutWid 
      picture2.AutoRedraw=True 
      DibPut picture2.hdc 
      picture2.refresh 
    end sub     运行一下,按钮按下,pictreu1中的图片就立刻显示到了picture2中。    这时,你可能会说,弄了这么半天就贴个图?用PaintPicture不是就可以了吗?    不错,如果只是要贴个图,确实不用这么麻烦,可是,我们后面要说的图像处理部分将会用到前门得到的像素值。所以,这只是一个开始,我真正要讲的东西还在后面呢。请大家继续关注。 
      

  3.   

    不会吧。用GetPixel能在一毫秒找到你要的颜色????
    你的搜索范围多大???????
      

  4.   

    .........................
    我是做外挂的..但是这问题实在难倒我很久了.感谢大家给我的回答.Modest(塞北雪貂 -- 偶最欣赏楼主的分).感谢你的.