GetPixelColour with mouse magnifier
Posted: Fri Nov 27, 2009 5:28 pm
Hi,
from a small coding question I was inspired to make this:
I hope all bugs are fixed.
I found it usefull, since I have often to do some html stuff,
and all other solutions are much bigger in size.
Bernd
from a small coding question I was inspired to make this:
Code: Select all
; Samplecode to get the color of a Pixel on the Desktop
; by PureLust for PureBasic-Forum - 18.09.2009 (with thanks to netmaestro) ;)
; extended by infratec
; windows Vista problem solved by srod (GetPixel() is to slow in Vista ~40ms !!!)
; now works also with 7 (GetDC() and ReleaseDC() now inside the loop)
; fix for multi screen environment added
; now multi screens should really work correct
; cursor movements are now correct (relative moves goes through the driver and his acceleration)
#MOUSEEVENTF_VIRTUALDESK = $4000
Global Mag = 5
Global ImageDim
NewMag = 5
#BoxPlusMinus = 10
Procedure SetMag(NewMag.i)
Mag = NewMag
ImageDim = #BoxPlusMinus * 2 * Mag
CreateImage(0, ImageDim, ImageDim)
If ImageDim < 100
WinDim = 100
Else
WinDim = ImageDim
EndIf
ResizeWindow(0, #PB_Ignore, #PB_Ignore, 100 + WinDim, 70 + WinDim)
TextGadget(1, 0, 45 + WinDim, 100 + WinDim, 20, "", #PB_Text_Center)
EndProcedure
Dim SendInputData.INPUT(0)
SendInputData(0)\Type = #INPUT_MOUSE
SendInputData(0)\mi\time = 0
SendInputData(0)\mi\dwExtraInfo = 0
SendInputData(0)\mi\mouseData = 0
OpenWindow(0, 0, 0, 200, 170, "", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Minimize)
ImageGadget(0, 46, 20, 105, 105, 0, #PB_Image_Border)
TextGadget(1, 0, 145, 200, 20, "", #PB_Text_Center)
TrackBarGadget(2, 10, 20, 20, 105, 1, 9, #PB_TrackBar_Vertical)
SetGadgetState(2, 1)
BoxDim = #BoxPlusMinus * 2
ImageDim = #BoxPlusMinus * 2 * Mag
CreateImage(0, ImageDim, ImageDim)
ShortCuts = 0
Repeat
Event = WaitWindowEvent(100)
x.l = DesktopMouseX()
y.l = DesktopMouseY()
hDC.l = GetDC_(0)
PointColor = GetPixel_(hDC, x, y)
Red = Red(PointColor)
Green = Green(PointColor)
Blue = Blue(PointColor)
PixelColour$ = RSet(Hex(Red), 2, "0") + RSet(Hex(Green), 2, "0") + RSet(Hex(Blue), 2, "0")
If WindowHeight(0) > 10
If ShortCuts = 0
AddKeyboardShortcut(0, #PB_Shortcut_Left, 1)
AddKeyboardShortcut(0, #PB_Shortcut_Up, 2)
AddKeyboardShortcut(0, #PB_Shortcut_Right, 3)
AddKeyboardShortcut(0, #PB_Shortcut_Down, 4)
AddKeyboardShortcut(0, #PB_Shortcut_Add, 5)
AddKeyboardShortcut(0, #PB_Shortcut_Subtract, 6)
AddKeyboardShortcut(0, #PB_Shortcut_F1, 7)
SetWindowTitle(0, "GetPixelColour")
ShortCuts = 1
EndIf
SetGadgetText(1, "Colour at " + Str(x) + ","+ Str(y) +" is: " + PixelColour$)
SD = StartDrawing(ImageOutput(0))
If SD
; find out the correct screensize
If GetSystemMetrics_(#SM_CMONITORS) = 1
DeskWidth.l = GetSystemMetrics_(#SM_CXSCREEN)
DeskHeight.l = GetSystemMetrics_(#SM_CYSCREEN)
dwFlags.q = #MOUSEEVENTF_ABSOLUTE + #MOUSEEVENTF_MOVE
Else
DeskWidth.l = GetSystemMetrics_(#SM_CXVIRTUALSCREEN)
DeskHeight.l = GetSystemMetrics_(#SM_CYVIRTUALSCREEN)
dwFlags.q = #MOUSEEVENTF_ABSOLUTE + #MOUSEEVENTF_MOVE + #MOUSEEVENTF_VIRTUALDESK
EndIf
; calculations for the 'borders'
If x - #BoxPlusMinus < 0
ScreenX1 = 0
ImageX1 = (#BoxPlusMinus - x) * Mag
Else
ScreenX1 = x - #BoxPlusMinus
ImageX1 = 0
EndIf
If x + #BoxPlusMinus > DeskWidth
ImageX2 = (#BoxPlusMinus * 2 - (x + #BoxPlusMinus - DeskWidth)) * Mag
Else
ImageX2 = ImageDim
EndIf
If y - #BoxPlusMinus < 0
ScreenY1 = 0
ImageY1 = (#BoxPlusMinus - y) * Mag
Else
ScreenY1 = y - #BoxPlusMinus
ImageY1 = 0
EndIf
If y + #BoxPlusMinus > DeskHeight
ImageY2 = (#BoxPlusMinus * 2 - (y + #BoxPlusMinus - DeskHeight)) * Mag
Else
ImageY2 = ImageDim
EndIf
; do the magnification
StretchBlt_(SD, ImageX1, ImageY1, ImageDim, ImageDim, hDC, ScreenX1, ScreenY1, BoxDim, BoxDim, #SRCCOPY)
; fill the borders if neccessary
If ImageX1 > 0
Box(0, 0, ImageX1, ImageDim, 0)
EndIf
If ImageY1 > 0
Box(0, 0, ImageDim, ImageY1, 0)
EndIf
If ImageX2 < ImageDim
Box(ImageX2, 0, ImageDim - ImageX2, ImageDim, 0)
EndIf
If ImageY2 < ImageDim
Box(0, ImageY2, ImageDim, ImageDim - ImageY2, 0)
EndIf
; draw the crosshairs
CompilerIf #PB_Compiler_Version >= 440
Line((ImageDim + Mag) / 2, 0, 1, ImageDim + Mag , ~PointColor)
Line(0, (ImageDim + Mag) / 2, ImageDim + Mag, 1 , ~PointColor)
CompilerElse
PointColor = $FFFFFF - PointColor
Line((ImageDim + Mag) / 2, 0, 0, ImageDim + Mag , PointColor)
Line(0, (ImageDim + Mag) / 2, ImageDim + Mag, 0 , PointColor)
CompilerEndIf
StopDrawing()
SetGadgetState(0, ImageID(0))
EndIf
If Event = #PB_Event_Gadget
If EventGadget() = 2
NewMag = 4 + (GetGadgetState(2) * 2 - 1)
If Mag <> NewMag
SetMag(NewMag)
EndIf
EndIf
EndIf
If Event = #PB_Event_Menu
SendInputData(0)\mi\dwFlags = dwFlags
Select EventMenu()
Case 1:
; mouse_event_(1, -1, 0, 0, 0)
SendInputData(0)\mi\dx = Round((65536.0 * (x - 1) / DeskWidth), #PB_Round_Up)
SendInputData(0)\mi\dy = Round((65536.0 * y) / DeskHeight, #PB_Round_Up)
SendInput_(1, SendInputData(0), SizeOf(INPUT))
Case 2:
;mouse_event_(1, 0, -1, 0, 0)
SendInputData(0)\mi\dx = Round((65536.0 * x) / DeskWidth, #PB_Round_Up)
SendInputData(0)\mi\dy = Round((65536.0 * (y - 1)) / DeskHeight, #PB_Round_Up)
SendInput_(1, SendInputData(0), SizeOf(INPUT))
Case 3:
;mouse_event_(1, 1, 0, 0, 0)
SendInputData(0)\mi\dx = Round((65536.0 * (x + 1)) / DeskWidth, #PB_Round_Up)
SendInputData(0)\mi\dy = Round((65536.0 * y) / DeskHeight, #PB_Round_Up)
SendInput_(1, SendInputData(0), SizeOf(INPUT))
Case 4:
;mouse_event_(1, 0, 1, 0, 0)
SendInputData(0)\mi\dx = Round((65536.0 * x) / DeskWidth, #PB_Round_Up)
SendInputData(0)\mi\dy = Round((65536.0 * (y + 1)) / DeskHeight, #PB_Round_Up)
SendInput_(1, SendInputData(0), SizeOf(INPUT))
Case 5:
If Mag < 21
Mag + 2
SetMag(Mag)
SetGadgetState(2, (Mag - 3) / 2 )
EndIf
Case 6:
If Mag > 5
Mag - 2
SetMag(Mag)
SetGadgetState(2, (Mag - 3) / 2 )
EndIf
Case 7:
Text$ = " Getpixelcolour" + Chr(13)
Text$ + Chr(13)
Text$ + " 2009 by Infratec" + Chr(13)
Text$ + Chr(13)
Text$ + "Use the cursor keys for fine adjustment" + Chr(13)
Text$ + "Plus and minus to set the magnification" + Chr(13)
Text$ + Chr(13)
Text$ + " Have fun!"
MessageRequester("Info", Text$)
EndSelect
EndIf
Else
SetWindowTitle(0, PixelColour$)
If ShortCuts = 1
RemoveKeyboardShortcut(0, #PB_Shortcut_All)
ShortCuts = 0
EndIf
EndIf
ReleaseDC_(0,hDC)
Until Event = #PB_Event_CloseWindow
I found it usefull, since I have often to do some html stuff,
and all other solutions are much bigger in size.
Bernd