Acce Posted August 25, 2020 Share Posted August 25, 2020 (edited) Hi I´m trying to make a picture move whiting a GUI , The behavior should be identical to a image viewer, or at least the one I´m using (Fast stone image viewer). ALso this need to work later when I implement a zoom function. So far my GUI is border less but will add at least a titlebar later when I get this working, and hopefuly an resize function of the gui as well. So far I have been able to get the picture move by holding the left button on the mouse , But not sure how to calculate the "end of the img" test script below : expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> Global Const $dll = DllOpen("user32.dll") Global $sx, $z = 10, $sy, $mc2, $f, $scroll_x = -350, $scroll_y Global $g_iIDC = -1, $g_iNewIDC = 0 Global $g_aArray = StringSplit("Hand|AppStarting|Arrow|Cross|Help|IBeam|Icon (obsolete)|No|" & _ "Size (obsolete)|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait|None", "|", 2) ; The flag parameter is set to flag = 2 as we don't require the total count of the array. $hGUI = GUICreate('MyGUI', @DesktopWidth-200, @DesktopHeight-200 , 100, 100, $WS_POPUP) ;GUICtrlSetBkColor($hGUI, 0x000000) GUISetState() _GDIPlus_Startup() $hcartridge = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "testimg.jpg") $iWidth = _GDIPlus_ImageGetWidth($hcartridge) *0.1 $iHeight = _GDIPlus_ImageGetHeight($hcartridge)*0.1 $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsDrawImage($hGraphic, $hcartridge, $scroll_x, $scroll_y) GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") ; Later for zoom function Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up Case 0x00780000 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Do $mc2 = MouseGetPos() If $g_iIDC = $g_iNewIDC Then $g_iIDC = -1 GUISetCursor($g_iIDC) EndIf While _IsPressed("01", $dll) If $g_iNewIDC <> $g_iIDC Then $g_iIDC = $g_iNewIDC GUISetCursor($g_iIDC) EndIf GUICtrlSetCursor(-1, 4) $mc3 = MouseGetPos() If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x = ($sx + ($mc3[0] - $mc2[0]) / ($z ^ 2 / 16)) $scroll_y = ($sy + ($mc3[1] - $mc2[1]) / ($z ^ 2 / 16)) _GDIPlus_GraphicsDrawImage($hGraphic, $hcartridge, $scroll_x, $scroll_y) EndIf Sleep(20) Wend $sx = $scroll_x $sy = $scroll_y Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) DllClose($dll) Any help would be much appreciated Edited August 31, 2020 by Acce Link to comment Share on other sites More sharing options...
Acce Posted August 25, 2020 Author Share Posted August 25, 2020 Looks like adding this little line prevents it from moving the img away from top: if $scroll_y > 1 Then $scroll_y = 0 But how in the world would i add the calculations for left,right bottom? My window Height is 880, img height is 1137 , i fail to find the logic to create this , maybe after some sleep (or some help, lol, ) Link to comment Share on other sites More sharing options...
markyrocks Posted August 25, 2020 Share Posted August 25, 2020 (edited) edit. My apologizes I have no idea what is goin on here. I thought this was a different post that had been edited. My question about your use of the dll still stands. Someone else had posted something about zoom that i had read and thought this was that post. Duh, been staring at the screen for too long. Edited August 25, 2020 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
Acce Posted August 26, 2020 Author Share Posted August 26, 2020 oucj missed the original msg from you so all good:) Link to comment Share on other sites More sharing options...
UEZ Posted August 26, 2020 Share Posted August 26, 2020 Have a look here: Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Acce Posted August 26, 2020 Author Share Posted August 26, 2020 (edited) @UEZ Hi thanks for your reply . I have had a look at several of your your old posts and looks like you are the master with this , I think very well this part is your code: If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x = ($sx + ($mc3[0] - $mc2[0]) / ($z ^ 2 / 16)) $scroll_y = ($sy + ($mc3[1] - $mc2[1]) / ($z ^ 2 / 16)) _GDIPlus_GraphicsDrawImage($hGraphic, $hcartridge, $scroll_x, $scroll_y) EndIf Edit: Also just realized that the scroll might be a bit slow any way to it scroll faster ? I guess I haven't looked at the post u mention here but I think l can use that zoom function. For Now m stuck with drag and push of the img. Like I said I want to be able to move the img inside the window much like a photo viewer This part: if $scroll_y > 1 Then $scroll_y = 0 prevents the img from moving away from top of the window , I suspect something like: if $scroll_x > 1 Then $scroll_x = 0 Will prevent the img from being pushed away from the left. However when it come to button and right I would need to calculate max $scroll_y and $scroll_x but im struggling with how to calculate it I thought it would be something like window.size - img.dimensions but this doesn't seam to be correct. in my setup the window height is set to 880 and the img.height is 1137 so in my mind i thought max scroll would be 1137-880 = 257 however runing an test the img can be moved to something like -650 scroll_y Edited August 26, 2020 by Acce Link to comment Share on other sites More sharing options...
Acce Posted August 27, 2020 Author Share Posted August 27, 2020 Have tried some functions now to prevent over scroll of img. but not working as i expect , any suggestions ; if $scroll_y > 1 Then $scroll_y = 0 endif if $scroll_x > 1 Then $scroll_x = 0 if $scroll_y < ($GUI_Pos[3] - $iHeight) * 2.48 Then $scroll_y = ($GUI_Pos[3] - $iHeight) * 2.48 EndIf if $scroll_x < ($GUI_Pos[2] - $iWidth) * 2.48 Then $scroll_x = ($GUI_Pos[2] - $iWidth) * 2.48 EndIf Link to comment Share on other sites More sharing options...
Acce Posted August 27, 2020 Author Share Posted August 27, 2020 (edited) Ok now I have a working code. The error was with how I loaded the img swaped this line _GDIPlus_GraphicsDrawImage($hGraphic, $hcartridge, $scroll_x, $scroll_y) with this: _GDIPlus_GraphicsDrawImageRect( $hContext, $hImage, 0, 0, $iImageWidth, $iImageHeight ) expandcollapse popup #include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> HotKeySet("{ESC}", "Terminate") Global Const $dll = DllOpen("user32.dll") Global $sx, $z = 5, $sy, $mc2, $f, $scroll_x = 0, $scroll_y,$current_iPos_y, $RQGUI_POS[3] = [280, 325, 0] Global $g_iIDC = -1, $g_iNewIDC = 0 Global $aDim Global $g_aArray = StringSplit("Hand|AppStarting|Arrow|Cross|Help|IBeam|Icon (obsolete)|No|" & _ "Size (obsolete)|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait|None", "|", 2) ; The flag parameter is set to flag = 2 as we don't require the total count of the array. $hGUI = GUICreate('MyGUI', @DesktopWidth-200, @DesktopHeight-200 , 100, 100, $WS_POPUP) GUICtrlSetBkColor($hGUI, 0x000000) $GUI_Pos = WinGetPos($hGUI) consolewrite("GUI Height = " & $GUI_Pos[3] & @lf) consolewrite("GUI Width = " & $GUI_Pos[2] & @lf) GUISetState() _GDIPlus_Startup() $hcartridge = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "testimg.jpg") Global $aDim = _GDIPlus_ImageGetDimension($hcartridge) consolewrite("!Img width = " & $aDim[0] & @lf) $iWidth = _GDIPlus_ImageGetWidth($hcartridge) $iHeight = _GDIPlus_ImageGetHeight($hcartridge) ConsoleWrite("!img $iHeight= " & $iHeight & @lf) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ConsoleWrite(_GDIPlus_ImageGetHeight & @lf) _GDIPlus_GraphicsDrawImageRect( $hGraphic, $hcartridge, $scroll_x, $scroll_y, $iWidth, $iHeight ) Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up Case 0x00780000 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Do $mc2 = MouseGetPos() If $g_iIDC = $g_iNewIDC Then $g_iIDC = -1 GUISetCursor($g_iIDC) EndIf While _IsPressed("01", $dll) If $g_iNewIDC <> $g_iIDC Then $g_iIDC = $g_iNewIDC GUISetCursor($g_iIDC) EndIf GUICtrlSetCursor(-1, 4) $mc3 = MouseGetPos() If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x = ($sx + ($mc3[0] - $mc2[0]) / ($z ^ 2 / 16)) $scroll_y = ($sy + ($mc3[1] - $mc2[1]) / ($z ^ 2 / 16)) ConsoleWrite("scroll_y= " & $scroll_y & @lf) ;prevent Scroling away from top if $scroll_y > 1 Then $scroll_y = 0 endif if $scroll_x > 1 Then $scroll_x = 0 if $scroll_y < ($GUI_Pos[3] - $iHeight) Then $scroll_y = ($GUI_Pos[3] - $iHeight) EndIf if $scroll_x > 1 Then $scroll_x = 0 if $scroll_x < ($GUI_Pos[2] - $iWidth) Then $scroll_x = ($GUI_Pos[2] - $iWidth) EndIf _GDIPlus_GraphicsDrawImageRect( $hGraphic, $hcartridge, $scroll_x, $scroll_y, $iWidth, $iHeight ) $current_iPos_y = $scroll_y EndIf Sleep(20) Wend $sx = $scroll_x $sy = $scroll_y Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) DllClose($dll) Func Terminate() Exit EndFunc ;==>Terminate Any suggestions as how I can have a mouse wheel zoom function that will play nice with the img move function ? Edited August 27, 2020 by Acce Error with text Link to comment Share on other sites More sharing options...
Acce Posted August 27, 2020 Author Share Posted August 27, 2020 I almost have it , It just behave a bit strange on zoom in/out expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> HotKeySet("{ESC}", "Terminate") Global Const $dll = DllOpen("user32.dll") Global $sx, $z = 5, $sy, $mc2, $f, $scroll_x = 0, $scroll_y, $current_iPos_y, $RQGUI_POS[3] = [280, 325, 0] Global $g_iIDC = -1, $g_iNewIDC = 0 Global $aDim Global $g_aArray = StringSplit("Hand|AppStarting|Arrow|Cross|Help|IBeam|Icon (obsolete)|No|" & _ "Size (obsolete)|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait|None", "|", 2) ; The flag parameter is set to flag = 2 as we don't require the total count of the array. $hGUI = GUICreate('MyGUI', @DesktopWidth - 200, @DesktopHeight - 200, 100, 100, $WS_POPUP) GUICtrlSetBkColor($hGUI, 0x000000) $GUI_Pos = WinGetPos($hGUI) ConsoleWrite("GUI Height = " & $GUI_Pos[3] & @LF) ConsoleWrite("GUI Width = " & $GUI_Pos[2] & @LF) GUISetState() _GDIPlus_Startup() $hcartridge = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "testimg.jpg" Global $aDim = _GDIPlus_ImageGetDimension($hcartridge) ConsoleWrite("!Img width = " & $aDim[0] & @LF) $iWidth = _GDIPlus_ImageGetWidth($hcartridge) $iHeight = _GDIPlus_ImageGetHeight($hcartridge) ConsoleWrite("!img $iHeight= " & $iHeight & @LF) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ConsoleWrite(_GDIPlus_ImageGetHeight & @LF) Global $fZoom = 1 _GDIPlus_GraphicsSetInterpolationMode($hGraphic, $GDIP_INTERPOLATIONMODE_NearestNeighbor) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, 0, 0, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up ConsoleWrite($fZoom & @LF) If $fZoom > 1 Then $fZoom -= 0.05 _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, 0, 0, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) $iWidth = $iWidth * 0.95 $iHeight = $iHeight * 0.95 EndIf Case 0x00780000 ConsoleWrite($iWidth & @LF) If $fZoom < 2 Then $fZoom += 0.05 _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, 0, 0, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) $iWidth = $iWidth * 1.05 $iHeight = $iHeight * 1.05 EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Do $mc2 = MouseGetPos() If $g_iIDC = $g_iNewIDC Then $g_iIDC = -1 GUISetCursor($g_iIDC) EndIf While _IsPressed("01", $dll) If $g_iNewIDC <> $g_iIDC Then $g_iIDC = $g_iNewIDC GUISetCursor($g_iIDC) EndIf GUICtrlSetCursor(-1, 4) $mc3 = MouseGetPos() If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x = ($sx + ($mc3[0] - $mc2[0]) / ($z ^ 2 / 16)) $scroll_y = ($sy + ($mc3[1] - $mc2[1]) / ($z ^ 2 / 16)) ConsoleWrite("scroll_y= " & $scroll_y & @LF) ;prevent Scroling away from top If $scroll_y > 1 Then $scroll_y = 0 EndIf If $scroll_x > 1 Then $scroll_x = 0 If $scroll_y < ($GUI_Pos[3] - $iHeight) Then $scroll_y = ($GUI_Pos[3] - $iHeight) EndIf If $scroll_x > 1 Then $scroll_x = 0 If $scroll_x < ($GUI_Pos[2] - $iWidth) Then $scroll_x = ($GUI_Pos[2] - $iWidth) EndIf _GDIPlus_GraphicsDrawImageRect($hGraphic, $hcartridge, $scroll_x, $scroll_y, $iWidth, $iHeight) $current_iPos_y = $scroll_y EndIf Sleep(20) WEnd $sx = $scroll_x $sy = $scroll_y Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) DllClose($dll) Func Terminate() Exit EndFunc ;==>Terminate If any expert could have a look it would be greatly appreciated Link to comment Share on other sites More sharing options...
pixelsearch Posted August 27, 2020 Share Posted August 27, 2020 (edited) Hi Acce This is how I would have done it, it may give you some ideas. * GUI1 for your big main GUI * GUI2 for your picture (a pic control which got the same size than GUI2) * $GUI_WS_EX_PARENTDRAG as extended style for the pic : allows you to drag easily your picture / GUI2 with left mouse * $GUI_DOCKAUTO to resize automatically your pic when GUI2 is resized (during zoom with mousewheel) * Func WM_WINDOWPOSCHANGING() will force the pic / GUI2 to stay between the limits of GUI1 * Func WM_MOUSEWHEEL() will be the most basic function to zoom (+ or - 10% each time) * In case the original pic is bigger than GUI1, it will be immediately resized (in memory) to fit GUI1 dimensions. All these functionalities are found in the following script. Just add one of your pic (jpg). Give your image exactly the same name as the script. Good luck expandcollapse popup#include <ColorConstantS.au3> #include <GDIPlus.au3> #include <GUIConstants.au3> #include <MenuConstants.au3> #include <MsgBoxConstants.au3> HotKeySet("{ESC}", "_Exit") Global $hGUI1 = 0, $hGUI2 = 0, $hImage = 0, $hBitmap = 0, $hImage_resized = 0 ; $hGUI1 = GUICreate("", @DesktopWidth - 200, @DesktopHeight - 200, -1, -1, $WS_POPUP) $hGUI1 = GUICreate("Title", @DesktopWidth - 200, @DesktopHeight - 200) $aClientSize = WinGetClientSize($hGUI1) $iWidth1 = $aClientSize[0] $iHeight1 = $aClientSize[1] $aWinPos = WinGetPos($hGUI1) If $aWinPos[3] = $aClientSize[1] Then ; GUI1 got no title bar $bTitleBar = False $iLeft1 = $aWinPos[0] $iTop1 = $aWinPos[1] Else $bTitleBar = True $iLeft1 = $aWinPos[0] + $aWinPos[2] - $aClientSize[0] - 2 $iTop1 = $aWinPos[1] + $aWinPos[3] - $aClientSize[1] - 2 EndIf $iRight1 = $iLeft1 + $iWidth1 $iBottom1 = $iTop1 + $iHeight1 ;==================================================== _GDIPlus_Startup() $sFileName = StringTrimRight(@ScriptFullPath, 4) & ".jpg" ; .au3/.a3x/.exe => .jpg If Not FileExists($sFileName) Then _Quit("File not found", $sFileName, 0, 0) $hImage = _GDIPlus_ImageLoadFromFile($sFileName) If @error Then _Quit("_GDIPlus_ImageLoadFromFile", $sFileName, @error, @extended) $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) If _CompareSize() = 0 Then $hImage_resized = $hImage Else $hImage_resized = _GDIPlus_ImageResize($hImage, $iX, $iY) If @error Then _Quit("_GDIPlus_ImageResize #1", $sFileName, @error, @extended) EndIf $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage_resized) If @error Then _Quit("_GDIPlus_BitmapCreateHBITMAPFromBitmap", $sFileName, @error, @extended) $hGUI2 = GUICreate("", $iX, $iY, -1, -1, $WS_POPUP, $WS_EX_MDICHILD, $hGUI1) $idPic = GUICtrlCreatePic("", 0, 0, $iX, $iY, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetResizing(-1, $GUI_DOCKAUTO) $hPrevImage = GUICtrlSendMsg($idPic, 0x0172, 0, $hBitmap) ; STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0 _WinAPI_DeleteObject($hPrevImage); Delete Prev image if any (help file) ;==================================================== GUISetState(@SW_SHOW, $hGUI1) GUISetState(@SW_SHOW, $hGUI2) GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING") GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") While 1 $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) Switch $aMsg[1] Case $hGUI1 Switch $aMsg[0] Case $GUI_EVENT_CLOSE _Exit() EndSwitch Case $hGUI2 Switch $aMsg[0] Case $GUI_EVENT_CLOSE _Exit() EndSwitch EndSwitch WEnd ;==================================================== Func WM_WINDOWPOSCHANGING($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam If $hWnd = $hGUI2 Then If $bTitleBar = True Then ; GUI1 got a title bar (=> movable, its coords may have changed) $aWinPos = WinGetPos($hGUI1) $iLeft1 = $aWinPos[0] + $aWinPos[2] - $aClientSize[0] - 2 $iTop1 = $aWinPos[1] + $aWinPos[3] - $aClientSize[1] - 2 $iRight1 = $iLeft1 + $iWidth1 $iBottom1 = $iTop1 + $iHeight1 EndIf Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam) Local $iLeft2 = DllStructGetData($stWinPos, 3) Local $iTop2 = DllStructGetData($stWinPos, 4) Local $iWidth2 = DllStructGetData($stWinPos, 5) Local $iHeight2 = DllStructGetData($stWinPos, 6) Local $iRight2 = $iLeft2 + $iWidth2 Local $iBottom2 = $iTop2 + $iHeight2 If $iLeft2 < $iLeft1 Then DllStructSetData($stWinPos, 3, $iLeft1) If $iTop2 < $iTop1 Then DllStructSetData($stWinPos, 4, $iTop1) If $iWidth2 > $iWidth1 Then DllStructSetData($stWinPos, 5, $iWidth1) If $iHeight2 > $iHeight1 Then DllStructSetData($stWinPos, 6, $iHeight1) If $iRight2 > $iRight1 Then If $iWidth2 <= $iWidth1 Then DllStructSetData($stWinPos, 3, $iRight1 - $iWidth2) Else DllStructSetData($stWinPos, 3, $iLeft1) DllStructSetData($stWinPos, 5, $iWidth1) EndIf EndIf If $iBottom2 > $iBottom1 Then If $iHeight2 <= $iHeight1 Then DllStructSetData($stWinPos, 4, $iBottom1 - $iHeight2) Else DllStructSetData($stWinPos, 4, $iTop1) DllStructSetData($stWinPos, 6, $iHeight1) EndIf EndIf EndIf ; Return $GUI_RUNDEFMSG ; (?) EndFunc ;==>WM_WINDOWPOSCHANGING ;==================================================== Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam If BitShift($wParam, 16) > 0 Then $iX *= 1.1 $iY *= 1.1 Else $iX /= 1.1 $iY /= 1.1 EndIf _CompareSize() WinMove($hGUI2, "", (@DesktopWidth - $iX) / 2, (@DesktopHeight - $iY) / 2, $iX, $iY) ; Return $GUI_RUNDEFMSG ; (?) EndFunc ;==>WM_MOUSEWHEEL ;==================================================== Func WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $lParam If $hWnd = $hGUI1 Then Switch $wParam Case $SC_MINIMIZE ; to avoid child window open at 0,0 after restore :( GUIRegisterMsg($WM_WINDOWPOSCHANGING, "") Case $SC_RESTORE GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING") EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_SYSCOMMAND ;==================================================== Func _CompareSize() Local $bResize = False If $iX > $iWidth1 Then $iY = $iWidth1 * $iY / $iX $iX = $iWidth1 $bResize = True EndIf If $iY > $iHeight1 Then $iX = $iHeight1 * $iX / $iY $iY = $iHeight1 $bResize = True EndIf If $bResize Then Return - 1 EndIf EndFunc ; _CompareSize() ;==================================================== Func _Quit($sError_title, $sError_msg, $iKeep_error, $iKeep_extended) ; bad error MsgBox($MB_TOPMOST, "Error : " & $sError_title, _ $sError_msg & @CRLF & @CRLF & _ "@error = " & $iKeep_error & " @extended = " & $iKeep_extended) _Exit() EndFunc ; _Quit() ; ==================================================== Func _Exit() _GDIPlus_ImageDispose($hImage_resized) _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() GUIDelete($hGUI2) GUIDelete($hGUI1) Exit EndFunc ; _Exit() 2nd edit : a stronger code, with UEZ's help. Edited August 28, 2020 by pixelsearch Modified code in case OP's GUI got more than $WS_POPUP style (title, movable...) Link to comment Share on other sites More sharing options...
UEZ Posted August 28, 2020 Share Posted August 28, 2020 (edited) I've modified by old script a little bit. The check for the border is not 100% and yet there is also no check if you zoom in and the image moves off the border. expandcollapse popup;Coded by UEZ build 2020-08-28 beta #include <GUIConstantsEx.au3> #include <Misc.au3> #include <Screencapture.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() ;~ Global Const $hBmp = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\test_new.jpg") Global $hHBitmap = _ScreenCapture_Capture("", 0, 0, 319, 255, 0) Global Const $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) _WinAPI_DeleteObject($hHBitmap) Global $sx_prev, $z = 10, $sy_prev, $mc2, $f, $scroll_x, $scroll_y, $fx, $fy, $tx, $ty, $scroll_x_prev, $scroll_y_prev Global Const $gdip_x = 0, $gdip_y = 0, $zmin = 5, $zmax = 15, $bg_c = "F0F0F0" Global Const $iW = 800, $iH = 600, $iW2 = $iW / 2, $iH2 = $iH / 2 Global $gdip_w = $iW , $gdip_h = $iH, $gdip_ww = $gdip_w, $gdip_hh = $gdip_h Global $bW = _GDIPlus_ImageGetWidth($hBmp), $bH = _GDIPlus_ImageGetHeight($hBmp), $bW2 = $bW / 2, $bH2 = $bH / 2 Global Const $hGUI = GUICreate("GDI+ Test", $iW, $iH) GUISetState() Global Const $dll = DllOpen("user32.dll") Global Const $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) Global Const $hBuffer_Bmp = _GDIPlus_BitmapCreateFromGraphics( $iW, $iH, $hGraphic) Global Const $hContext = _GDIPlus_ImageGetGraphicsContext($hBuffer_Bmp) _GDIPlus_GraphicsSetPixelOffsetMode($hContext, 2) ;~ _GDIPlus_GraphicsSetCompositingQuality($hContext, 2) _GDIPlus_GraphicsSetInterpolationMode($hContext, 7) Global $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, $gdip_w / 2, $gdip_h / 2) Draw2Graphic($hBmp) Zoom(2) GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") Do $mc2 = MouseGetPos() If _IsPressed("02", $dll) Then EndIf While _IsPressed("01", $dll) $mc3 = MouseGetPos() If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x_prev = $scroll_x $scroll_y_prev = $scroll_y $aE = _GDIPlus_MatrixGetElements($hMatrix) $scroll_x = ($sx_prev + ($mc3[0] - $mc2[0]) / $aE[0]) $scroll_y = ($sy_prev + ($mc3[1] - $mc2[1]) / $aE[0]) $tx = -($gdip_w - $bW * $aE[0]) / 2 $ty = -($gdip_h - $bH * $aE[0]) / 2 If $tx > $scroll_x * $aE[0] Or $tx > -$scroll_x * $aE[0] Then $scroll_x = $scroll_x_prev If $ty > $scroll_y * $aE[0] Or $ty > -$scroll_y * $aE[0] Then $scroll_y = $scroll_y_prev Draw2Graphic($hBmp) Zoom(2) EndIf Sleep(10) WEnd $sx_prev = $scroll_x $sy_prev = $scroll_y Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_MatrixDispose($hMatrix) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hContext) _GDIPlus_BitmapDispose($hBuffer_Bmp) _GDIPlus_BitmapDispose($hBmp) _GDIPlus_Shutdown() GUIDelete() DllClose($dll) Exit Func Draw2Graphic($hImage) Local $w, $h, $x, $y _GDIPlus_GraphicsClear($hContext, "0xFF" & $bg_c) If $bW <= $gdip_w And $bH <= $gdip_h Then $f = 1 $aE = _GDIPlus_MatrixGetElements($hMatrix) $x = ($gdip_w - $bW * $aE[0]) / 2 - $scroll_x $y = ($gdip_h - $bH * $aE[0]) / 2 - $scroll_y _GDIPlus_GraphicsDrawImageRect($hContext, $hImage, $x, $y, $bW, $bH) Else If $bW >= $bH Then $f = $bW / $gdip_w Else $f = $bH / $gdip_h EndIf $w = Floor($bW / $f) $h = Floor($bH / $f) If $w > $gdip_w Then $f = $bW / $gdip_w ElseIf $h > $gdip_h Then $f = $bH / $gdip_h EndIf $x = ($gdip_w - $w) / 2 - $scroll_x $y = ($gdip_h - $h) / 2 - $scroll_y _GDIPlus_GraphicsDrawImageRect($hContext, $hImage, $x, $y, $w, $h) EndIf EndFunc ;==>Draw2Graphic Func Zoom($zoom_dir) Local $fZoomSpeed = 0.075, $fMatrix_ScaleAdd = 1 + $fZoomSpeed, $fMatrix_ScaleSub = 1 - $fZoomSpeed Switch $zoom_dir Case -1 _GDIPlus_MatrixDispose($hMatrix) $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, $gdip_w / 2, $gdip_h / 2) _GDIPlus_MatrixScale($hMatrix, 1 / $f, 1 / $f) $scroll_x = 0 $scroll_y = 0 Case 0 If $z > $zmin Then _GDIPlus_MatrixTranslate($hMatrix, $scroll_x, $scroll_y) _GDIPlus_MatrixScale($hMatrix, $fMatrix_ScaleSub, $fMatrix_ScaleSub) $z -= $fZoomSpeed _GDIPlus_MatrixTranslate($hMatrix, -$scroll_x, -$scroll_y) EndIf Case 1 If $z <= $zmax Then _GDIPlus_MatrixTranslate($hMatrix, $scroll_x, $scroll_y) _GDIPlus_MatrixScale($hMatrix, $fMatrix_ScaleAdd, $fMatrix_ScaleAdd) _GDIPlus_MatrixTranslate($hMatrix, -$scroll_x, -$scroll_y) $z += $fZoomSpeed EndIf Case 2 _GDIPlus_MatrixScale($hMatrix, 1, 1) EndSwitch _GDIPlus_GraphicsSetTransform($hContext, $hMatrix) _GDIPlus_GraphicsClear($hContext, "0xFF" & $bg_c) _GDIPlus_GraphicsDrawImageRect($hContext, $hBmp, -$bW / 2 + $scroll_x, -$bH / 2 + $scroll_y, $bW, $bH) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBuffer_Bmp, $gdip_x, $gdip_y, $gdip_w, $gdip_h) EndFunc ;==>Zoom Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Local $iDir = _WinAPI_HiWord($wParam) Switch $iDir Case $iDir < 0 Zoom(0) Return 0 Case Else Zoom(1) Return 0 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Func Max($a, $b) Return ($a > $b) ? $a : $b EndFunc Func Min($a, $b) Return ($a < $b) ? $a : $b EndFunc @pixelsearch nice approach but it crashes when the zoom is too high -> AutoIt3.exe ended.rc:-1073741822 Edited August 28, 2020 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
pixelsearch Posted August 28, 2020 Share Posted August 28, 2020 2 hours ago, UEZ said: @pixelsearch nice approach but it crashes when the zoom is too high -> AutoIt3.exe ended.rc:-1073741822 Thanks UEZ for trying the script 2 hours of tests now and it didn't crash for me. It probably depends on the OS, windows version, Autoit version, memory etc... maybe the size of the pic itself ? I tried crazy things (without crash), for example : $hGUI1 = GUICreate("Title", @DesktopWidth * 10 , @DesktopHeight * 10) I also kept the original coords of the pic into 2 variables $iX_Ori and $iY_Ori, then displaying this tooltip each time the MouseWheel function is called : ToolTip($iX_Ori & " / " & $iY_Ori & " --> " & $iX & " / " & $iY, _ @DesktopWidth / 2, 9, "", 0, 2) ; 9 (good position), 0 = no icon, 2 = center tip at x,y I just tried on a 2.4Mb pic whose resolution is 4320 x 3240 pixels, this is a screen copy while zooming : Is it possible that when $iX and $iY got decimals, then a crash could appear ? In fact these 2 variables should be integers, as the help file stipulates it in the _GDIPlus_ImageResize() help page, quote : $iNewWidth : An integer value $iNewHeight : An integer value During these last months, I zoomed a lot with another script, based on _GDIPlus_GraphicsCreateFromHWND() and _GDIPlus_GraphicsDrawImage() because it seems to me that the speed of display is faster when you draw directly, compared to the "lower" speed of display with an image control pic. But though my $iX and $iY got decimals, I never had a single problem during months with the function _GDIPlus_ImageResize() The only problem I found (very rarely) was related to the function _GDIPlus_BitmapCloneArea() => error 10, extended 3 when I used it this way : $hClone = _GDIPlus_BitmapCloneArea($hImage_Resized, $iCrop_Left2, $iCrop_Top2, $iX_resized, $iY_resized) And the error totally disappeared when I used it that way : $hClone = _GDIPlus_BitmapCloneArea($hImage_Resized, $iCrop_Left2, $iCrop_Top2, Int($iX_resized), Int($iY_resized)) Though the help file for _GDIPlus_BitmapCloneArea() doesn't indicate that integers are mandatory, quote : $nWidth : The width of the rectangle that specifies the portion of this bitmap to copy $nHeight : The height of the rectangle that specifies the portion of this bitmap to copy Sorry it was a long comment but it's always great to chat with you Now let's hope Acce will find what he needs with the amended script you prepared. Thanks UEZ for being on AutoIt ! Link to comment Share on other sites More sharing options...
UEZ Posted August 28, 2020 Share Posted August 28, 2020 (edited) @pixelsearchI'm on Win10 b19041.450. It crashes as soon as the image reaches the GUI borders. What is purpose of these lines in function WM_MOUSEWHEEL? If _CompareSize() <> 0 Then _GDIPlus_ImageDispose($hImage_resized) $hImage_resized = _GDIPlus_ImageResize($hImage, $iX, $iY) If @error Then _Quit("_GDIPlus_ImageResize #2", $sFileName, @error, @extended) EndIf It crashes when the condition is true and the lines get executed. There is no further usage of $hImage_resized and these 5 lines can be removed. Then it works without any crash on my test image. Edited August 28, 2020 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Acce Posted August 28, 2020 Author Share Posted August 28, 2020 (edited) Thanks all for you replies , To be honest the skill level of you guys are way above my level I dont even know how to modify what you have posted to change from a screenshot to saved png from my computer. But looking at the sample script Im not sure you understand what I want ? I want to load a img, The img will be bigger then the Gui window. 2. I want to be able to move the img until it hit any end in the GUI_ bottom, left or right . Also I want to be able to zoom in on this img . What you posted is quite similar to what I want however quite different . I basically want an img viewer in my gui Edited August 28, 2020 by Acce Link to comment Share on other sites More sharing options...
Acce Posted August 28, 2020 Author Share Posted August 28, 2020 My latest version is this and work flawlessly however zoom not added as im unser how the correct way to add it would be expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> HotKeySet("{ESC}", "Terminate") Global Const $dll = DllOpen("user32.dll") Global $sx, $z = 5, $sy, $mc2, $f, $scroll_x = 0, $scroll_y,$current_iPos_y, $RQGUI_POS[3] = [280, 325, 0] Global $g_iIDC = -1, $g_iNewIDC = 0 Global $aDim Global $g_aArray = StringSplit("Hand|AppStarting|Arrow|Cross|Help|IBeam|Icon (obsolete)|No|" & _ "Size (obsolete)|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait|None", "|", 2) ; The flag parameter is set to flag = 2 as we don't require the total count of the array. $hGUI = GUICreate('MyGUI', @DesktopWidth-200, @DesktopHeight-200 , 100, 100, $WS_POPUP) GUICtrlSetBkColor($hGUI, 0x000000) $GUI_Pos = WinGetPos($hGUI) consolewrite("GUI Height = " & $GUI_Pos[3] & @lf) consolewrite("GUI Width = " & $GUI_Pos[2] & @lf) GUISetState() _GDIPlus_Startup() $hcartridge = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "test.jpg") Global $aDim = _GDIPlus_ImageGetDimension($hcartridge) consolewrite("!Img width = " & $aDim[0] & @lf) $iWidth = _GDIPlus_ImageGetWidth($hcartridge) $iHeight = _GDIPlus_ImageGetHeight($hcartridge) ConsoleWrite("!img $iHeight= " & $iHeight & @lf) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ConsoleWrite(_GDIPlus_ImageGetHeight & @lf) Global $fZoom = 1 _GDIPlus_GraphicsSetInterpolationMode($hGraphic, $GDIP_INTERPOLATIONMODE_NearestNeighbor) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, 0, 0, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up Case 0x00780000 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Do $mc2 = MouseGetPos() If $g_iIDC = $g_iNewIDC Then $g_iIDC = -1 GUISetCursor($g_iIDC) EndIf While _IsPressed("01", $dll) If $g_iNewIDC <> $g_iIDC Then $g_iIDC = $g_iNewIDC GUISetCursor($g_iIDC) EndIf GUICtrlSetCursor(-1, 4) $mc3 = MouseGetPos() If $mc2[0] <> $mc3[0] Or $mc2[1] <> $mc3[1] Then $scroll_x = ($sx + ($mc3[0] - $mc2[0]) / ($z ^ 2 / 16)) $scroll_y = ($sy + ($mc3[1] - $mc2[1]) / ($z ^ 2 / 16)) ConsoleWrite("scroll_y= " & $scroll_y & @lf) ;prevent Scroling away from top if $scroll_y > 1 Then $scroll_y = 0 endif if $scroll_x > 1 Then $scroll_x = 0 if $scroll_y < ($GUI_Pos[3] - $iHeight) Then $scroll_y = ($GUI_Pos[3] - $iHeight) EndIf if $scroll_x > 1 Then $scroll_x = 0 if $scroll_x < ($GUI_Pos[2] - $iWidth) Then $scroll_x = ($GUI_Pos[2] - $iWidth) EndIf _GDIPlus_GraphicsDrawImageRect( $hGraphic, $hcartridge, $scroll_x, $scroll_y, $iWidth, $iHeight ) $current_iPos_y = $scroll_y EndIf Sleep(20) Wend $sx = $scroll_x $sy = $scroll_y Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) DllClose($dll) Func Terminate() Exit EndFunc ;==>Terminate Link to comment Share on other sites More sharing options...
Acce Posted August 28, 2020 Author Share Posted August 28, 2020 (edited) Also I have noticed that my version kinda lags more then what UEZ made which looks very promising but it will not allow me to move the img out the edges which I want much like an img viewer. I just dont want the img to escape the borders Edited August 28, 2020 by Acce Link to comment Share on other sites More sharing options...
Acce Posted August 28, 2020 Author Share Posted August 28, 2020 (edited) deleted Edited August 28, 2020 by Acce Link to comment Share on other sites More sharing options...
pixelsearch Posted August 28, 2020 Share Posted August 28, 2020 2 hours ago, UEZ said: What is purpose of these lines in function WM_MOUSEWHEEL? If _CompareSize() <> 0 Then _GDIPlus_ImageDispose($hImage_resized) $hImage_resized = _GDIPlus_ImageResize($hImage, $iX, $iY) If @error Then _Quit("_GDIPlus_ImageResize #2", $sFileName, @error, @extended) EndIf There is no further usage of $hImage_resized and these 5 lines can be removed. Then it works without any crash on my test image. Hi UEZ Thanks for your comments concerning the 5 lines. Let's compare what happens without or with these 5 lines, based on an original image whose size is 700 x 469 1) Without the 5 lines : * Image on the left : ok * Image in the middle (+ 4 mouse wheel up) : bad as the image is now stretched vertically * Image on the right (+ 20 mouse wheel up) : still stretched (of course) and the tooltip indicates 5.025.706 pixels width, 3.367.223 height Now you'll need another 20 mouse wheel down to get the control and be able to zoom - again : nothing will happen on screen during all those 20 mouse wheel down. Of course, what a silly idea to mouse wheel up 20 times for nothing, but well... we're testing And the stretched image is still an issue. ============================ 1) With the 5 lines active : * Image on the left : ok * Image in the middle (+ 4 mouse wheel up) : ok (a small increase in coords from 249 / 166 to 274 / 183, correct) * Image on the right (+ 20 mouse wheel up) : ok. The tooltip is the same as the image in the middle (274 / 183) And only 1 mousewheel will be needed to start the zoom - ============================ To avoid the crash you experimented, my suggestion would be to : * Keep the 5 lines active... but to do as I did in another more complete script, i.e : * Create a dummy control ($idDummy_Wheel) in the GUI * Activate the dummy control from Func WM_MOUSEWHEEL() GUICtrlSendToDummy($idDummy_Wheel) * The code in the dummy control control should contain the 5 lines + the WinMove line Then only, the script would immediately quit Func WM_MOUSEWHEEL() and it should avoid the crash you experimented. Maybe that's the cause of the crash, spending too much time in Func WM_MOUSEWHEEL() ? For fun, in my other script, the code for the dummy control is commented like this : Case $idDummy_Wheel ; triggered during Func WM_MOUSEWHEEL() when user "mousewheels" to resize an image during Preview... ; OR triggered after manual Crop when left-mouse is pressed more than 0.3s during Case $GUI_EVENT_PRIMARYDOWN... ; OR triggered to Undo that manual Crop when right-mouse is pressed more than 0.3s during Case $GUI_EVENT_SECONDARYDOWN... ; OR triggered if user press Up key / + / Down key / - => WM_MOUSEWHEEL() => $idDummy_Wheel, in case... ; his computer got no external mouse (or his mouse doesn't have a mouse wheel, who knows ?) ; Same code in all cases : great ! I wish I could share that code with all of you but it requires a personal version of ArrayDisplayInternals.au3 If I succeed to delete the lines related to the non-standard ArrayDisplayInternals.au3, then I'll share that code with you but it should take some time as the code is about 114KB, though half of the lines are probably comment lines ! In the meantime, I'll rework the script above to create the dummy control $idDummy_Wheel, hoping it will solve your crash. Thanks for reading Link to comment Share on other sites More sharing options...
UEZ Posted August 28, 2020 Share Posted August 28, 2020 $hImage_resized is used only in that function for resizing the image, nowhere else. I'm wondering how you get these effects when the lines are commented out. Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Acce Posted August 28, 2020 Author Share Posted August 28, 2020 @UAZ I just noticed the top line u had commented out Global Const $hBmp = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\test_new.jpg") - just did a test with your version now , The zoom function works great exactly how I want, however the image calculations are way off (at least for what I´m trying to do). If somehow it would be possible to have your code load the image in full size into the little window obviously the img would be larger then the window which is what I want so I can scroll/push it around it should stop when it comes to the jpg edges like x 0 should not be allowed to be moved further than 0 in the window, same goes with all the edges > Like what my version does. But my code is so weak compered to this , it would be wicked to be able to use your work instead Link to comment Share on other sites More sharing options...
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