May 11, 2024, 10:13:28 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


GetPixel

Started by LarryMc, October 16, 2009, 02:20:21 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

I have used GetPixel in the past to find the color of a specific pixel in a window/control created by my application.

GetPixel needs a DC and that is no problem when I create the window/controls.

I would like to expand my horizon.

How do I find the color of a given pixel anywhere on my screen regardless of whether it's in my application, another application or the desktop.

I know GetCurPos will tell me the screen coordinates of where the cursor is when my application has the cursor captured.

How do I determine the hdc to use?
Are is there some other function I should be using?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

October 16, 2009, 04:12:27 PM #1 Last Edit: October 16, 2009, 04:17:14 PM by sapero
This may be a good start for you:$include "windowssdk.inc"

' demo start
HDC desktopDC = GetDC(0)
SetPixel(desktopDC, 33, 44, 0x123456)
ReleaseDC(0, desktopDC)

int x, y
if (FindPixel(0x123456, x, y))
MessageBox 0, using("found at #x#", x, y), ""
else
MessageBox 0, "not found", ""
endif
' demo end


sub FindPixel(COLORREF _color, int x byref, int y byref),BOOL

BOOL found = false
HDC desktopDC = GetDC(0)
HDC compatDC  = CreateCompatibleDC(desktopDC)

BITMAPINFOHEADER bmiHeader
RtlZeroMemory(&bmiHeader, len(bmiHeader))
bmiHeader.biSize = len(BITMAPINFOHEADER)
bmiHeader.biWidth = GetSystemMetrics(SM_CXSCREEN)
bmiHeader.biHeight = GetSystemMetrics(SM_CYSCREEN)
bmiHeader.biPlanes = 1
bmiHeader.biBitCount = 32

pointer pixels
HBITMAP bmp = CreateDIBSection(desktopDC, &bmiHeader, DIB_RGB_COLORS, &pixels, 0, 0)
if (bmp)
HBITMAP oldBitmap = SelectObject(compatDC, bmp)
' copy desktop to our bitmap
BitBlt(compatDC, 0, 0, bmiHeader.biWidth, bmiHeader.biHeight, desktopDC, 0, 0, SRCCOPY)
' find the pixel
DWORD pos = __scasd(pixels, bmiHeader.biWidth * bmiHeader.biHeight, _color)
if (pos)
pos = (pos-pixels) / 4 ' convert pointer to pixel index
x = pos % bmiHeader.biWidth
y = bmiHeader.biHeight - (pos / bmiHeader.biWidth) - 1 ' the bitmap is top-down!
found = true
endif

SelectObject(compatDC, oldBitmap)
DeleteObject(bmp)
endif

DeleteDC(compatDC)
ReleaseDC(0, desktopDC)
return found
endsub


sub __scasd(pointer pixels, int count, COLORREF _color),DWORD
_asm
mov edi,[ebp+ 8] ; pixels
mov ecx,[ebp+12] ; count
mov eax,[ebp+16] ; color
bswap eax        ; swap red and blue
shr eax,8
repne scasd      ; search: while (*edi++ <> eax) {if (!--ecx) break}
je .found
mov edi,4        ; force edi to be NULL
.found:
add edi,-4       ; undo the recent increment from scasd
mov [ebp+8],edi  ; save edi back in pixels
_endasm
return pixels
endsub

LarryMc

Thanks sapero,

I'll have to study your code.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library