GetPixel API - Simple question about color

Biodegradable

Member
Joined
Nov 20, 2005
Messages
9
ok I have never messed with GetPixel before so this is my guess at how it supposed to work (I got really close i think) My code:
Code:
Public Class Form1
    Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Integer
    Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Integer) As Integer
    Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Integer, ByVal ByValhdc As Integer) As Integer
    Private Sub GetPixels(ByVal hdc As Long, ByVal x As Long, ByVal y As Long)
        Dim black As Color = Color.Black
        Dim hWnd As Integer = GetForegroundWindow()
        hdc = (GetWindowDC(hWnd))
        If GetPixel(hdc, 400, 400) = black Then
            MsgBox("w00t Returned black")
        End If
    End Sub
End Class
I realized that Vb.net does not read Hex but RGB. So my problem is how do i get my program to recognize color black, or #000000, or (0,0,0) my friend said something like defing R, G and B as something and then putting those in a form of (0,0,0) so something like GetPixel (hdc,400,400) = (0,0,0) or something like that. how should I do it?
to make it even more complicated I want to put this on a timer :P
 
Last edited by a moderator:
First of all, your longs should be changed to Integers. A VB6 Long is a .Net integer, and you are using VB6 declarations. Secondly, you can use masks and bitshifts to extract R, G, and B values from the 32-bit integer returned. You could also use a struct. You could also compare the integers to hex values.

Here is your complete toolkit for basic GDI color operations.
[VB]
Compare to yellow
Since GDI doesnt use ARGB, the first two digits should always be 00, i think
If GetPixel(MyHdc, MyX, MyY) = &H00FF00FF Then
...
Note that you can enter hex values in VB using the &H notation
End If

Some sample color constants
Const Int32 Red = &H00FF0000
Const Int32 Black = &H00000000
Const Int32 Green = &H000000FF

A function to do the work for us
Public Function ToGDIColor(Clr As System.Drawing.Color) As Int32
Return Clr.ToArgb() And &H00FFFFFF
End Function
[/code]

A struct!
[VB]
Imports System.Runtime.InteropServices
Imports System.Drawing

<StructLayout(LayoutKind.Explicit)> _
Public Structure MyColorStruct
<FieldOffset(0)> Dim A As Byte
<FieldOffset(1)> Dim R As Byte
<FieldOffset(2)> Dim G As Byte
<FieldOffset(3)> Dim B As Byte
<FieldOffset(0)> Dim ARGB As Int32
<FieldOffset(0)> Dim UnsignedARGB As UInt32

Public ReadOnly Property ColorStruct() As Color
Get
Return Color.FromArgb(ARGB)
End Get
End Property

Public Function Gdi_to_GdiPlus() As Color
Return Color.FromArgb(ARGB Or &HFF000000)
End Function
End Structure

You can get any of the component color values from the
A, R, G, and B members, and a composite value from ARGB
or UnsignedARGB. The property gets a System.Drawing.Color
from GDI+ color values, and Gdi_to_GdiPlus gets a
System.Drawing.Color from a GDI color value.

Here are our .Net API function declaration:
VB6 Longs are .Net Int32s, and IntPtr is best suited for handles

I changed the return from GetPixel to MyColorStruct. You could just as easily use an Int32 to get raw numeric values.
Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As IntPtr, ByVal x As Int32, ByVal y As Int32) As MyColorStruct
Private Declare Function GetForegroundWindow Lib "user32" () As IntPtr
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[/VB]
I hope my answer isnt overkill, Im just trying to be helpful.
 
Ok I dont know much about VB.Net, but if you wish to compare the colour of the pixel you will need to use ToArgb() method of the color object.

So for your example black.ToArgb()

EDIT- ok marble beat me to an answer again
 
Last edited by a moderator:
Code:
Public Class form1
    Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As IntPtr, ByVal x As Int32, ByVal y As Int32)
    Private Declare Function GetForegroundWindow Lib "user32" () As IntPtr
    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
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim hdc As Integer
        Dim hWnd As Integer = GetForegroundWindow()
        hdc = (GetWindowDC(hWnd))
        If GetPixel(hdc, 400, 400) = &HFF00FF Then
            MsgBox("Returned yellow")
        End If
        ReleaseDC(hWnd, hdc)
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Enabled = True
        Timer1.Interval = 16
    End Sub
End Class
that should work but it dosnt (thats all my code)
I want to be able to run that program...open up mspaint and fill with yelow and get a msgbox saying Yellow
 
If you output the result of GetPixel to the debug window does it produce sensible values? Also are you sure the Messagebox isnt causing problems by changing the active window to itself.
 
I got it to work...here is the code
Code:
Public Class form1
    Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As Integer, ByVal x As Int32, ByVal y As Int32) As Int32
    Private Declare Function GetForegroundWindow Lib "user32" () As Integer
    Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Integer) As Integer
    Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Integer, ByVal hdc As Integer) As Integer
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim hdc As Integer
        Dim hWnd As Integer = GetForegroundWindow()
        hdc = (GetWindowDC(hWnd))
        If GetPixel(hdc, 400, 400) = &HFFFF Then
            MsgBox("Returned yellow")
        End If
        ReleaseDC(hWnd, hdc)
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Enabled = True
        Timer1.Interval = 16
    End Sub
End Class
I put a pixel on paint at coords 335,345 (thats coord according to paint) and i got a lot of pop-ups saying returned yellow. I think it real coords its like 396,396 or something. but yeah solved!
 

Similar threads

Back
Top