Yes it is possible. There are many ways to do this for instance we will need the GetPixel API to get the pixel color value from a specific point:
Code:
Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As IntPtr, ByVal x As Int32, ByVal y As Int32) As Int32
We will also need a few other APIs to make this work:
Code:
Public Declare Function GetWindowDC Lib "user32" (ByVal hwnd As IntPtr) As IntPtr
Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As IntPtr, ByVal ByValhdc As IntPtr) As Integer
Now how do we make this work? Let me show you an example of how this will work:
Code:
Dim PixelColor as Int32
PixelColor = GetPixel(windowDC, X, Y)
GetPixel will return the specified pixel color as a 32 bit integer from the x and y coordinates on the specified window device context that you have provided. You might be wondering how to get the window dc, well we will use the GetWindowDC API for that:
Code:
Dim windowDC as IntPtr
windowDC = GetWindowDC(PictureBox1.Handle)
We will be using a PictureBox for this example. We got the handle of the PictureBox by using the controls handle property. Then we used GetWindowDC to return the device context of the picturebox to windowDC.
Now how do we use this code to find a color? Well you can program a search function like this:
Code:
Public Sub FindColor(ByVal hWND As IntPtr, ByVal Color As Int32, ByRef X As Int32, ByRef Y As Int32)
Dim hDC As Int32
hDC = GetWindowDC(hWND)
For iX = 0 To 100
For iY = 0 To 100
If GetPixel(hDC, iX, iY) = Color Then
ReleaseDC(hWND, hDC)
X = iX
Y = iY
Exit Sub
End If
Next
Next
ReleaseDC(hWND, hDC)
X = -1
Y = -1
End Sub
If the color you have specified is found then it will return the coordinates of the pixel to X and Y. If the color is not found it will return -1 to X and Y.
Now how do we use this function you say? Well lets make a new form with with a picturebox and a button. Set the picture or background color of the picture box. Now lets program the button code:
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim px As Int32
Dim py As Int32
FindColor(PictureBox1.Handle, 255, px, py)
If px = -1 And py = -1 Then
MsgBox("Not found")
Else
MsgBox(px.ToString & ", " & py.ToString)
End If
End Sub
If the color is not found we will use a message box to say we didn't find it. If the color is found we will use the message box to display the coordinates.
Now for mouse clicking we are going to need another API call:
Code:
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32)
We will also need 2 constant variables:
Code:
Public Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2
Public Const MOUSEEVENTF_LEFTUP As Int32 = &H4
With this we can write a mouse clicking function:
Code:
Public Sub mClick(ByVal X As Int32, ByVal Y As Int32)
Dim cPoint As Point
cPoint.X = X
cPoint.Y = Y
Cursor.Position = cPoint
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
End Sub
This function will move the mouse cursor to the specified coordinates you have provided and invoke a left mouse click.
An example of this would be:
The problem here is you will need to modify the returned coordinates of the find color function because we got the coordinates based from the window handle. So we will need yet another API call:
Code:
Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hWnd As IntPtr, ByRef rect As Rectangle) As Boolean
Here is an example on how to use this:
Code:
Dim rWND As System.Drawing.Rectangle
GetWindowRect(hWND, rWND)
Now how do we use this to get modify our returned mouse coordinates? Simple:
Code:
mClick(rWND.X +X, rWND.Y + Y)
We are done now. That is the shitty guide I wrote while I was bored for the past hour. Here is the finished code:
Code:
Public Class Form1
Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As IntPtr, ByVal x As Int32, ByVal y As Int32) As Int32
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As IntPtr) As IntPtr
Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As IntPtr, ByVal ByValhdc As IntPtr) As Integer
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32)
Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hWnd As IntPtr, ByRef rect As Rectangle) As Boolean
Public Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2
Public Const MOUSEEVENTF_LEFTUP As Int32 = &H4
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim rWND As System.Drawing.Rectangle
Dim px As Int32
Dim py As Int32
FindColor(PictureBox1.Handle, 255, px, py)
If px = -1 And py = -1 Then
MsgBox("Not found")
Else
MsgBox(px.ToString & ", " & py.ToString)
GetWindowRect(PictureBox1.Handle, rWND)
mClick(rWND.X + px, rWND.Y + py)
End If
End Sub
Public Sub FindColor(ByVal hWND As IntPtr, ByVal Color As Int32, ByRef X As Int32, ByRef Y As Int32)
Dim hDC As Int32
hDC = GetWindowDC(hWND)
For iX = 0 To 100
For iY = 0 To 100
If GetPixel(hDC, iX, iY) = Color Then
ReleaseDC(hWND, hDC)
X = iX
Y = iY
Exit Sub
End If
Next
Next
ReleaseDC(hWND, hDC)
X = -1
Y = -1
End Sub
Public Sub mClick(ByVal X As Int32, ByVal Y As Int32)
Dim cPoint As Point
cPoint.X = X
cPoint.Y = Y
Cursor.Position = cPoint
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
End Sub
End Class
There are other ways to do this but this is just one way to do it. We could also create a bitmap image and get the pixels from it which would be much quicker.