Leaderboard
Popular Content
Showing content with the highest reputation on 12/20/2015 in all areas
-
OK Here is a working example . When you hit F1 you pause/unpause (using the global $Paused variable), and when paused it will automatically unpause if the delay is reached (using TimerDiff) HotKeySet("{F1}", "Pause") HotKeySet("{ESC}", "Terminate") Global $Paused = 0 Global $delay = 3000 While 1 ToolTip('Script is NOT paused', 0, 0) Sleep(100) WEnd Func Pause() $Paused = Not $Paused $nBegin = TimerInit() While $Paused ; exit loop if $Paused = 0 ToolTip('Script is paused', 0, 0) ; exit loop if $delay reached If TimerDiff($nBegin) > $delay Then $Paused = 0 Wend EndFunc Func Terminate() Exit EndFunc ;==>Terminate1 point
-
J1, you should add the $INET_FORCERELOAD parameter, no ?1 point
-
A utility for getting the points array of a bezier curve (spline) for use elsewhere. About Bezier Curve The two end points ( start and last point) have ony one control point. The intermediate points on the bezier curve have two control points. The control points have a thin red line to the curve point they control. Each control point of a curve point governs the entry an exit shape of the curve at that curve point. The angle to, and distance away from the curve point determines the shape of the curve before and after that point on the bezier curve. User Guide A single click and drag on a red spot that does not turn green, drags the desktop size, invisible, layered GUI. A double click and drag on a red spot that does turn green, allows repositioning of that spot (point). And the bezier curve moves in response. Once a point turns green, a single click on another red point is all that is needed the turn other points green for repositioning. When the point turns green and the left mouse button is held down, the tooltip appears showing the point number in the array of points, and the x and y coordinate values. Context Menu Right mouse button click on a point or on the curve brings up a context menu containing:- Toggle hide/show points Add a point - Actually adds three points, a curve point and two control points. Delete a point - Actually deletes three points. Write points array to text file, PolyDat.txt in same directory as script. Notepad.exe is used for display of data. Set space size around bezier points. - Should a point be dragged off layered GUI, entering a space value around all the points will reposition all the points on the layered gui with the space specified. When the bezier curve is how you want it, you can set the space boundary size to zero. Then when you write points to text file, the recommended size width x height, is the minimun size rectangle that will contain all the points. Exit - To exit #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <GuiSlider.au3> #include <Date.au3> #include <WindowsConstants.au3> #include <misc.au3> #include <GuiMenu.au3> #include <WinAPI.au3> Global Const $iOpacity = 255 Global $hGui, $hGraphic, $hBitmap, $hBrush, $hBrush, $SBoth, $GrnPt, $hBrushGrad, $pt = 0 Global $iMinBorder = 25, $bStatFlag = False Global $dll = DllOpen("user32.dll") Global $GuiSizeX = @DesktopWidth, $GuiSizeY = @DesktopHeight ; 200 ; ;Global Const $WM_LBUTTONDOWN = 0x0201 ; Drag Window 1 of 3 addin Global $msg, $exit, $moveAll, $viewpoints, $pointsVisible = 1 Global Const $SS_CENTER = 1 Global $aPoints Opt("MouseCoordMode", 0) Opt("GUIOnEventMode", 1) Opt("WinTitleMatchMode", 2) Local $aPointsJigSaw[38][2] = [[37, 0],[45, 134],[85, 142],[94, 148],[91, 127],[81, 98],[128, 100], _ [112, 130],[105, 143],[123, 153],[161, 138],[173, 220],[154, 177],[147, 183], _ [121, 184],[132, 215],[148, 205],[179, 194],[162, 233],[157, 256],[137, 253], _ [114, 240],[111, 268],[131, 291],[80, 292],[97, 268],[103, 250],[85, 254], _ [44, 257],[41, 237],[25, 204],[62, 218],[80, 218],[79, 186],[59, 194], _ [29, 211],[38, 173],[45, 134]] Local $aPoints26A[26][2] = [[25, 0],[215, 117],[289, 54],[269, 136],[355, 118],[306, 184],[394, 197], _ [309, 225],[385, 274],[287, 270],[313, 346],[227, 288],[198, 366],[163, 284], _ [88, 333],[122, 259],[35, 280],[109, 221],[25, 201],[108, 180],[41, 130], _ [127, 138],[96, 64],[162, 121],[187, 42],[215, 117]] Local $aPoints19A[20][2] = [[19, 0],[348, 25],[348, 94],[206, 94],[281, 198],[344, 198],[344, 250], _ [198, 250],[198, 198],[255, 198],[172, 94],[114, 177],[145, 177],[145, 229], _ [36, 229],[36, 177],[89, 177],[145, 94],[25, 94],[25, 25]] Local $aPoints10A[11][2] = [[10, 0],[618, 105],[278, 131],[334, 187],[801, 411],[52, 377],[604, 165], _ [123, 240],[101, 137],[483, 521],[185, 97]] Local $aPoints10B[11][2] = [[10, 0],[367, 53],[590, 152],[881, 185],[788, 418],[902, 667],[569, 674], _ [308, 847],[253, 547],[56, 377],[287, 248]] BezierCurve($aPointsJigSaw) ; <============= Start ================== Func BezierCurve($aPoints1) Local $0nPoint, $mouseDiffX, $mouseDiffY, $MouseStartPos, $pos $aPoints = $aPoints1 $hGui = GUICreate("GDI+", $GuiSizeX, $GuiSizeY, -1, -1, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUIRegisterMsg($WM_LBUTTONDOWN, "_WinMove") ; Drag Window 2 of 3 addin $ContextMenu = GUICtrlCreateContextMenu() $viewpoints = GUICtrlCreateMenuItem("Show points", $ContextMenu, 1) GUICtrlSetState($viewpoints, $GUI_CHECKED) GUICtrlSetOnEvent($viewpoints, "ShowaPoints") $addpoint = GUICtrlCreateMenuItem("Add a point numbered after selected point number", $ContextMenu) GUICtrlSetOnEvent($addpoint, "AddPoint") $substractpoint = GUICtrlCreateMenuItem("Delete the selected (green) point ", $ContextMenu) GUICtrlSetOnEvent($substractpoint, "SubstractPoint") $separator1 = GUICtrlCreateMenuItem("", $ContextMenu) ; create a separator line $Currentpoints = GUICtrlCreateMenuItem("Write points to 'PolyDat.txt' file", $ContextMenu) GUICtrlSetOnEvent($Currentpoints, "CurrentPoints2Console") $Border = GUICtrlCreateMenuItem("Set Space Size around Bezier Points", $ContextMenu) GUICtrlSetOnEvent($Border, "Border") $separator1 = GUICtrlCreateMenuItem("", $ContextMenu) ; create a separator line $MenuItemExit = GUICtrlCreateMenuItem("Exit", $ContextMenu) GUICtrlSetOnEvent($MenuItemExit, "quitclk") GUISetState() Draw(-1) Do $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Or $exit = 1 Then ExitLoop If _IsPressed("01", $dll) Then ; Virtual-Key Code (0x01) Left mouse button $MouseStartPos = MouseGetPos() $0nPoint = CheckOverPoint($MouseStartPos[0], $MouseStartPos[1]) $mouseDiffX = 0 If $0nPoint > 0 Then ToolTip(TooltipFunc($0nPoint), _ClientToScreen($hGui, $aPoints, $0nPoint, 0) - 30, _ _ClientToScreen($hGui, $aPoints, $0nPoint, 1) + 20) $moveAll = 1 Draw($0nPoint) $GrnPt = $0nPoint While _IsPressed("01", $dll) ; Virtual-Key Code (0x01) Left mouse button $pos = MouseGetPos() $mouseDiffX = Int(($pos[0] - $MouseStartPos[0])) $mouseDiffY = Int(($pos[1] - $MouseStartPos[1])) If Abs($mouseDiffX) > 0 Or Abs($mouseDiffY) > 0 Then $aPoints[$0nPoint][0] = $pos[0] $aPoints[$0nPoint][1] = $pos[1] Draw($0nPoint) ToolTip(TooltipFunc($0nPoint), _ClientToScreen($hGui, $aPoints, $0nPoint, 0) - 30, _ _ClientToScreen($hGui, $aPoints, $0nPoint, 1) + 20) Sleep(200) EndIf Sleep(20) WEnd ToolTip("") Else $moveAll = 0 Draw(-1) EndIf EndIf ; mouse BTN 1 pressed?? Sleep(20) Until _IsPressed("1B") ; ESC key DllClose($dll) EndFunc ;==>BezierCurve ;Check if mouse pointer is over a red/green spot Func CheckOverPoint($MouseX, $MouseY) Local $x, $retValue = -1 For $x = 0 To UBound($aPoints) - 1 If $MouseX < $aPoints[$x][0] + 5 And $MouseX > $aPoints[$x][0] - 5 And _ $MouseY < $aPoints[$x][1] + 5 And $MouseY > $aPoints[$x][1] - 5 Then $retValue = $x EndIf Next Return $retValue EndFunc ;==>CheckOverPoint Func TooltipFunc($0nPoint) Local $sText $sText = "Point: " & $0nPoint & @CRLF & " X: " & $aPoints[$0nPoint][0] & _ " Y: " & $aPoints[$0nPoint][1] & @CRLF Return $sText EndFunc ;==>TooltipFunc Func Draw($pt) Local $hWnd, $hDC, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend, $hBrushRed, $hBrushGreen, $hPen, $aCentPt $GrnPt = $pt _GDIPlus_Startup() $hWnd = _WinAPI_GetDC(0) $hDC = _WinAPI_CreateCompatibleDC($hWnd) $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSizeX, $GuiSizeY) _WinAPI_SelectObject($hDC, $hBitmap) $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) $hPen = _GDIPlus_PenCreate(0xFF010101, 2) $hPenRed = _GDIPlus_PenCreate(0xFFFF0000, 1) $hBrushRed = _GDIPlus_BrushCreateSolid(0x8fff0000) ;red $hBrushGreen = _GDIPlus_BrushCreateSolid(0x8f00ff00) ;Green _GDIPlus_GraphicsClear($hGraphic) _GDIPlus_GraphicsDrawBeziers($hGraphic, $aPoints, $hPen) If $pointsVisible = 1 Then For $x = 1 To UBound($aPoints) - 1 If $x = $pt Then _GDIPlus_GraphicsFillEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10, $hBrushGreen) Else _GDIPlus_GraphicsFillEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10, $hBrushRed) EndIf _GDIPlus_GraphicsDrawEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10) If Mod($x - 1, 3) = 0 And $x > 3 And $x < UBound($aPoints) - 3 Then _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[$x][0], $aPoints[$x][1], $aPoints[$x + 1][0], $aPoints[$x + 1][1], $hPenRed) _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[$x][0], $aPoints[$x][1], $aPoints[$x - 1][0], $aPoints[$x - 1][1], $hPenRed) EndIf Next _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[1][0], $aPoints[1][1], $aPoints[2][0], $aPoints[2][1], $hPenRed) _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[UBound($aPoints) - 1][0], $aPoints[UBound($aPoints) - 1][1], _ $aPoints[UBound($aPoints) - 2][0], $aPoints[UBound($aPoints) - 2][1], $hPenRed) EndIf $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", $GuiSizeX) DllStructSetData($tSize, "Y", $GuiSizeY) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPenRed) ; _GDIPlus_BrushDispose($hBrushGrad[2]) _GDIPlus_BrushDispose($hBrushRed) _GDIPlus_BrushDispose($hBrushGreen) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() _WinAPI_ReleaseDC(0, $hWnd) _WinAPI_DeleteDC($hDC) Return EndFunc ;==>Draw ;Called from context menu check / uncheck Show Points Func ShowaPoints() If $pointsVisible = 1 Then GUICtrlSetState($viewpoints, $GUI_UNCHECKED) $pointsVisible = 0 Else GUICtrlSetState($viewpoints, $GUI_CHECKED) $pointsVisible = 1 EndIf Draw(-1) Return EndFunc ;==>ShowaPoints ;Called from context menu Write Current points to console Func CurrentPoints2Console() If WinExists("PolyDat.txt") Then WinActivate("PolyDat.txt") WinWaitActive("PolyDat.txt") Send("^s") WinWaitActive("PolyDat.txt") Send("{ALT}") Send("f") Send("x") EndIf $hFile = FileOpen("PolyDat.txt", 1) $aPoints[0][0] = UBound($aPoints) - 1 $aPoints[0][1] = 0 $FromStats = SizeStats() $text = "Local $aPoints[" & UBound($aPoints) & "][2] = [[" & $aPoints[0][0] & "," & $aPoints[0][1] & "]," For $x = 1 To UBound($aPoints) - 1 If Mod($x, 7) = 0 Then $text &= " _" & @CRLF & " " $text &= "[" & $aPoints[$x][0] & "," & $aPoints[$x][1] & "]," Next $text = StringTrimRight($text, 1) & "]" FileWriteLine($hFile, "; =========== " & _Now() & " ===================" & @CRLF & @CRLF) FileWriteLine($hFile, $text & @CRLF & @CRLF) FileWriteLine($hFile, "Recommended GUI size : Width X Height = " & $FromStats[4] & " X " & $FromStats[5] & @CRLF & _ "About the points in array: MiniX, MiniY = " & $FromStats[0] & ", " & $FromStats[1] & _ " MaxX, MaxY = " & $FromStats[2] & ", " & $FromStats[3] & _ " Border set to " & $iMinBorder & @CRLF & @CRLF) FileClose($hFile) Run("Notepad.exe PolyDat.txt") Return EndFunc ;==>CurrentPoints2Console ; Called from context menu Exit script. Func quitclk() $exit = 1 ; Chr(27) ; EndFunc ;==>quitclk ; Returns a suitable Width and Height to encompass polygon for use in ; save as image and write to console. Max & Min points are just for info. Func SizeStats() Local $iMinX = $aPoints[1][0], $iMaxX = $aPoints[1][0], $x = 0, $y = 0 Local $iMinY = $aPoints[1][1], $iMaxY = $aPoints[1][1] Local $iMinWidth, $iMinHeigth For $r = 1 To UBound($aPoints) - 1 If $aPoints[$r][0] < $iMinX Then $iMinX = $aPoints[$r][0] If $aPoints[$r][1] < $iMinY Then $iMinY = $aPoints[$r][1] If $aPoints[$r][0] > $iMaxX Then $iMaxX = $aPoints[$r][0] If $aPoints[$r][1] > $iMaxY Then $iMaxY = $aPoints[$r][1] Next Local $iMaxBorder = 80 If Not $bStatFlag Then If $iMinX < $iMinBorder Then $x = $iMinBorder - $iMinX If $iMinY < $iMinBorder Then $y = $iMinBorder - $iMinY If ($iMinX - $iMinBorder) > $iMaxBorder Then $x = $x - ($iMinX - $iMinBorder) If ($iMinY - $iMinBorder) > $iMaxBorder Then $y = $y - ($iMinY - $iMinBorder) If $x <> 0 Or $y <> 0 Then $aPoints = arrayplusScalarPoint($aPoints, $x, $y); If $iMinBorder = 0 Then $aPoints = arrayplusScalarPoint($aPoints, -$iMinX, 0); $bStatFlag = True SizeStats() EndIf $bStatFlag = False $iMinWidth = $iMinX + $iMaxX ; = (2 * $iMinX) + actual width $iMinHeigth = $iMinY + $iMaxY ; = (2 * $iMinY) + actual height Local $aStats[6] = [$iMinX, $iMinY, $iMaxX, $iMaxY, $iMinWidth, $iMinHeigth] Draw(-1) Return $aStats EndFunc ;==>SizeStats ;Called from context menu. Adds a points. eg. if point3 is selected (green) then a new point 4 is added Func AddPoint() ;Local $LastColor If $GrnPt <> Mod($GrnPt - 1, 3) And $GrnPt < 3 And $GrnPt > UBound($aPoints) - 3 Then MsgBox(0, "Add a Point", "Select a point.(NOT Endpoints). (Click on a red point to turn it green)", 0, _ WinGetHandle('Program Manager'));$hGui ); Else Dim $aRET[UBound($aPoints) + 3][2] For $r = 1 To UBound($aPoints) - 1 If $r = $GrnPt Then $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] $aRET[$r + 1][0] = $aPoints[$r][0] + 10 $aRET[$r + 1][1] = $aPoints[$r][1] + 10 $aRET[$r + 2][0] = $aPoints[$r][0] + 20 $aRET[$r + 2][1] = $aPoints[$r][1] + 20 $aRET[$r + 3][0] = $aPoints[$r][0] + 30 $aRET[$r + 3][1] = $aPoints[$r][1] + 30 ElseIf $r > $GrnPt Then $aRET[$r + 3][0] = $aPoints[$r][0] $aRET[$r + 3][1] = $aPoints[$r][1] Else $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] EndIf Next $aPoints = $aRET $aRET = "" Draw(-1) EndIf Return EndFunc ;==>AddPoint ; Called from context menu. Deletes the selected (green) point. Func SubstractPoint() If $GrnPt <> Mod($GrnPt - 1, 3) And $GrnPt < 3 And $GrnPt > UBound($aPoints) - 3 Then MsgBox(0, "Substract a point", "Select a point. (Click on a red point to turn it green", 0, $hGui) Else Dim $aRET[UBound($aPoints) - 3][2] For $r = 1 To UBound($aRET) - 1 If $r >= $GrnPt - 1 Then $aRET[$r][0] = $aPoints[$r + 2][0] $aRET[$r][1] = $aPoints[$r + 2][1] Else $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] EndIf Next $aPoints = $aRET $aRET = "" Draw(-1) EndIf Return EndFunc ;==>SubstractPoint Func Border() Local $x = 0, $y = 0 $Bdr = InputBox("Change border space size around the image to be saved", _ "Current border size is " & $iMinBorder & @CRLF & @CRLF & _ "Enter new border size, or Cancel" & @CRLF & @CRLF, $iMinBorder, "", 400, 150, -1, -1, -1, $hGui) If Not @error And Number($Bdr) >= 0 Then $iMinBorder = Number($Bdr) ; Min border size = 1 SizeStats() Draw(-1) Return EndFunc ;==>Border ;Matrix $a plus a Scalar (number) $k (Used in Margin/border Utility) Func arrayplusScalarPoint(ByRef $pts, $x = 0, $y = 0) Dim $aRET[UBound($pts)][2] For $r = 0 To UBound($pts) - 1 $aRET[$r][0] = $pts[$r][0] + $x $aRET[$r][1] = $pts[$r][1] + $y Next Return $aRET EndFunc ;==>arrayplusScalarPoint ; ================================================================= ; Drag Window 3 of 3 addin ; ================================================================= Func _WinMove($hWnd, $Command, $wParam, $lParam) If BitAND(WinGetState($hWnd), 32) Then Return $GUI_RUNDEFMSG If $moveAll = 0 Then DllCall("user32.dll", "int", "SendMessage", "hWnd", $hWnd, "int", $WM_NCLBUTTONDOWN, "int", $HTCAPTION, "int", 0) EndIf Return EndFunc ;==>_WinMove ;_ClientToScreen() Function - Converts client (gui) coordinates to Screen coordinates ;Input - $hwnd - Handle from GUICreate() function ; $cPoint - Array of points in $cPoint[n+1][2] = [[n,0],[x1,y1],[x2,y2],...[xn,yn]] format ; Where n = Number of points ; $index - Index of array e.g for point $cPoint[2][0] and $cPoint[2][1] $index = 2 ; $xy - if 0 then returns screen coordinate of x ; - If 1 then returns screen coordinate of y ; - if 2 then returns array where return array[0] = x, and array[1] = y value Func _ClientToScreen($hWnd, ByRef $cPoint, $index, $xy = 2) Local $tpoint = DllStructCreate("int X;int Y") Local $ret[2] DllStructSetData($tpoint, "X", $cPoint[$index][0]) DllStructSetData($tpoint, "Y", $cPoint[$index][1]) _WinAPI_ClientToScreen($hWnd, $tpoint) $ret[0] = DllStructGetData($tpoint, "X") $ret[1] = DllStructGetData($tpoint, "Y") If $xy = 0 Then Return $ret[0] ; x value If $xy = 1 Then Return $ret[1] ; y value If $xy = 2 Then Return $ret ; array EndFunc ;==>_ClientToScreen ; #FUNCTION# ===================================================================== ; Name...........: _GDIPlus_GraphicsDrawBeziers ========================================== #cs ; Parameters ....: ;$hGraphics Handle to a Graphics object ;$aPoints - An array of points $aPoints[0][0] Total number of points (3*n - 2), where n is number of points on curve $aPoints[0][1] Y coordinate of the 1st (starting) point $aPoints[1][0] X coordinate of the 1st (starting) point $aPoints[1][1] Y coordinate of the 1st (starting) point $aPoints[2][0] X coordinate of the control point for 1st (starting) point $aPoints[2][1] Y coordinate of the first control for 1st (starting) point $aPoints[3][0] X coordinate of the first control point for 2nd point $aPoints[3][1] Y coordinate of the first control point for 2nd point $aPoints[4][0] X coordinate of the 2nd point $aPoints[4][1] Y coordinate of the 2nd point $aPoints[5][0] X coordinate of the second control point for 2nd point $aPoints[5][1] Y coordinate of the second control point for 2nd point $aPoints[n][0] X coordinate of the first control point for nth point $aPoints[n][1] Y coordinate of the first control point for nth point $aPoints[n+1][0] X coordinate of the nth point $aPoints[n+1][1] Y coordinate of the nth point $aPoints[n+2][0] X coordinate of the second control point for nth point $aPoints[n+2][1] Y coordinate of the second control point for nth point $aPoints[Second Last point][0] X coordinate of the first control point for last point $aPoints[Second Last point][1] Y coordinate of the first control point for last point. $aPoints[Last point][0] X coordinate of the ending point $aPoints[Last point][1] Y coordinate of the ending point $hPen Handle to a pen object that is used to draw the bezier. If 0, a solid black pen with a width of 1 will be used. GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points, INT count) #ce Func _GDIPlus_GraphicsDrawBeziers($hGraphics, $aPoints, $hPen = 0) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 ; Modified was $iCount = $aPoints[0][0] $tPoints = DllStructCreate("int[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next ;_GDIPlus_PenDefCreate($hPen) $aResult = DllCall($ghGDIPDll, "int", "GdipDrawBeziersI", "hwnd", $hGraphics, "hwnd", $hPen, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended _GDIPlus_PenDispose($hPen) If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_GDIPlus_GraphicsDrawBeziers Enjoy. Edit: Updated to run on AutoIt version 3.3.6.1 (on 31/10/2010).1 point
-
This script creates a centre jigsaw piece from a bezier curve and fills that piece with a clipped image. The finished jigsaw piece can be rotated at 90 degree increments. using the middle mouse button or spacebar. Just wanted to see if it could be done completely in AutoIt. What would be really good if a bevelled edge could be added to the jigsaw piece as ImageMagick can do - without using ImageMagick. This script leave an image file, JigSawCentrePiece.png, on the desktop. #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <Misc.au3> #include <WindowsConstants.au3> Global Const $GUI_Width = 400, $GUI_Height = 400 Global $hGui1 $hGui = GUICreate("GDI+", $GUI_Width, $GUI_Height, (@DesktopWidth - $GUI_Width) / 2, 10) GUISetState() ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize. _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@WindowsDir & "\Web\Wallpaper\Ascent.jpg") $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GUI_Width, $GUI_Height, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) _GDIPlus_GraphicsClear($hGraphic, 0xFFF8FFE8) _AntiAlias($hGraphic) _GDIPlus_GraphicsClear($hGraphic, 0xFFF8FFE8) Local $aPoints[38][2] = [[37, 0],[20, 36],[60, 44],[69, 50],[66, 29],[56, 0],[103, 2], _ [87, 32],[80, 45],[98, 55],[136, 40],[148, 122],[129, 79],[122, 85], _ [96, 86],[107, 117],[123, 107],[154, 96],[137, 135],[132, 158],[112, 155], _ [89, 142],[86, 170],[106, 193],[55, 194],[72, 170],[78, 152],[60, 156], _ [19, 159],[16, 139],[0, 106],[37, 120],[55, 120],[54, 88],[34, 96], _ [4, 113],[13, 75],[20, 36]] Local $x = 0, $y = 10 _SetClipBezier($hGraphic, $aPoints, $x, $y) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $GUI_Width, $GUI_Height) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) $hBitmap = ImageColorToTransparent($hBMPBuff, $x, $y, 154, 194);, 0xFFFFFFFF) _GDIPlus_ImageSaveToFile($hBitmap, @DesktopCommonDir & "\JigSawCentrePiece.png") ;ShellExecute(@DesktopCommonDir & "\JigSawCentrePiece.png") GDIPlus_ResetClip($hGraphic) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, $GUI_Width / 2 - 50, $GUI_Height / 2 - 30, $GUI_Width / 2 + 50, $GUI_Height / 2 + 30) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) GUICtrlCreateLabel("Press middle mouse button or spacebar" & @CRLF & _ "to rotate layered GUI ( JigSaw piece )." & @CRLF & " And, it is draggable.", $GUI_Width / 2, 10) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hBitmap) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_ImageDispose($hImage) ;============================================================================== Global Const $iOpacity = 254 ;Global Const $ULW_ALPHA = 2 Global $GuiSize = 200 Global Const $nPI = 3.1415926535897932384626433832795 Global Const $WM_LBUTTONDOWN = 0x0201 ; Drag Window 1 of 3 addin Global $iPath = @DesktopCommonDir & "\JigSawCentrePiece.png" Global $angle ;$nAngle = 0 GUIRegisterMsg($WM_LBUTTONDOWN, "_WinMove") ; Drag Window 2 of 3 addin $hGui1 = GUICreate("GDI+ Rotate", $GuiSize, $GuiSize, @DesktopWidth/2 - 230, 200, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetState() RotatePiece() Do $msg = GUIGetMsg() If _IsPressed("20") Or _IsPressed("04") Then ; SpaceBar or middle mouse button $angle = Mod($angle + 90, 360) ; 10deg increments (plus clockwise) RotatePiece($angle) EndIf Until _IsPressed("1B") Or $msg = -3 ; ESC key ; Clean up resources _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_GraphicsDispose($hGraphicGUI) _GDIPlus_Shutdown() Func RotatePiece($angle = 0) Local $hMatrix, $nX, $nY, $x, $y, $Pos[4], $radius, $hGraphic, $hImage Local $hWnd, $hDC, $hBitmap, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend, $nXt, $nYt $hWnd = _WinAPI_GetDC(0) $hDC = _WinAPI_CreateCompatibleDC($hWnd) $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSize, $GuiSize) _WinAPI_SelectObject($hDC, $hBitmap) $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) $hImage = _GDIPlus_ImageLoadFromFile($iPath) $Pos = WinGetPos($hGui1) ; "GDI+ Rotate") ConsoleWrite($Pos & @CRLF) $nX = $Pos[0] $nY = $Pos[1] $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixRotate($hMatrix, $angle, False) _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix) $x = ($GuiSize / 2) * Cos($angle * $nPI / 180) - ($GuiSize / 2) + $nX - ($GuiSize / 2) * Sin($angle * $nPI / 180);Parametric equations for a circle $y = ($GuiSize / 2) * Sin($angle * $nPI / 180) - ($GuiSize / 2) + $nY + ($GuiSize / 2) * Cos($angle * $nPI / 180); and adjusts for center of text box $nXt = ($nX - $x) * Cos($angle * $nPI / 180) + ($nY - $y) * Sin($angle * $nPI / 180) $nYt = -($nX - $x) * Sin($angle * $nPI / 180) + ($nY - $y) * Cos($angle * $nPI / 180) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, $nXt + ($GuiSize * 0.2), $nYt + ($GuiSize * 0.2), $GuiSize * 0.6, $GuiSize * 0.6) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", $GuiSize) ;$iWidth ) DllStructSetData($tSize, "Y", $GuiSize) ;$iHeight) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGui1, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA) Sleep(500) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_MatrixDispose($hMatrix) _WinAPI_ReleaseDC(0, $hWnd) _WinAPI_DeleteObject($hBitmap) _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteDC($hDC) Return 1 EndFunc ;==>RotatePiece ; ================================================================= ; Drag Window 3 of 3 addin (from AutoIt forum) ; ================================================================= Func _WinMove($hWnd, $Command, $wParam, $lParam) If BitAND(WinGetState($hWnd), 32) Then Return $GUI_RUNDEFMSG DllCall("user32.dll", "int", "SendMessage", "hWnd", $hWnd, "int", $WM_NCLBUTTONDOWN, "int", $HTCAPTION, "int", 0) EndFunc ;==>_WinMove Func _SetClipBezier($hGraphics, $aPoints, $x, $y) Local $aResult, $hPath = GDIPlus_CreatePath() Local $aTempPoints = ArrayPlusScalar($aPoints, $x, $y) _GDIPlus_AddPathBeziers($hPath, $aTempPoints) ;Trace path with pen Local $hPen = _GDIPlus_PenCreate() _GDIPlus_PenDispose($hPen) ;Apply mask $aResult = DllCall($ghGDIPDll, "int", "GdipSetClipPath", "hwnd", $hGraphics, "ptr", $hPath, "int", 1) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_SetClipBezier Func ArrayPlusScalar($pts, $x = 0, $y = 0) Dim $aRET[UBound($pts)][2] For $r = 0 To UBound($pts) - 1 $aRET[$r][0] = $pts[$r][0] + $x $aRET[$r][1] = $pts[$r][1] + $y Next Return $aRET EndFunc ;==>ArrayPlusScalar Func _AntiAlias($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_AntiAlias Func _GDIPlus_CreateTextureTrans($hImage, $nTrans = 0.5, $iX = 0, $iY = 0, $iWidth = "", $iHeight = "") Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) If $iWidth = 0 Or $iWidth = "" Then $iWidth = $iW If $iHeight = 0 Or $iHeight = "" Then $iHeight = $iH ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;blending values: $x = DllStructSetData($tColorMatrix, 1, 1, 1) * DllStructSetData($tColorMatrix, 2, 1, 2) * DllStructSetData($tColorMatrix, 3, 1, 3) * _ DllStructSetData($tColorMatrix, 4, $nTrans, 4) * DllStructSetData($tColorMatrix, 5, 1, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) $hImgAttrib = $hImgAttrib[1] DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, _ "int", 1, "ptr", DllStructGetPtr($tColorMatrix), "ptr", 0, "int", 0) ;;draw image into graphic object with alpha blend Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateTextureIAI", "hwnd", $hImage, "ptr", $hImgAttrib, "int", $iX, "int", _ $iY, "int", $iWidth, "int", $iHeight, "ptr*", 0) ;clean up DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return $aResult[7] EndFunc ;==>_GDIPlus_CreateTextureTrans Func GDIPlus_CreatePath() Local $hPath, $res $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", 0, "int*", 0) Return $hPath[2] EndFunc ;==>GDIPlus_CreatePath ; GdipResetClip(GpGraphics *graphics) Func GDIPlus_ResetClip($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipResetClip", "hwnd", $hGraphics) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_ResetClip ;GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) Func _GDIPlus_AddPathBeziers($hPath, $aPoints) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 $tPoints = DllStructCreate("float[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathBeziers", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[2], 0, $aResult[1]); $aResult[1] EndFunc ;==>_GDIPlus_AddPathBeziers Func ImageColorToTransparent($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iColor = Default) Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB) If $iColor = Default Then $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1) ; Transparent color ConsoleWrite($iColor & @CRLF) ProgressOn("Making a color Transparent", "The image is being processed.", "0 percent", -1, -1, 16) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") For $i = 0 To $GuiSizeX - 1 For $j = 0 To $GuiSizeY - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $v_Value = DllStructGetData($v_Buffer, 1) If Hex($v_Value, 6) = Hex($iColor, 6) Then DllStructSetData($v_Buffer, 1, Hex($iColor, 6)) ; Sets Transparency here. Alpha Channel = 00, not written to. EndIf Next ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent") Next _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ProgressOff() Return $hBitmap1 EndFunc ;==>ImageColorToTransparent ;The GetPixel method gets the color of a specified pixel in this bitmap. Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY) Local $tArgb, $pArgb, $aRET $tArgb = DllStructCreate("dword Argb") $pArgb = DllStructGetPtr($tArgb) $aRET = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb) Return "0x" & Hex(DllStructGetData($tArgb, "Argb")) EndFunc ;==>GDIPlus_BitmapGetPixel ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) ; Check, if the GUI with the Graphic should be repainted ; The sequencial order of these two commands is important. _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT1 point