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
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
Thanks sapero,
I'll have to study your code.
Larry