pixelsearch Posted August 28, 2020 Share Posted August 28, 2020 (edited) 1 hour ago, UEZ said: I'm wondering how you get these effects when the lines are commented out. To answer your question, when the 5 lines are commented out, this is the line that will generate the vertical stretching effect, as seen in the pic above : GUICtrlSetResizing(-1, $GUI_DOCKAUTO) Now if we comment out this line too, the vertical stretching will disappear... but any zoom won't display the full image anymore, everything seems to be linked ! Edited August 28, 2020 by pixelsearch Link to comment Share on other sites More sharing options...
pixelsearch Posted August 28, 2020 Share Posted August 28, 2020 @UEZ : good news Problems seem to be solved after replacing the 5 lines you mentioned : 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 With that single line : _CompareSize() This will force $iX & $iY when needed. The return value was useful when the function was initially called at the beginning of the script, to resize the original file if necessary. But here, the return value isn't useful anymore. I'm gonna amend the script already posted, fingers crossed ! If you still got a crash (I doubt it as you didn't have a crash without the 5 lines) then I'll add the dummy control. Thanks for your help. Link to comment Share on other sites More sharing options...
Acce Posted August 29, 2020 Author Share Posted August 29, 2020 U guys mind taking a look at my version? Now I have been able to make the scroll work as well as the zoom function. There are a few issues somehow it scrolls opposite of what i want for example when i click and drag downwards the image goes down this is a bit award same behavior when puling either direction Also I have not been able to figure out how to calculate the edges for the image when its in "zoom" state . Here is my lates version: 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. ; --- Create GUI --- $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\" & "test1.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) GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") ; --- Create GUI --- Global $fZoom = 1 Global $iMinZoom = 1 Global $iMaxZoom = 20 Global $imgwidth = $iWidth Global $imgheight = $iHeight _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 if $fZoom > $iMinZoom Then $fZoom -= 0.05 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom ConsoleWrite("Zoom= " & $fZoom & " img.width:" & $imgwidth & " img.height: " & $imgheight & @lf) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) EndIf Case 0x00780000 $fZoom += 0.05 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom ConsoleWrite("Zoom= " & $fZoom & " img.width:" & $imgwidth & " img.height: " & $imgheight & @lf) ConsoleWrite($imgwidth & @lf) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) ;ConsoleWrite($fZoom & @lf) 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)) if $scroll_y < 1 Then $scroll_y = 0 if $scroll_x < 1 Then $scroll_x = 0 if $scroll_y > ($iHeight - $GUI_Pos[3]) Then $scroll_y = ($iHeight - $GUI_Pos[3]) EndIf if $scroll_x > ($imgwidth - $GUI_Pos[2]) Then $scroll_x = ($imgwidth - $GUI_Pos[2]) EndIf consolewrite("GUI Width = " & $GUI_Pos[2] & @lf) ConsoleWrite("Zoom= " & $fZoom & " img.width:" & $imgwidth & " img.height: " & $imgheight & @lf) consolewrite($scroll_x & @lf) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom) / 2, _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) $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 The zoom function seams to work like I want . Link to comment Share on other sites More sharing options...
pixelsearch Posted August 29, 2020 Share Posted August 29, 2020 (edited) Hi Acce First of all, I downloaded the freeware you mentioned : FastStone Image Viewer 7.5 (2020-03-10) in its portable version. It's a very interesting program (thanks !) and I checked its scrolling & zoom behavior because you would like the same behavior as you explained it in your 1st post. I succeeded to do that in the 2nd script below and it matches what you asked to UEZ yesterday, quote : On 8/28/2020 at 8:12 PM, Acce said: 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 This 2nd script is based on the 1st script I posted yesterday, but this time the image (GUI2) got a $WS_CHILD style which is a big help for your request, plus some changes in the WM_WINDOWPOSCHANGING() function. You will be able to scroll/push around when the image (GUI2) is wider or higher (or both) than GUI1, just like with FastStone Viewer. And the edges of the image will be checked when necessary. With my small expertise, I don't think I can do more but I like the result and it was an interesting challenge. Please try it with a jpg of yours (just rename the jpg accordingly to the script name) Good luck and have a great week-end expandcollapse popup#include <GDIPlus.au3> #include <GUIConstants.au3> #include <MsgBoxConstants.au3> HotKeySet("{ESC}", "_Exit") Global $iZoom = 1.05 ; change the value if needed Global $hGUI1 = 0, $hGUI2 = 0, $hImage = 0, $hBitmap = 0 Global $iLeft2, $iTop2, $iWidth2, $iHeight2 ; $hGUI1 = GUICreate("", @DesktopWidth - 200, @DesktopHeight - 200, -1, -1, $WS_POPUP, $WS_EX_COMPOSITED) $hGUI1 = GUICreate("Image draggable, zoomable, expandable", @DesktopWidth - 200, @DesktopHeight - 200, -1, -1, -1, $WS_EX_COMPOSITED) $aClientSize = WinGetClientSize($hGUI1) $iWidth1 = $aClientSize[0] $iHeight1 = $aClientSize[1] ;==================================================== _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) $iX_Ori = $iX $iY_Ori = $iY $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) If @error Then _Quit("_GDIPlus_BitmapCreateHBITMAPFromBitmap", $sFileName, @error, @extended) $hGUI2 = GUICreate("", $iX, $iY, -1, -1, $WS_CHILD, -1, $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_MOUSEWHEEL, "WM_MOUSEWHEEL") GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING") ; 1st WinMove will update 4 global variables in WM_WINDOWPOSCHANGING() : $iLeft2, $iTop2, $iWidth2, $iHeight2 ; These 4 variables will be used later in WM_MOUSEWHEEL() to calculate accurate $iNewLeftCoord & $iNewTopCoord WinMove($hGUI2, "", ($iWidth1 - $iX) / 2, ($iHeight1 - $iY) / 2, $iX, $iY) ; possible negative coords ToolTip($iX_Ori & " / " & $iY_Ori & " --> " & Int($iX) & " / " & Int($iY), _ @DesktopWidth / 2, 9, "", 0, 2) ; 9 (good position), 0 = no icon, 2 = center tip at x,y 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_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam Sleep(10) ; useful to prevent freezing on slow computers & big images & big repeated zooms If BitShift($wParam, 16) > 0 Then $iX *= $iZoom $iY *= $iZoom Local $iNewLeftCoord = $iLeft2 - ($iWidth2 * $iZoom - $iWidth2) / 2 Local $iNewTopCoord = $iTop2 - ($iHeight2 * $iZoom - $iHeight2) / 2 Else $iX /= $iZoom $iY /= $iZoom Local $iNewLeftCoord = $iLeft2 - ($iWidth2 / $iZoom - $iWidth2) / 2 Local $iNewTopCoord = $iTop2 - ($iHeight2 / $iZoom - $iHeight2) / 2 EndIf WinMove($hGUI2, "", $iNewLeftCoord, $iNewTopCoord, $iX, $iY) ToolTip($iX_Ori & " / " & $iY_Ori & " --> " & Int($iX) & " / " & Int($iY), _ @DesktopWidth / 2, 9, "", 0, 2) ; 9 (good position), 0 = no icon, 2 = center tip at x,y ; Return $GUI_RUNDEFMSG ; (?) EndFunc ;==>WM_MOUSEWHEEL ;==================================================== Func WM_WINDOWPOSCHANGING($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam If $hWnd = $hGUI2 Then Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam) $iLeft2 = DllStructGetData($stWinPos, 3) $iTop2 = DllStructGetData($stWinPos, 4) $iWidth2 = DllStructGetData($stWinPos, 5) $iHeight2 = DllStructGetData($stWinPos, 6) Local $iRight2 = $iLeft2 + $iWidth2 Local $iBottom2 = $iTop2 + $iHeight2 ;~ ConsoleWrite("$iLeft2 = " & $iLeft2 & @TAB & "$iTop2 = " & $iTop2 & @TAB & _ ;~ "$iWidth2 = " & $iWidth2 & @TAB & "$iHeight2 = " & $iHeight2 & @TAB & _ ;~ "$iRight2 = " & $iRight2 & @TAB & "$iBottom2 = " & $iBottom2 & @lf) If $iWidth2 <= $iWidth1 Then ; image (GUI2) fits horizontally within GUI1 => centered & non draggable (hozizontally) DllStructSetData($stWinPos, 3, ($iWidth1 - $iWidth2) / 2) ; left border Else ; image (GUI2) larger than GUI1 => draggable (horizontally) => left & right borders of GUI2 to be checked Select Case $iLeft2 > 0 ; $iLeft2 coord relative to GUI1 because of GUI2 $WS_CHILD style (+++) DllStructSetData($stWinPos, 3, 0) ; left border Case $iRight2 < $iWidth1 ; $iRight2 coord relative to GUI1 because etc... DllStructSetData($stWinPos, 3, $iWidth1 - $iWidth2) ; left border again EndSelect EndIf If $iHeight2 <= $iHeight1 Then ; image (GUI2) fits vertically within GUI1 => centered & non draggable (vertically) DllStructSetData($stWinPos, 4, ($iHeight1 - $iHeight2) / 2) ; top border Else ; image (GUI2) higher than GUI1 => draggable (vertically) => top & bottom borders of GUI2 to be checked Select Case $iTop2 > 0 ; $iTop2 coord relative to GUI1 because of GUI2 $WS_CHILD style (+++) DllStructSetData($stWinPos, 4, 0) ; top border Case $iBottom2 < $iHeight1 ; $iBottom2 coord relative to GUI1 because etc... DllStructSetData($stWinPos, 4, $iHeight1 - $iHeight2) ; top border again EndSelect EndIf EndIf ; Return $GUI_RUNDEFMSG ; (?) EndFunc ;==>WM_WINDOWPOSCHANGING ;==================================================== 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() ToolTip("") _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() GUIDelete($hGUI2) GUIDelete($hGUI1) Exit EndFunc ; _Exit() Edited August 31, 2020 by pixelsearch 2020-08-31 : no more flickering, thanks $WS_EX_COMPOSITED Link to comment Share on other sites More sharing options...
Acce Posted August 29, 2020 Author Share Posted August 29, 2020 (edited) Thanks a lot for your effort in helping me pixelsearch I have almost had a break through myself ., But calculating the edges have been a bit of a nightmare for me. Looking forward to test your version Have a nice weekend yourself there might be a question or two later , hope you dont mind Edit just ran it now and it looks like you nailed it with your version . Im just a bit afraid that your version is to powerful for me to comprehend , Yikes Very nice work indeed , Only thing that I would want is that the img should never be allowed to be smaller then the window , where would I edit that ? in the version I made I had a few lines like this if $fZoom > $iMinZoom Then if $fZoom < $iMaxZoom Then Also the img i loaded had dimension of 1920*915 but for some reason it didn't fill the window completely Edited August 29, 2020 by Acce Link to comment Share on other sites More sharing options...
pixelsearch Posted August 30, 2020 Share Posted August 30, 2020 (edited) I did a lot of rework in the 2nd script above, because $WS_CHILD style in GUI2 may generate negative coords relative to GUI1 (I didn't know that when I scripted it yesterday) This is very different from the 1st script in the precedent page, where $WS_EX_MDICHILD extended style in GUI2 had its coords relative to screen ! 16 hours ago, Acce said: the img i loaded had dimension of 1920*915 but for some reason it didn't fill the window completely With the reworked script above, your 1920*915 image will fill the window completely when you load it. The reason why it didn't work is that I displayed the image centered with positive coords, when in fact it requires negative coords when GUI2 size is > GUI1 size Also another functionality has been improved : when your image size (GUI2) is wider/higher than GUI1, if you drag/push the image (so it's not centered anymore) and after that you zoom again, it will zoom at the good part of the image (and not "back to center" as it was wrongly & quickly scripted) Maybe UEZ will be kind enough to control the simple formula applied to both variables $iNewLeftCoord and $iNewTopCoord found in this line of script : WinMove($hGUI2, "", $iNewLeftCoord, $iNewTopCoord, $iX, $iY) These 2 variables allow a more accurate zoom region, their values may be negative but the tests I did with different images sizes seem ok. You can see the negative values if you uncomment the ConsoleWrite line in Func WM_WINDOWPOSCHANGING(), for example : $iLeft2 = -1748 $iTop2 = -1336 $iWidth2 = 4320 $iHeight2 = 3240 $iRight2 = 2572 $iBottom2 = 1904 $iLeft2 = -1964 $iTop2 = -1498 $iWidth2 = 4752 $iHeight2 = 3564 $iRight2 = 2788 $iBottom2 = 2066 Concerning your other request : 16 hours ago, Acce said: Only thing that I would want is that the img should never be allowed to be smaller then the window I'll see what I can do, but it was important first to improve the 2nd script above... before adding other functionalities Edited August 30, 2020 by pixelsearch typo Link to comment Share on other sites More sharing options...
Acce Posted August 30, 2020 Author Share Posted August 30, 2020 Thanks again for your help your version is really powerful compered to what I wrote , the scroll is much more smooth did you edit your post above with latest changes ? this negative coordinates gives kinda a headache dont it ? lol Link to comment Share on other sites More sharing options...
Acce Posted August 30, 2020 Author Share Posted August 30, 2020 (edited) Hi again I really appreciated the help you have put into this, although im very afraid to use the version you created pixelsearch as that looks so complex and im really unsure how I would be able to continue work on that version , lol do you mind having a look at the version I have created? my version is a little more sluggish but works as intended , my version is prime rely based upon work I have found from UAZ , this obviously an inferior version to his code as well. I was kinda hoping to build it like in this post which is something I almost can get my head around. I have a few questions if you dont mind answer ? 1. I think I dont ever delete the images in my code , how can that be implemented ? 2 why is this so sluggish compered to what you guys wrote ? code bellow expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> HotKeySet("{ESC}", "Terminate") 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, $bg_c = "404040" 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. ; --- Create GUI --- $hGUI = GUICreate('MyGUI', @DesktopWidth - 200, @DesktopHeight - 200, 100, 100, $WS_POPUP) GUICtrlSetBkColor($hGUI, 0x000000) GUISetState() Global Const $dll = DllOpen("user32.dll") _GDIPlus_Startup() $hcartridge = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "test_img0.jpg") $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") ; --- GUI Dimensions --- Global $GUI_Pos = WinGetPos($hGUI) Global $aDim = _GDIPlus_ImageGetDimension($hcartridge) Global $iWidth = _GDIPlus_ImageGetWidth($hcartridge) Global $iHeight = _GDIPlus_ImageGetHeight($hcartridge) Global $fZoom = 1 Global $iMinZoom = 1 Global $iMaxZoom = 20 Global $imgwidth = $iWidth Global $imgheight = $iHeight Global $imgxDIFF = 0 Global $imgyDIFF = 0 Global $iGUIWidth = $GUI_Pos[2] Global $iGUIHeight = $GUI_Pos[3] Draw2Graphic() 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)) Draw2Graphic() $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 Draw2Graphic() $iMinScrollx = (($imgxDIFF / 2)) / $fZoom $iMinScrolly = ($imgyDIFF) / $fZoom If $scroll_y <= -($iMinScrolly) Then $scroll_y = -($iMinScrolly) If $scroll_x <= -(($imgxDIFF / 2)) / $fZoom Then $scroll_x = -(($imgxDIFF / 2)) / $fZoom ConsoleWrite("$iMinScrolly= " & $iMinScrolly & @LF) If $scroll_y >= (($imgheight - $iGUIHeight) / $fZoom) - $iMinScrolly Then $scroll_y = (($imgheight - $iGUIHeight) / $fZoom) - $iMinScrolly EndIf If $scroll_x >= (($imgwidth - $iGUIWidth) / $fZoom) - $iMinScrollx Then $scroll_x = (($imgwidth - $iGUIWidth) / $fZoom) - $iMinScrollx EndIf ConsoleWrite("Min scrolly=" & - (($imgyDIFF / 2)) / $fZoom & @LF) ConsoleWrite("GUI Width = " & $GUI_Pos[2] & @LF) ConsoleWrite("Zoom= " & $fZoom & " img.width:" & $imgwidth & " img.height: " & $imgheight & " img difference =" & $imgxDIFF & @LF) ConsoleWrite("scroll_y = " & $scroll_y & @LF) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hcartridge, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom), _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) ;consolewrite(($aDim[1] - $aDim[1] * $fZoom) / 2) ;ConsoleWrite("Max scroll= " & (($imgwidth - $iGUIWidth) / $fZoom) - $iMinScrollx & @LF) EndFunc ;==>Draw2Graphic Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up If $fZoom > $iMinZoom Then $fZoom -= 0.05 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom $imgxDIFF = $imgwidth - $iWidth $imgyDIFF = $imgheight - $iHeight Draw2Graphic() EndIf Case 0x00780000 $fZoom += 0.05 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom $imgxDIFF = $imgwidth - $iWidth $imgyDIFF = $imgheight - $iHeight Draw2Graphic() EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Func Terminate() Exit EndFunc ;==>Terminate Any more help would really be appreciated Edited August 30, 2020 by Acce Link to comment Share on other sites More sharing options...
pixelsearch Posted August 30, 2020 Share Posted August 30, 2020 @Acce : your script worked nicely on my computer, good job Concerning my script above, a big improvement has been done to eliminate totally the flickering while resizing, after I added $WS_EX_COMPOSITED extended style to GUI1, what a great day ! Thanks to Martin in this thread : He wrote : "Use the extended window style $WS_EX_COMPOSITED and the flickering will go away" Help file : "$WS_EX_COMPOSITED : paints all descendants of a window in bottom-to-top painting order using double-buffering." Script updated above Link to comment Share on other sites More sharing options...
Acce Posted August 30, 2020 Author Share Posted August 30, 2020 Hi thanks again for your reply and kind words "He wrote : "Use the extended window style $WS_EX_COMPOSITED and the flickering will go away" - I have moved to next phase in my project and trying to load an img on top of the background img and it flickers like crazy , so a new window is the way to go yeah ? Link to comment Share on other sites More sharing options...
pixelsearch Posted August 30, 2020 Share Posted August 30, 2020 (edited) 53 minutes ago, Acce said: so a new window is the way to go yeah ? Probably, but I'm not an expert at all you know. As you can see in my script, it worked because : 1) GUI2 got a $WS_CHILD style (hello negative coords) 2) The parent window GUI1 got a $WS_EX_COMPOSITED extended style ("paints all descendants of a window [...] using double-buffering.") I guess that's the reason while the flickering totally disappeared when the child window GUI2 is resized. Concerning the negative coords when using $WS_CHILD, maybe the function _WinAPI_ClientToScreen() could be helpful to replace GUI2 coordinates with screen coordinates (we know that the parent GUI1 got screen coordinates) Then, comparing (for example) the left/top position of the child window to the left/top position of the parent window should be friendlier. Maybe I'll experiment it in my script... but as it works nicely now, I'd better not change anything Edited August 30, 2020 by pixelsearch typo Link to comment Share on other sites More sharing options...
Acce Posted August 30, 2020 Author Share Posted August 30, 2020 I guess we can close this thread now , many thanks for help and your code , will revisit this a bit later when my skill level is a bit higher would love to be able to edit your version but im not at that level yet , lol Link to comment Share on other sites More sharing options...
UEZ Posted September 3, 2020 Share Posted September 3, 2020 I cleaned up my GDI+ code and here is the result which seems to work properly. expandcollapse popup;Coded by UEZ build 2020-09-03 beta #include <GUIConstantsEx.au3> #include <Misc.au3> #include <Screencapture.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() ;~ Global Const $hBmp = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Testbitmap.bmp") Global $hHBitmap = _ScreenCapture_Capture("", 0, 0, 319, 255, 0) Global Const $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) _WinAPI_DeleteObject($hHBitmap) Global Const $bg_c = "808080" Global Const $iW = 800, $iH = 600, $iW2 = $iW / 2, $iH2 = $iH / 2, $zs = 0.025 Global $bW = _GDIPlus_ImageGetWidth($hBmp), $bH = _GDIPlus_ImageGetHeight($hBmp), $bW2 = $bW / 2, $bH2 = $bH / 2 Global Const $hGUI = GUICreate("GDI+ Zoom and Move Image within GUI", $iW, $iH) GUISetState() Global $aMPos1, $aMPos2, $iMPx = $iW2 - $bW2, $iMPy = $iH2 - $bH2, $iMPx_p = 0, $iMPy_p = 0, $z = 1.0, $zp = 1.0 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, 4) _GDIPlus_GraphicsSetInterpolationMode($hContext, 5) Draw2Graphic($iMPx, $iMPy, 1, 1) GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") Do $aMPos1 = MouseGetPos() While _IsPressed("01", $dll) And WinActive($hGUI) $aMPos2 = MouseGetPos() $iMPx = $iMPx_p + $aMPos2[0] - $aMPos1[0] $iMPy = $iMPy_p + $aMPos2[1] - $aMPos1[1] Draw2Graphic($iMPx, $iMPy, $z, $zp) Sleep(10) WEnd $iMPx_p = $iMPx $iMPy_p = $iMPy Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hContext) _GDIPlus_BitmapDispose($hBuffer_Bmp) _GDIPlus_BitmapDispose($hBmp) _GDIPlus_Shutdown() GUIDelete() DllClose($dll) Exit Func Draw2Graphic($x, $y, $fZoom, $fZoom_prev) _GDIPlus_GraphicsClear($hContext, "0xFF" & $bg_c) $x = Min(Max(0, $x), $iW - $bW * $zp - 1) $y = Min(Max(0, $y), $iH - $bH * $zp - 1) Local Const $iW_New = $bW * $fZoom, $iH_New = $bH * $fZoom Local Const $iW_Prev = $bW * $fZoom_prev, $iH_Prev = $bH * $fZoom_prev Local Const $dx = ($iW_New - $iW_Prev) / 2, $dy = ($iW_New - $iW_Prev) / 2 $iMPx -= $dx $iMPy -= $dy _GDIPlus_GraphicsDrawImageRect($hContext, $hBmp, $x - $dx, $y - $dy, $iW_New, $iH_New) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBuffer_Bmp, 0, 0, $iW, $iH) EndFunc ;==>Draw2Graphic Func Max($a, $b) Return ($a > $b) ? $a : $b EndFunc ;==>Max Func Min($a, $b) Return ($a < $b) ? $a : $b EndFunc ;==>Min Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) Local $iDir = _WinAPI_HiWord($wParam) Switch $iDir Case $iDir < 0 If $z - $zs < 8 * $zs Then Return 0 $zp = $z $z -= $zs Draw2Graphic($iMPx, $iMPy, $z, $zp) Return 0 Case Else If ($z + $zs) * $bW > $iW Or ($z + $zs) * $bH > $iH Then Return 0 $zp = $z $z += $zs Draw2Graphic($iMPx, $iMPy, $z, $zp) Return 0 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSEWHEEL Use mouse wheel to zoom image and press lmb to move image around without leaving the borders. pixelsearch 1 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 September 3, 2020 Author Share Posted September 3, 2020 U are really good with this UAZ( i read several of you old posts) are you able to reprogram it to work like I want with a bigger image, which can be scrolled around based on image dimension? here is humble attempt since i didnt have double buffering in the code I posted earlier I had to rewrite it, but now all the cordinate calculations are off, not really sure why ? expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <Misc.au3> ; --- Hotkeys --- HotKeySet("{ESC}", "Terminate") HotKeySet("^0", "_ResetZoom") ; ctr and 0 ; --- Vars --- 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, $bg_c = "404040" Global $aDim, $hImage = 0, $iMinScrollx, $iMinScrolly 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. ; --- MAIN GUI --- $hGUI = GUICreate('MyGUI', @DesktopWidth - 200, @DesktopHeight - 200, 100, 100, $WS_POPUP) GUICtrlSetBkColor($hGUI, 0x000000) ; GUI width and height Global $GUI_Pos = WinGetPos($hGUI) Global $iGUIWidth = $GUI_Pos[2] Global $iGUIHeight = $GUI_Pos[3] GUISetState() ; Load GDI+ resources _GDIPlus_Startup() ;load 1st image $hBitmapTmp = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "background.jpg") $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "background.jpg") ; --- IMG Dimensions --- Global $aDim = _GDIPlus_ImageGetDimension($hImage) Global $iWidth = _GDIPlus_ImageGetWidth($hImage) Global $iHeight = _GDIPlus_ImageGetHeight($hImage) Global $fZoom = 1 Global $iMinZoom = 1 Global $iMaxZoom = 20 Global $imgwidth = $iWidth Global $imgheight = $iHeight Global $imgxDIFF = 0 Global $imgyDIFF = 0 Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic) Global $hBackBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsClear($hBackBuffer) ; draw images into back buffer _GDIPlus_GraphicsDrawImage($hBackBuffer, $hBitmapTmp, 0, 0) ; Windows messages GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") ; Catch key presses Global Const $dll = DllOpen("user32.dll") _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom), _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) ;Draw2Graphic() ;_loadAssets() Func _loadAssets() $base_x = 500 $base_y = 300 $start_x = -$iMinScrollx $start_y = -$iMinScrolly $ix = $start_x - $scroll_x ; pos 0 on img $iy = $start_y - $scroll_y ; pos 0 on img $xx = ($ix + $base_x) * $fZoom $yy = ($iy + $base_y) * $fZoom ; ,x:-1,y:3 $base = 10 $Pos_x = 3 * $base ; Load the GDI+ bitmap $hImage_1 = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\" & "x-png-15.png") $x = _GDIPlus_ImageGetWidth($hImage_1) $y = _GDIPlus_ImageGetHeight($hImage_1) $hImage_resized = _GDIPlus_ImageResize($hImage_1, 25, 25) _GDIPlus_GraphicsDrawImage($hBackBuffer, $hImage_resized, $xx, $yy) EndFunc 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)) Draw2Graphic() $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 Draw2Graphic() $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic) $hBackBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsClear($hBackBuffer) ; draw images into back buffer _GDIPlus_GraphicsDrawImage($hBackBuffer, $hBitmapTmp, 0, 0) _loadAssets() $iMinScrollx = (($imgxDIFF / 2)) / $fZoom $iMinScrolly = ($imgyDIFF) / $fZoom If $scroll_y <= -($iMinScrolly) Then $scroll_y = -($iMinScrolly) If $scroll_x <= -(($imgxDIFF / 2)) / $fZoom Then $scroll_x = -(($imgxDIFF / 2)) / $fZoom ;ConsoleWrite("$iMinScrolly= " & $iMinScrolly & @LF) If $scroll_y >= (($imgheight - $iGUIHeight) / $fZoom) - $iMinScrolly Then $scroll_y = (($imgheight - $iGUIHeight) / $fZoom) - $iMinScrolly EndIf If $scroll_x >= (($imgwidth - $iGUIWidth) / $fZoom) - $iMinScrollx Then $scroll_x = (($imgwidth - $iGUIWidth) / $fZoom) - $iMinScrollx EndIf ;ConsoleWrite("Min scrolly=" & - (($imgyDIFF / 2)) / $fZoom & @LF) ;ConsoleWrite("GUI Width = " & $GUI_Pos[2] & @LF) ;ConsoleWrite("Zoom= " & $fZoom & " img.width:" & $imgwidth & " img.height: " & $imgheight & " img difference =" & $imgxDIFF & @LF) ;ConsoleWrite("scroll_y = " & $scroll_y & @LF) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap, $scroll_x, $scroll_y, $aDim[0], $aDim[1], _ ($aDim[0] - $aDim[0] * $fZoom) / 2, ($aDim[1] - $aDim[1] * $fZoom), _ $aDim[0] * $fZoom, $aDim[1] * $fZoom) EndFunc ;==>Draw2Graphic Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0xFF880000 ;mouse wheel up If $fZoom > $iMinZoom Then $fZoom -= 0.1 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom $imgxDIFF = $imgwidth - $iWidth $imgyDIFF = $imgheight - $iHeight Draw2Graphic() EndIf Case 0x00780000 $fZoom += 0.1 $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom $imgxDIFF = $imgwidth - $iWidth $imgyDIFF = $imgheight - $iHeight Draw2Graphic() EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel func _ResetZoom() $fZoom = 1 $scroll_x = 0 $scroll_y = 0 Global $sx, $z = 5, $sy = 0 , $mc2 = 0 , $f = 0, $scroll_x = 0, $scroll_y = 0, $current_iPos_y = 0, $RQGUI_POS[3] = [280, 325, 0] $imgwidth = $iWidth * $fZoom $imgheight = $iHeight * $fZoom $imgxDIFF = $imgwidth - $iWidth $imgyDIFF = $imgheight - $iHeight Draw2Graphic() EndFunc Func Terminate() Exit EndFunc ;==>Terminate Link to comment Share on other sites More sharing options...
Ferropasha Posted November 25, 2020 Share Posted November 25, 2020 On 8/30/2020 at 11:40 PM, pixelsearch said: Concerning my script above, a big improvement has been done to eliminate totally the flickering while resizing, after I added $WS_EX_COMPOSITED extended style to GUI1, what a great day ! Hi Pixelsearch. I am looking into incorporating image zooming feature into one of my GUIs and your approach is a very easy and elegant way of doing it. But my experiments with your code are not entirely successful (at this stage I am just using my own image, no other changes to your code were made). The problem is that flickering is not entirely gone. Generally the GUI doesn't flicker when I change zoom level whith mouse wheel. But there are two cases the problem still shows up in my experiments. First is when I drag the image whith my left mouse button pressed (but this one is mild). And the second is when I minimize the window to tray and later unfurl it back. After that it starts flickering like hell when I adjust zoom level whith my mose wheel. Would you or UEZ be so kind as to provide some advice on how it would be possible to get rid of this nasty little problem? 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