Jump to content

Issue dragging a "magnifier"


Recommended Posts

I'm doing some tests with the ">Magnifier Functions udf" by Ascend4nt.
Here is a draft for a magnifying glass.

 

 

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>
#include <Misc.au3>
;
#include "WinMagnifier.au3" ; <--- get this udf from following link
; http://www.autoitscript.com/forum/topic/161193-magnifier-functions-windows-vista-magnifier-manipulation/
;
_MagnifierInit()
;
Global $b_Test_WinAPI_SetTimer = False ; experiments with _WinAPI_SetTimer (affects on lines 42, 49, 101)
;
Global Const $iWinWidth = 200, $iWinHeight = 100 ; window dimensions
Global $nMagFactor = 2 ; zoom factor
Global $bCaptureCursor = False ; If True the cursor will be captured with the image
Global $bFollowMouse = True ; If true,  magnifies what's around the mouse position by following it. Lens location is fixed
;                             If false, magnifies the portion of screen that lies behind lens (behind the window)
Global $iLensMode = 2 ; 0 = magnifies what's around the mouse into the lens. The lens stays where it was placed
;                       1 = magnifies what's around the mouse into the lens. The lens follows the mouse
;                       2 = magnifies the portion of screen that lies behind the lens. The lens stays where it was placed
;
$aTemp = _MagnifierGUICreate($iWinWidth, $iWinHeight, 10, 10, 0, 0)

Global $hMagnifyGUI = $aTemp[0] ; hwndHost - Handle of the host window.
Global $hMagnifyCtrl = $aTemp[1] ; hwndMag - Handle of the magnifier window.

GUISetStyle($WS_POPUPWINDOW, BitOR($WS_EX_LAYERED, $WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE), $hMagnifyGUI) ; modify lens aspect
;
Global $aLensDim = WinGetClientSize($hMagnifyCtrl) ; a 2-element array containing the following information:
;                                                    $aLensDim[0] = Width of window's client area (inner area excluding borders).
;                                                    $aLensDim[1] = Height of window's client area (inner area excluding borders).
$idPic = GUICtrlCreatePic("", 0, 0, $aLensDim[0], $aLensDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; to allow dragging of the lens by click on lens and drag.
Global $aViewFinder[2] = [0, 0], $iTimerID, $hSnapShot
; Global $CaptureX = $iWinWidth / ($nMagFactor * 2), $CaptureY = $iWinHeight / ($nMagFactor * 2)
Global $aCaptureSource[2] = [Int($aLensDim[0] / ($nMagFactor * 2)), Int($aLensDim[1] / ($nMagFactor * 2))]
;
_MagnifierSetScale($hMagnifyCtrl, $nMagFactor)
; GUISetState(@SW_SHOW, $hMagnifyCtrl)
GUISetState(@SW_SHOW, $hMagnifyGUI)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

If $b_Test_WinAPI_SetTimer Then
    $hSnapShot = DllCallbackRegister('SnapShot', 'none', 'hwnd;uint;uint_ptr;dword')
    $iTimerID = _WinAPI_SetTimer(0, 0, 1000, DllCallbackGetPtr($hSnapShot))
EndIf

Do
    Sleep(100)
    If Not $b_Test_WinAPI_SetTimer Then SnapShot($hMagnifyCtrl) ; executed only if $b_Test_WinAPI_SetTimer is False
Until _IsPressed('1B')
_Exit()

Func SnapShot($hMagnifyCtrl)
    If $iLensMode = 0 Or $iLensMode = 1 Then ; take snapshot around the mouse
        $aViewFinder = MouseGetPos() ; // Get the mouse coordinates.
        If $iLensMode = 1 Then
            WinMove($hMagnifyGUI, "", $aViewFinder[0] - $iWinWidth / 2, $aViewFinder[1] - $iWinHeight / 2) ; lens follows the mouse
        EndIf
        $aViewFinder[0] = $aViewFinder[0] - $aCaptureSource[0]
        $aViewFinder[1] = $aViewFinder[1] - $aCaptureSource[1]

    ElseIf $iLensMode = 2 Then ; take the snapshot behind the "lens"
        $aViewFinder = _WinAPI_GetClientScreenPos($hMagnifyGUI)
        $aViewFinder[0] = $aViewFinder[0] + $aCaptureSource[0] / 2
        $aViewFinder[1] = $aViewFinder[1] + $aCaptureSource[1] / 2
    EndIf

    _MagnifierSetSource($hMagnifyCtrl, $aViewFinder[0], $aViewFinder[1], $aCaptureSource[0], $aCaptureSource[1])

EndFunc   ;==>SnapShot

; #FUNCTION# ====================================================================================================================
; http://www.autoitscript.com/forum/topic/107966-window-space-position-size/?p=761415
; Name...........: _WinAPI_GetClientScreenPos (a bit modified by me)
; Description ...: Returns the onscreen x y of a client area of a window.
; Syntax.........: _WinAPI_GetClientScreenPos($hWindow)
; Parameters ....: $hWindow     - Identifies an open handle to a window
; Return values .: Success       - Array
;                   [0] x
;                   [1] y
;                  Failure       - False
; Author ........: Nemcija
; Remarks .......: For minimized windows values wouldn't be correct!
; Related .......: _WinAPI_GetClientRect
; ===============================================================================================================================
Func _WinAPI_GetClientScreenPos($hWindow)
    Local $tLocalClientRect, $tPoint, $aiReturnValue[2]
    $tLocalClientRect = _WinAPI_GetClientRect($hWindow)
    If @error Then Return SetError(@error, @extended, False)
    $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", DllStructGetData($tLocalClientRect, "Left"))
    DllStructSetData($tPoint, "Y", DllStructGetData($tLocalClientRect, "Top"))
    _WinAPI_ClientToScreen($hWindow, $tPoint)
    If @error Then Return SetError(@error, @extended, False)
    $aiReturnValue[0] = DllStructGetData($tPoint, "X")
    $aiReturnValue[1] = DllStructGetData($tPoint, "Y")
    Return $aiReturnValue
EndFunc   ;==>_WinAPI_GetClientScreenPos

Func _Exit()
    If $b_Test_WinAPI_SetTimer Then
        _WinAPI_KillTimer(0, $iTimerID)
        DllCallbackFree($hSnapShot)
    EndIf
    _MagnifierUnInit()
    ConsoleWrite("Exit: bye bye" & @CR)
    GUIDelete($hMagnifyGUI)
    Exit
EndFunc   ;==>_Exit

 


I have two problems:
Issue 1)  When I start the script, sometimes it starts properly, while other times the lens shows only a black box instead of the magnified area. I saw that in those cases, interrupting the script by pressing esc and running it again several times solves this strange problem (ie, after several reboots of the script, it works correctly... (?))
Problem 2) when the lens works well and you try to drag the lens, the image that is located inside the lens remains frozen until the lens is dropped. I wish that the content of the lens continues to update even while dragging. I tried to use the _WinAPI_SetTimer to update the contents of the lens even while dragging, but without success  (set the variable $b_Test_WinAPI_SetTimer = True at line 11 to see the unsuccessfully attempt)
Any suggestions for achieve this purpose will be appreciated
thanks

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

A little better now. The content of the lens is updated while dragging.
still occurs randomly the black box issue inside the lens
I don't like much this... I give up.

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>
#include <Misc.au3>
;
#include "WinMagnifier.au3" ; <--- get this udf from following link
; http://www.autoitscript.com/forum/topic/161193-magnifier-functions-windows-vista-magnifier-manipulation/
;
_MagnifierInit()
;
Global $b_Test_WinAPI_SetTimer = True ; experiments with _WinAPI_SetTimer (affects on lines 39, 46, 98)
;
Global Const $iWinWidth = 400, $iWinHeight = 200 ; window dimensions
Global $nMagFactor = 1.5 ; zoom factor
Global $bCaptureCursor = False ; If True the cursor will be captured with the image
Global $bFollowMouse = True ; If true,  magnifies what's around the mouse position by following it. Lens location is fixed
;                             If false, magnifies the portion of screen that lies behind lens (behind the window)
Global $iLensMode = 0 ; 0 = magnifies what's around the mouse into the lens. The lens stays where it was placed
;                       1 = magnifies what's around the mouse into the lens. The lens follows the mouse
;                       2 = magnifies the portion of screen that lies behind the lens. The lens stays where it was placed
;
$aTemp = _MagnifierGUICreate($iWinWidth, $iWinHeight, 10, 10, 0, 0)

Global $hMagnifyGUI = $aTemp[0] ; hwndHost - Handle of the host window.
Global $hMagnifyCtrl = $aTemp[1] ; hwndMag - Handle of the magnifier window.

GUISetStyle($WS_POPUPWINDOW, BitOR($WS_EX_LAYERED, $WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE), $hMagnifyGUI) ; modify lens aspect
;
Global $aLensDim = WinGetClientSize($hMagnifyCtrl) ; a 2-element array containing the following information:
;                                                    $aLensDim[0] = Width of window's client area (inner area excluding borders).
;                                                    $aLensDim[1] = Height of window's client area (inner area excluding borders).
;
$idPic = GUICtrlCreatePic("", 0, 0, $aLensDim[0], $aLensDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; to allow dragging of the lens by click on lens and drag.
Global $aViewFinder[2] = [0, 0], $iTimerID, $hSnapShot
; Global $CaptureX = $iWinWidth / ($nMagFactor * 2), $CaptureY = $iWinHeight / ($nMagFactor * 2)
Global $aCaptureSource[2] = [Int($aLensDim[0] / ($nMagFactor * 2)), Int($aLensDim[1] / ($nMagFactor * 2))]
;
_MagnifierSetScale($hMagnifyCtrl, $nMagFactor)
; GUISetState(@SW_SHOW, $hMagnifyCtrl)
GUISetState(@SW_SHOW, $hMagnifyGUI)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

If $b_Test_WinAPI_SetTimer Then
    $hSnapShot = DllCallbackRegister('_SnapShot', 'none', 'hwnd;int;int;dword')
    $iTimerID = _WinAPI_SetTimer($hMagnifyGUI, 0, 40, DllCallbackGetPtr($hSnapShot))
EndIf

Do
    Sleep(100)
    ; If Not $b_Test_WinAPI_SetTimer Then _SnapShot() ; executed only if $b_Test_WinAPI_SetTimer is False
Until _IsPressed('1B')
_Exit()

Func _SnapShot($hWnd, $Msg, $iIDTimer, $dwTime)
    ; #forceref $hWnd , $Msg , $iIDTimer , $dwTime
    ; ConsoleWrite("." & @CR)
    If $iLensMode = 0 Or $iLensMode = 1 Then ; take snapshot around the mouse
        $aViewFinder = MouseGetPos() ; // Get the mouse coordinates.
        If $iLensMode = 1 Then
            WinMove($hMagnifyGUI, "", $aViewFinder[0] - $iWinWidth / 2, $aViewFinder[1] - $iWinHeight / 2) ; lens follows the mouse
        EndIf
        $aViewFinder[0] = $aViewFinder[0] - $aCaptureSource[0]
        $aViewFinder[1] = $aViewFinder[1] - $aCaptureSource[1]

    ElseIf $iLensMode = 2 Then ; take the snapshot behind the "lens"
        $aViewFinder = _WinAPI_GetClientScreenPos($hMagnifyGUI)
        $aViewFinder[0] = $aViewFinder[0] + $aCaptureSource[0] / 2
        $aViewFinder[1] = $aViewFinder[1] + $aCaptureSource[1] / 2
    EndIf

    _MagnifierSetSource($hMagnifyCtrl, $aViewFinder[0], $aViewFinder[1], $aCaptureSource[0], $aCaptureSource[1])

EndFunc   ;==>_SnapShot

; #FUNCTION# ====================================================================================================================
; http://www.autoitscript.com/forum/topic/107966-window-space-position-size/?p=761415
; Name...........: _WinAPI_GetClientScreenPos (a bit modified by me)
; Description ...: Returns the onscreen x y of a client area of a window.
; Syntax.........: _WinAPI_GetClientScreenPos($hWindow)
; Parameters ....: $hWindow     - Identifies an open handle to a window
; Return values .: Success       - Array
;                   [0] x
;                   [1] y
;                  Failure       - False
; Author ........: Nemcija
; Remarks .......: For minimized windows values wouldn't be correct!
; Related .......: _WinAPI_GetClientRect
; ===============================================================================================================================
Func _WinAPI_GetClientScreenPos($hWindow)
    Local $tLocalClientRect, $tPoint, $aiReturnValue[2]
    $tLocalClientRect = _WinAPI_GetClientRect($hWindow)
    If @error Then Return SetError(@error, @extended, False)
    $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", DllStructGetData($tLocalClientRect, "Left"))
    DllStructSetData($tPoint, "Y", DllStructGetData($tLocalClientRect, "Top"))
    _WinAPI_ClientToScreen($hWindow, $tPoint)
    If @error Then Return SetError(@error, @extended, False)
    $aiReturnValue[0] = DllStructGetData($tPoint, "X")
    $aiReturnValue[1] = DllStructGetData($tPoint, "Y")
    Return $aiReturnValue
EndFunc   ;==>_WinAPI_GetClientScreenPos

Func _Exit()
    If $b_Test_WinAPI_SetTimer Then
        _WinAPI_KillTimer(0, $iTimerID)
        DllCallbackFree($hSnapShot)
    EndIf
    _MagnifierUnInit()
    ConsoleWrite("Exit: bye bye" & @CR)
    ; GUIDelete($hMagnifyGUI)
    Exit
EndFunc   ;==>_Exit

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...