corz Posted April 8, 2018 Posted April 8, 2018 This is a magnifier-color-picker thing mostly based on some code I found on Stack Overflow, of all places. At least all the clever bits are from there. I'd love to use this code inside an app I'm working on. But it has an issue. The first time the mag pops up it works perfectly, but the second and subsequent times, it's a boring grey square. One of you smart dudes will probably look at this and go, "Aha!", but I'm stumped. expandcollapse popup#include <WindowsConstants.au3> #include <WinAPI.au3> #include <StaticConstants.au3> MagWindow() MagWindow() ; Magnifier-Color-Picker.. ; Props to McBarby for the cross-hairs. func MagWindow() global $iMagZoom = 5 global $iMagWidth = Ceiling(100/$iMagZoom) global $iMagHeight = Ceiling(100/$iMagZoom) global $hDCDesk, $hDCZoom, $hPen global $hUser32 = DllOpen("user32.dll") global $hGDI32 = DllOpen("gdi32.dll") global $pixel_color, $mag_open = false local $mX, $mY global $hCross = GUICreate('', 48, 48, -1, -1, $WS_POPUP, $WS_EX_TOPMOST) WinSetTrans($hCross, '', 0) GUISetCursor(3, 1, $hCross) global $hZoom = GUICreate("MagPicker", $iMagWidth * $iMagZoom, $iMagHeight * $iMagZoom, _ MouseGetPos(0), MouseGetPos(1), $WS_POPUP+$WS_BORDER, $WS_EX_TOPMOST) global $mag_label = GUICtrlCreateLabel("placehold", (($iMagHeight * $iMagZoom)/2)+2, ($iMagHeight * $iMagZoom) - 13, _ (($iMagHeight * $iMagZoom)/2)-3, 12, $SS_RIGHT) ; put this after the GUICreate()s so that it will not error on startup with mouse already moving. (now trapped! but we will leave them here.) global $__hMouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam") global $__hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($__hMouseProc), _WinAPI_GetModuleHandle(0)) GUISetState(@SW_SHOW, $hCross) GUISetState(@SW_SHOW, $hZoom) $mag_open = true ; once at start, then from the mouse-callback-function.. _Magnify() while $mag_open Sleep(50) $mX = MouseGetPos(0) $mY = MouseGetPos(1) $pixel_color = Hex(PixelGetColor($mX, $mY), 6) GUICtrlSetData ($mag_label, $pixel_color) wend GUIDelete($hZoom) GUIDelete($hCross) ReleaseHooks() endfunc func _Magnify($_iX=-1, $_iY=-1) local Static $fInit = true if $fInit then $fInit = False $hDCDesk = (DLLCall($hUser32, "int", "GetDC", "hwnd", 0))[0] $hDCZoom = (DLLCall($hUser32, "int", "GetDC", "hwnd", $hZoom))[0] $hPen = (DLLCall($hGDI32, "int", "CreatePen", "int", 0, "int", 3, "int", 0x008b9094))[0] ; 0=PS_SOLID, dark-blue (0x00BBGGRR) DLLCall($hGDI32, "int", "SelectObject", "int", $hDCZoom, "hwnd", $hPen) $_iX = MouseGetPos(0) $_iY = MouseGetPos(1) endif local $iW = $iMagWidth * $iMagZoom, $iH = $iMagHeight * $iMagZoom if not @error then DLLCall($hGDI32, "int", "StretchBlt", "int", $hDCZoom, "int", _ 0, "int", 0, "int", $iW, "int", $iH, "int", $hDCDesk, "int", _ $_iX - $iMagWidth/2, "int", $_iY - $iMagHeight/2, "int", $iMagWidth ,"int", $iMagHeight, _ "long", $SRCCOPY) ; draw the crosshair (start x, start y, end x, end y) _GDI32_DrawLine($hDCZoom, ($iW/2)-2, $iH/8, ($iW/2)-2, 4*($iH/8)-6, $hGDI32) ; vertical top _GDI32_DrawLine($hDCZoom, ($iW/2)-2, 5*($iH/8)-10, ($iW/2)-2, 7*($iH/8), $hGDI32) ; vertical bottom _GDI32_DrawLine($hDCZoom, $iW/8, ($iH/2)-2, (3*($iW/8))+6, ($iH/2)-2, $hGDI32) ; horizontal left _GDI32_DrawLine($hDCZoom, 4*($iW/8)+3, ($iH/2)-2, 7*($iW/8), ($iH/2)-2, $hGDI32) ; horizontal right endif endfunc func _GDI32_DrawLine(ByRef $_hDC, $_iX0, $i_Y0, $_iX1, $i_Y1, $_hDll=-1) If $_hDll = -1 then $_hDll = "gdi32.dll" Local $tCurrent = DllStructCreate("struct; long X;long Y; endstruct") DllCall($_hDll, "int", "MoveToEx", "int", $_hDC, "int", $_iX0, "int", $i_Y0, "ptr", DllStructGetPtr($tCurrent)) DllCall($_hDll, "int", "LineTo", "int", $_hDC, "int", $_iX1, "int", $i_Y1) return $tCurrent endfunc func _MouseProc($_nCode, $_wParam, $_lParam) local $tMSLLHOOKSTRUCT = DllStructCreate("struct; long X;long Y; endstruct; " & _ "DWORD mouseData; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo;endstruct", $_lParam) if $_nCode < 0 Then Return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) local $iX = $tMSLLHOOKSTRUCT.X, $iY = $tMSLLHOOKSTRUCT.Y switch $_wParam case $WM_LBUTTONDOWN CloseMag() case $WM_MOUSEMOVE if not $mag_open then return WinMove($hCross, "", $iX -24, $iY -24) Local $iXz = ($iX +24 + $iMagWidth*$iMagZoom > @DesktopWidth) ? $iX -(24 + $iMagWidth*$iMagZoom) : $iX +24 Local $iYz = ($iY +24 + $iMagHeight*$iMagZoom > @DesktopHeight) ? $iY -(24 + $iMagHeight*$iMagZoom) : $iY +24 WinMove($hZoom, "", $iXz + $iMagWidth/2, $iYz) _Magnify($iX, $iY) endswitch return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) endfunc func ReleaseHooks() DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", $hPen) DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCDesk, "hwnd", 0) DLLCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", 0) DllClose($hUser32) DllClose($hGDI32) _WinAPI_UnhookWindowsHookEx($__hHook) DllCallbackFree($__hMouseProc) endfunc func CloseMag() ; called by mouse left click $mag_open = false endfunc Thanks for any and all insights! ;o) Cor nothing is foolproof to the sufficiently talented fool..
Developers Jos Posted April 8, 2018 Developers Posted April 8, 2018 Nice ... try this version and find the difference expandcollapse popup#include <WindowsConstants.au3> #include <WinAPI.au3> #include <StaticConstants.au3> MagWindow() MagWindow() ; Magnifier-Color-Picker.. ; Props to McBarby for the cross-hairs. Func MagWindow() Global $iMagZoom = 5 Global $iMagWidth = Ceiling(100 / $iMagZoom) Global $iMagHeight = Ceiling(100 / $iMagZoom) Global $hDCDesk = 0, $hDCZoom = 0, $hPen = 0 Global $hUser32 = DllOpen("user32.dll") Global $hGDI32 = DllOpen("gdi32.dll") Global $pixel_color, $mag_open = False Local $mX = 0, $mY = 0 Global $hCross = GUICreate('', 48, 48, -1, -1, $WS_POPUP, $WS_EX_TOPMOST) WinSetTrans($hCross, '', 0) GUISetCursor(3, 1, $hCross) Global $hZoom = GUICreate("MagPicker", $iMagWidth * $iMagZoom, $iMagHeight * $iMagZoom, _ MouseGetPos(0), MouseGetPos(1), $WS_POPUP + $WS_BORDER, $WS_EX_TOPMOST) Global $mag_label = GUICtrlCreateLabel("placehold", (($iMagHeight * $iMagZoom) / 2) + 2, ($iMagHeight * $iMagZoom) - 13, _ (($iMagHeight * $iMagZoom) / 2) - 3, 12, $SS_RIGHT) ; put this after the GUICreate()s so that it will not error on startup with mouse already moving. (now trapped! but we will leave them here.) Global $__hMouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam") Global $__hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($__hMouseProc), _WinAPI_GetModuleHandle(0)) GUISetState(@SW_SHOW, $hCross) GUISetState(@SW_SHOW, $hZoom) $mag_open = True ; once at start, then from the mouse-callback-function.. _Magnify() While $mag_open Sleep(50) $mX = MouseGetPos(0) $mY = MouseGetPos(1) $pixel_color = Hex(PixelGetColor($mX, $mY), 6) GUICtrlSetData($mag_label, $pixel_color) WEnd GUIDelete($hZoom) GUIDelete($hCross) ReleaseHooks() EndFunc ;==>MagWindow Func _Magnify($_iX = -1, $_iY = -1, $reset = False) Local Static $fInit = True If $fInit Then $fInit = False $hDCDesk = (DllCall($hUser32, "int", "GetDC", "hwnd", 0))[0] $hDCZoom = (DllCall($hUser32, "int", "GetDC", "hwnd", $hZoom))[0] $hPen = (DllCall($hGDI32, "int", "CreatePen", "int", 0, "int", 3, "int", 0x008b9094))[0] ; 0=PS_SOLID, dark-blue (0x00BBGGRR) DllCall($hGDI32, "int", "SelectObject", "int", $hDCZoom, "hwnd", $hPen) $_iX = MouseGetPos(0) $_iY = MouseGetPos(1) EndIf Local $iW = $iMagWidth * $iMagZoom, $iH = $iMagHeight * $iMagZoom If Not @error Then DllCall($hGDI32, "int", "StretchBlt", "int", $hDCZoom, "int", _ 0, "int", 0, "int", $iW, "int", $iH, "int", $hDCDesk, "int", _ $_iX - $iMagWidth / 2, "int", $_iY - $iMagHeight / 2, "int", $iMagWidth, "int", $iMagHeight, _ "long", $SRCCOPY) ; draw the crosshair (start x, start y, end x, end y) _GDI32_DrawLine($hDCZoom, ($iW / 2) - 2, $iH / 8, ($iW / 2) - 2, 4 * ($iH / 8) - 6, $hGDI32) ; vertical top _GDI32_DrawLine($hDCZoom, ($iW / 2) - 2, 5 * ($iH / 8) - 10, ($iW / 2) - 2, 7 * ($iH / 8), $hGDI32) ; vertical bottom _GDI32_DrawLine($hDCZoom, $iW / 8, ($iH / 2) - 2, (3 * ($iW / 8)) + 6, ($iH / 2) - 2, $hGDI32) ; horizontal left _GDI32_DrawLine($hDCZoom, 4 * ($iW / 8) + 3, ($iH / 2) - 2, 7 * ($iW / 8), ($iH / 2) - 2, $hGDI32) ; horizontal right EndIf If $reset Then $fInit = True EndIf EndFunc ;==>_Magnify Func _GDI32_DrawLine(ByRef $_hDC, $_iX0, $i_Y0, $_iX1, $i_Y1, $_hDll = -1) If $_hDll = -1 Then $_hDll = "gdi32.dll" Local $tCurrent = DllStructCreate("struct; long X;long Y; endstruct") DllCall($_hDll, "int", "MoveToEx", "int", $_hDC, "int", $_iX0, "int", $i_Y0, "ptr", DllStructGetPtr($tCurrent)) DllCall($_hDll, "int", "LineTo", "int", $_hDC, "int", $_iX1, "int", $i_Y1) Return $tCurrent EndFunc ;==>_GDI32_DrawLine Func _MouseProc($_nCode, $_wParam, $_lParam) Local $tMSLLHOOKSTRUCT = DllStructCreate("struct; long X;long Y; endstruct; " & _ "DWORD mouseData; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo;endstruct", $_lParam) If $_nCode < 0 Then Return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) Local $iX = $tMSLLHOOKSTRUCT.X, $iY = $tMSLLHOOKSTRUCT.Y Switch $_wParam Case $WM_LBUTTONDOWN CloseMag() Case $WM_MOUSEMOVE If Not $mag_open Then Return WinMove($hCross, "", $iX - 24, $iY - 24) Local $iXz = ($iX + 24 + $iMagWidth * $iMagZoom > @DesktopWidth) ? $iX - (24 + $iMagWidth * $iMagZoom) : $iX + 24 Local $iYz = ($iY + 24 + $iMagHeight * $iMagZoom > @DesktopHeight) ? $iY - (24 + $iMagHeight * $iMagZoom) : $iY + 24 WinMove($hZoom, "", $iXz + $iMagWidth / 2, $iYz) _Magnify($iX, $iY) EndSwitch Return _WinAPI_CallNextHookEx($__hHook, $_nCode, $_wParam, $_lParam) EndFunc ;==>_MouseProc Func ReleaseHooks() _Magnify(Default, Default, True) DllCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", $hPen) DllCall($hUser32, "int", "ReleaseDC", "int", $hDCDesk, "hwnd", 0) DllCall($hUser32, "int", "ReleaseDC", "int", $hDCZoom, "hwnd", 0) DllClose($hUser32) DllClose($hGDI32) _WinAPI_UnhookWindowsHookEx($__hHook) DllCallbackFree($__hMouseProc) EndFunc ;==>ReleaseHooks Func CloseMag() ; called by mouse left click $mag_open = False EndFunc ;==>CloseMag Jos argumentum 1 SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past.
corz Posted April 8, 2018 Author Posted April 8, 2018 Jos! As ever, you are a star! Reset. Very clever! Ta, mate! ;o) Cor nothing is foolproof to the sufficiently talented fool..
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now