Jump to content

Recommended Posts

Posted (edited)

The following is the code

#include-once
#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Misc.au3>

_GDIPlus_Startup()
Opt("MouseCoordMode", 2)

;User Values
Global $i_WindAngle = -60 ;Time Unit is Milli-Secs. Angle in Degrees
Global $hGfx_Direction, $hMatrix = _GDIPlus_MatrixCreate() ;The Graphics where Animation and Direction Change will occur
Global $hGfx_DirectionBitmap, $hBmp_Direction;The Bitmap and Bitmap Graphic object of the Direction control.
;...-------===============================================

OnAutoItExitRegister("Dispose")

;Create Pen for drawing direction
Global $hPen = _GDIPlus_PenCreate(0xFF00FFAB)
Global $hArrowCap = _GDIPlus_ArrowCapCreate(5, 3)
_GDIPlus_PenSetCustomEndCap($hPen, $hArrowCap)
;...-------===============================================

;Create the GUI for Animation.
Global $hGUI = GUICreate("GDI+ Test", 300, 150)

GUICtrlCreateLabel("WindAngle:", 10, 82)

Global $iInput = GUICtrlCreateInput($i_WindAngle, 75, 80, 80)

Global $iDirection = GUICtrlCreateLabel("", 170, 40, 90, 90, $SS_BITMAP)
Global $hDirection = GUICtrlGetHandle(-1)
GUICtrlSetCursor(-1, 0)

$hGfx_Direction = _GDIPlus_GraphicsCreateFromHWND($hDirection)
$hBmp_Direction = _GDIPlus_BitmapCreateFromGraphics(90, 90, $hGfx_Direction)
$hGfx_DirectionBitmap = _GDIPlus_ImageGetGraphicsContext($hBmp_Direction)

_GDIPlus_MatrixTranslate($hMatrix, 45, 45)
_GDIPlus_MatrixRotate($hMatrix, $i_WindAngle)

ChangeDirection(1)

GUIRegisterMsg($WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC")
GUISetState()

Local $iTimeMsg

While $iTimeMsg <> $GUI_EVENT_CLOSE
$iTimeMsg = GUIGetMsg()

Switch $iTimeMsg

Case $iDirection
GUICtrlSetState($iDirection, $GUI_DISABLE)
;Change the Pointing Arrow
While _IsPressed("01")
Sleep(10)
WEnd
ChangeDirection()

GUICtrlSetState($iDirection, $GUI_ENABLE)
EndSwitch

WEnd
;...-------===============================================

Exit

Func ChangeDirection($iDraw = 0)
;If draw is required return immediately
If $iDraw Then
_GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix)
_GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen)
_WinAPI_RedrawWindow($hDirection)
Return 1
EndIf

;Trap the Mouse to the ClientWin
Local $tPoint = DllStructCreate($tagPoint)
DllStructSetData($tPoint, 1, 0)
DllStructSetData($tPoint, 2, 0)
_WinAPI_ClientToScreen($hGUI, $tPoint)

_MouseTrap( DllStructGetData($tPoint,1), DllStructGetData($tPoint,2), DllStructGetData($tPoint,1) + _WinAPI_GetClientWidth($hGUI), DllStructGetData($tPoint,2) + _WinAPI_GetClientHeight($hGUI))

Local $nAngle = 0, $aDirectionPos = ControlGetPos($hGUI, '', $iDirection)
Do
;Clear the Bimap
_GDIPlus_GraphicsClear($hGfx_DirectionBitmap, 0xFFF0F0F0)

;Get the Angle suspended with the Mouse
$nAngle = Radian2Degree(ATan(Abs(MouseGetPos(1) - $aDirectionPos[1]) / Abs(MouseGetPos(0) - ($aDirectionPos[0] + $aDirectionPos[2] / 2))))
_GDIPlus_MatrixRotate($hMatrix, $nAngle) ;Rotate it
_GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix) ;Show changes in the Graphics
_GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen) ;Draw the Arrow
_WinAPI_RedrawWindow($hDirection) ;Show the changes in the Control

;Change the Angle in the Input
GUICtrlSetData($iInput, Round($nAngle, 2))

;Matrix Reset Angles
_GDIPlus_MatrixRotate($hMatrix, -$nAngle)

;For Degugging purposes only
ToolTip($nAngle)
Until _IsPressed("01") ;Exit when clicked again

ToolTip("")
_MouseTrap()
EndFunc ;==>ChangeDirection

Func Degree2Radian($iDegree)
Return ACos(-1) * $iDegree / 180
EndFunc ;==>Degree2Radian

Func Radian2Degree($iRadian)
Return 180 * $iRadian / ACos(-1)
EndFunc ;==>Radian2Degree

Func WM_CTLCOLORSTATIC($hWnd, $iMsg, $wParam, $lParam)
If $hDirection = $lParam Then
_GDIPlus_GraphicsDrawImage($hGfx_Direction, $hBmp_Direction, 0, 0)
Return _WinAPI_GetStockObject($HOLLOW_BRUSH) ;Msg Handled
EndIf
EndFunc ;==>WM_CTLCOLORSTATIC

Func Dispose()
GUIDelete($hGUI)

;Memory Release
_GDIPlus_PenDispose($hPen)
_GDIPlus_ArrowCapDispose($hArrowCap)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_GraphicsDispose($hGfx_DirectionBitmap)
_GDIPlus_ImageDispose($hBmp_Direction)
_GDIPlus_GraphicsDispose($hGfx_Direction)
_GDIPlus_Shutdown()
EndFunc ;==>Dispose
The Problem is
  • The Angle detected seems to be incorrect
  • I don't find a way to receive angles beyond 90 degrees.
There should be a way I'm not aware of, please guide me.

Thanks for you help and time. :)

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Posted (edited)

Hi,

Here you go :

#include-once
#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Misc.au3>

_GDIPlus_Startup()
Opt("MouseCoordMode", 2)

;User Values
Global $i_WindAngle = -60 ;Time Unit is Milli-Secs. Angle in Degrees
Global $hGfx_Direction, $hMatrix = _GDIPlus_MatrixCreate() ;The Graphics where Animation and Direction Change will occur
Global $hGfx_DirectionBitmap, $hBmp_Direction;The Bitmap and Bitmap Graphic object of the Direction control.
;...-------===============================================

OnAutoItExitRegister("Dispose")

;Create Pen for drawing direction
Global $hPen = _GDIPlus_PenCreate(0xFF00FFAB)
Global $hArrowCap = _GDIPlus_ArrowCapCreate(5, 3)
_GDIPlus_PenSetCustomEndCap($hPen, $hArrowCap)
;...-------===============================================

;Create the GUI for Animation.
Global $hGUI = GUICreate("GDI+ Test", 300, 150)

GUICtrlCreateLabel("WindAngle:", 10, 82)

Global $iInput = GUICtrlCreateInput($i_WindAngle, 75, 80, 80)

Global $iDirection = GUICtrlCreateLabel("", 170, 40, 90, 90, $SS_BITMAP)
Global $hDirection = GUICtrlGetHandle(-1)
GUICtrlSetCursor(-1, 0)

$hGfx_Direction = _GDIPlus_GraphicsCreateFromHWND($hDirection)
$hBmp_Direction = _GDIPlus_BitmapCreateFromGraphics(90, 90, $hGfx_Direction)
$hGfx_DirectionBitmap = _GDIPlus_ImageGetGraphicsContext($hBmp_Direction)

_GDIPlus_MatrixTranslate($hMatrix, 45, 45)
_GDIPlus_MatrixRotate($hMatrix, $i_WindAngle)

ChangeDirection(1)

GUIRegisterMsg($WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC")
GUISetState()

Local $iTimeMsg

While $iTimeMsg <> $GUI_EVENT_CLOSE
    $iTimeMsg = GUIGetMsg()

    Switch $iTimeMsg

        Case $iDirection
            GUICtrlSetState($iDirection, $GUI_DISABLE)
            ;Change the Pointing Arrow
            While _IsPressed("01")
                Sleep(10)
            WEnd
            ChangeDirection()

            GUICtrlSetState($iDirection, $GUI_ENABLE)
    EndSwitch

WEnd
;...-------===============================================

Exit

Func ChangeDirection($iDraw = 0)
    ;If draw is required return immediately
    If $iDraw Then
        _GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix)
        _GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen)
        _WinAPI_RedrawWindow($hDirection)
        Return 1
    EndIf

    ;Trap the Mouse to the ClientWin
    Local $tPoint = DllStructCreate($tagPoint)
    DllStructSetData($tPoint, 1, 0)
    DllStructSetData($tPoint, 2, 0)
    _WinAPI_ClientToScreen($hGUI, $tPoint)

    _MouseTrap(DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2), DllStructGetData($tPoint, 1) + _WinAPI_GetClientWidth($hGUI), DllStructGetData($tPoint, 2) + _WinAPI_GetClientHeight($hGUI))

    Local $nAngle = 0, $aCenter[2] = [215, 85]
    Do
        ;Clear the Bimap
        _GDIPlus_GraphicsClear($hGfx_DirectionBitmap, 0xFFF0F0F0)

        ;Get the Angle suspended with the Mouse
        $nAngle = Radian2Degree(atan2(MouseGetPos(1) - $aCenter[1], MouseGetPos(0) - $aCenter[0])) - $i_WindAngle

        _GDIPlus_MatrixRotate($hMatrix, $nAngle) ;Rotate it
        _GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix) ;Show changes in the Graphics
        _GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen) ;Draw the Arrow
        _WinAPI_RedrawWindow($hDirection) ;Show the changes in the Control

        ;Change the Angle in the Input
        GUICtrlSetData($iInput, Round($nAngle, 2))

        ;Matrix Reset Angles
        _GDIPlus_MatrixRotate($hMatrix, -$nAngle)

        ;For Degugging purposes only
        ToolTip($nAngle)
    Until _IsPressed("01") ;Exit when clicked again

    ToolTip("")
    _MouseTrap()
EndFunc   ;==>ChangeDirection

Func atan2($y, $x)
    Local $absx = 0, $absy = 0, $val = 0
    Local Const $M_PI = 3.14159265359, $M_PI_2 = $M_PI / 2

    If ($x = 0 And $y = 0) Then
        Return 0
    EndIf
    $absy = Abs($y)
    $absx = Abs($x)
    If ($absy - $absx = $absy) Then
        ;x negligible compared to y
        If $y < 0 Then
            Return -$M_PI_2
        Else
            Return $M_PI_2
        EndIf
    EndIf
    If ($absx - $absy = $absx) Then
        ;y negligible compared to x
        $val = 0
    Else
        $val = ATan($y / $x)
    EndIf
    If ($x > 0) Then
        ;first or fourth quadrant; already correct
        Return $val
    EndIf
    If ($y < 0) Then
        ;third quadrant
        Return $val - $M_PI
    EndIf
    Return $val + $M_PI
EndFunc   ;==>atan2

Func Degree2Radian($iDegree)
    Return ACos(-1) * $iDegree / 180
EndFunc   ;==>Degree2Radian

Func Radian2Degree($iRadian)
    Return 180 * $iRadian / ACos(-1)
EndFunc   ;==>Radian2Degree

Func WM_CTLCOLORSTATIC($hWnd, $iMsg, $wParam, $lParam)
    If $hDirection = $lParam Then
        _GDIPlus_GraphicsDrawImage($hGfx_Direction, $hBmp_Direction, 0, 0)
        Return _WinAPI_GetStockObject($HOLLOW_BRUSH) ;Msg Handled
    EndIf
EndFunc   ;==>WM_CTLCOLORSTATIC

Func Dispose()
    GUIDelete($hGUI)

    ;Memory Release
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_ArrowCapDispose($hArrowCap)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_GraphicsDispose($hGfx_DirectionBitmap)
    _GDIPlus_ImageDispose($hBmp_Direction)
    _GDIPlus_GraphicsDispose($hGfx_Direction)
    _GDIPlus_Shutdown()
EndFunc   ;==>Dispose

Br, FireFox.

Edited by FireFox
Posted

If you only want to rotate the arrow then you don't need to use the matrix rotate function. A simple sin() and cos() will do it:

#include-once
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Misc.au3>

_GDIPlus_Startup()
Opt("MouseCoordMode", 2)
Opt("GUIOnEventMode", 1)

;User Values
Global Const $Degree2Radian = ACos(-1) / 180
Global Const $fRadius = 45
Global $i_WindAngle = 0 ;Time Unit is Milli-Secs. Angle in Degrees
Global $hGfx_DirectionBitmap, $hBmp_Direction;The Bitmap and Bitmap Graphic object of the Direction control.
;...-------===============================================

OnAutoItExitRegister("Dispose")

;Create Pen for drawing direction
Global $hPen = _GDIPlus_PenCreate(0xFF00A06B)
Global $hArrowCap = _GDIPlus_ArrowCapCreate(5, 3)
_GDIPlus_PenSetCustomEndCap($hPen, $hArrowCap)
;...-------===============================================

;Create the GUI for Animation.
Global $hGUI = GUICreate("GDI+ Test", 300, 150)
GUICtrlCreateLabel("WindAngle:", 10, 82)
Global $iInput = GUICtrlCreateInput($i_WindAngle, 75, 80, 80)

Global $iDirection = GUICtrlCreateLabel("", 170, 40, 90, 90, $SS_BITMAP)
Global $hDirection = GUICtrlGetHandle(-1)
GUICtrlSetCursor(-1, 0)

Global $iX2 = 45, $iY2 = 45, $iLMB = -1
$hGfx_Direction = _GDIPlus_GraphicsCreateFromHWND($hDirection)
$hBmp_Direction = _GDIPlus_BitmapCreateFromGraphics(90, 90, $hGfx_Direction)
$hGfx_DirectionBitmap = _GDIPlus_ImageGetGraphicsContext($hBmp_Direction)
_GDIPlus_GraphicsSetSmoothingMode($hGfx_DirectionBitmap, 2)
GUISetState()

$hDLL = DllOpen("User32.dll")
GUISetOnEvent($GUI_EVENT_CLOSE, "Dispose")

While Sleep(50)
    _GDIPlus_GraphicsClear($hGfx_DirectionBitmap, 0xFFF0F0F0)
    _GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, $iX2, $iY2, $iX2 + Cos($i_WindAngle * $Degree2Radian) * $fRadius, $iY2 + Sin($i_WindAngle * $Degree2Radian) * $fRadius, $hPen)
    _GDIPlus_GraphicsDrawImageRect($hGfx_Direction, $hBmp_Direction, 0, 0, 90, 90)
    $aMPos = GUIGetCursorInfo($hGUI)
    If $iLMB > 0 Then
        $i_WindAngle = Mod($aMPos[0], 360)
        GUICtrlSetData($iInput, $i_WindAngle)
    EndIf
    If _IsPressed("01", $hDLL) Then
        $iLMB *= -1
        While _IsPressed("01", $hDLL)
        WEnd
    EndIf
WEnd

Exit

Func Dispose()
    DllClose($hDLL)
    ;Memory Release
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_ArrowCapDispose($hArrowCap)
    _GDIPlus_GraphicsDispose($hGfx_DirectionBitmap)
    _GDIPlus_ImageDispose($hBmp_Direction)
    _GDIPlus_GraphicsDispose($hGfx_Direction)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
    Exit
EndFunc   ;==>Dispose

Br,

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

Thanks UEZ, new learning :)

This is the full script what I was trying for ie Projectile Motion

#cs Trajectory Motion
Started to 2D vectors : 29/03/2013
Trying to make a ball which could be manipulated by
|a user-defined force and angle (Wind)
|gravity
#ce

#include-once
#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <APIConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Misc.au3>

_GDIPlus_Startup()
Opt("MouseCoordMode", 2)

;User Values
Global $iBall_Diameter = 20, $iBall_ColorOutline = 0xFF00FF00, $iBall_ColorFill = 0x8000AA00
Global $iBall_X = 10, $iBall_Y = 300, $iWidth, $tAnim_Rect = DllStructCreate($tagRect), $iSleep = 2, $iColor_Bk = 0xBBAAAA
Global $i_WindVelocity = 9, $i_GravityAcceleration = 0.3, $i_WindAngle = -60 ;Time Unit is Milli-Secs. Angle in Degrees
Global $hGfx_GUIAnimation, $hGfx_Direction, $hMatrix = _GDIPlus_MatrixCreate() ;The Graphics where Animation and Direction Change will occur
Global $hGfx_DirectionBitmap, $hBmp_Direction;The Bitmap and Bitmap Graphic object of the Direction control.
Global $hBmp_GUIAnimation, $hGfx_GUIAnimationBitmap ;The Bitmap and Bitmap Graphic object of the Main GUI.
;...-------===============================================

OnAutoItExitRegister("Dispose")

;Create the Ball Bitmap
Global $hBitmap_Ball = _GDIPlus_BitmapCreateFromScan0($iBall_Diameter, $iBall_Diameter)
Global $hgFx_Ball = _GDIPlus_ImageGetGraphicsContext($hBitmap_Ball)
_GDIPlus_GraphicsSetSmoothingMode($hgFx_Ball, 1) ;Anti-Alias

;Create Pen and Brush for drawing direction and the Ball
Global $hPen = _GDIPlus_PenCreate($iBall_ColorOutline)
Global $hArrowCap = _GDIPlus_ArrowCapCreate(5, 3)
_GDIPlus_PenSetCustomEndCap($hPen, $hArrowCap)

Global $hBrush = _GDIPlus_BrushCreateSolid($iBall_ColorOutline)

;...-------===============================================


;Create the GUI for Animation.
Global $hGUI = GUICreate("GDI+ Projectile Motion Without Angles - Coded PXL", 600, 650)

GUISetFont(11, 450, 0, "Times New Roman")
GUICtrlCreateGroup("Controls", 5, 480, 590, 160)

;Labels
GUICtrlCreateLabel("X:", 10, 502)
GUICtrlCreateLabel("Y:", 95, 502)
GUICtrlCreateLabel("Wind:", 180, 502)
GUICtrlCreateLabel("Gravity:", 290, 502)
GUICtrlCreateLabel("Sleep:", 409, 502)
GUICtrlCreateLabel("BkColor:", 10, 542)
GUICtrlCreateLabel("WindAngle:", 10, 582)

;Inputs
Global $iInput_Start = _
GUICtrlCreateInput($iBall_X, 25, 500, 50)
GUICtrlCreateInput($iBall_Y, 110, 500, 50)
GUICtrlCreateInput($i_WindVelocity, 215, 500, 50)
GUICtrlCreateInput($i_GravityAcceleration, 339, 500, 50)
GUICtrlCreateInput($iSleep, 449, 500, 50)
GUICtrlCreateInput($iColor_Bk, 65, 540, 80)
GUICtrlCreateInput($i_WindAngle, 75, 580, 80)

Local $iBtn_Reset = GUICtrlCreateButton("Reset", 280, 600, 90)
Local $iBtn_Animate = GUICtrlCreateButton("Animate", 480, 600, 90)
Local $iBtn_Draw = GUICtrlCreateButton("Draw", 380, 600, 90)

Global $iDirection = GUICtrlCreateLabel("", 170, 540, 90, 90, $SS_BITMAP)
Global $hDirection = GUICtrlGetHandle(-1)
GUICtrlSetCursor(-1, 0)

$hGfx_Direction = _GDIPlus_GraphicsCreateFromHWND($hDirection)
$hBmp_Direction = _GDIPlus_BitmapCreateFromGraphics(90, 90, $hGfx_Direction)
$hGfx_DirectionBitmap = _GDIPlus_ImageGetGraphicsContext($hBmp_Direction)

_GDIPlus_GraphicsSetSmoothingMode($hGfx_DirectionBitmap, 2) ;Anti-Alias
_GDIPlus_GraphicsSetSmoothingMode($hGfx_Direction, 1) ;Anti-Alias
_GDIPlus_MatrixTranslate($hMatrix, 45, 45)

ChangeDirection($i_WindAngle)
AnimationSetup()
Animate(1)

GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()

Local $iTimeMsg

While $iTimeMsg <> $GUI_EVENT_CLOSE
$iTimeMsg = GUIGetMsg()

Switch $iTimeMsg

Case $iBtn_Reset
;Reset to Default
Reset()

Case $iBtn_Animate, $iBtn_Draw
;Start the Animation or Draw the Ball
Animate($iTimeMsg - $iBtn_Animate)

Case $iDirection
GUICtrlSetState($iDirection, $GUI_DISABLE)
;Change the Pointing Arrow
While _IsPressed("01")
Sleep(10)
WEnd
ChangeDirection()

GUICtrlSetState($iDirection, $GUI_ENABLE)
EndSwitch

WEnd
;...-------===============================================

Exit


Func Animate($fStart = 0) ;If $fStart is 1, the ball is only drawn

;Set the Velocity to the Value of the Input
SetValues()

If $i_WindVelocity = 0 And $i_GravityAcceleration = 0 Then Return -1

ReDrawBall()

_GDIPlus_GraphicsClear($hGfx_GUIAnimationBitmap, 0xFF000000 + $iColor_Bk) ;Remove previous contents
;Draw the Ball

If $fStart Then
_GDIPlus_GraphicsDrawImage($hGfx_GUIAnimationBitmap, $hBitmap_Ball, $iBall_X, $iBall_Y)
Return _WinAPI_RedrawWindow($hGUI, $tAnim_Rect, 0, $RDW_INTERNALPAINT)
EndIf

Local $tPoint = DllStructCreate($tagPoint)
DllStructSetData($tPoint, 1, $iBall_X)
DllStructSetData($tPoint, 2, $iBall_Y)
;Lets start the Projectile motion

Local $iBall_X_New = $iBall_X, $iBall_Y_New = $iBall_Y, $iTime = 1
;Velocity/Acceleration
Do
;New Coords
$iBall_X_New = $iBall_X + $i_WindVelocity * $iTime * Cos(Degree2Radian($i_WindAngle)) ;Constant Velocity
$iBall_Y_New = $iBall_Y + $i_WindVelocity * $iTime * Sin(Degree2Radian($i_WindAngle)) + $i_GravityAcceleration * $iTime ^ 2 / 2 ;Acceleration
DllStructSetData($tPoint, 1, $iBall_X_New)
DllStructSetData($tPoint, 2, _Iif($iBall_Y_New <= 0, 0, $iBall_Y_New)) ;Cancel out if less than zero so that gravity could accelerate it down.
$iTime += 1
;Draw
_GDIPlus_GraphicsDrawImage($hGfx_GUIAnimationBitmap, $hBitmap_Ball, $iBall_X_New, $iBall_Y_New)
;Reflect the Changes
_WinAPI_RedrawWindow($hGUI, $tAnim_Rect, 0, $RDW_INTERNALPAINT)
;Speed
Sleep($iSleep)
;Erase
_GDIPlus_GraphicsClear($hGfx_GUIAnimationBitmap, 0xFF000000 + $iColor_Bk)

Until _WinAPI_PtInRect($tAnim_Rect, $tPoint) = 0
;Erase The Ball
_GDIPlus_GraphicsClear($hGfx_GUIAnimationBitmap, 0xFF000000 + $iColor_Bk)
;Change The GUI
_WinAPI_RedrawWindow($hGUI, $tAnim_Rect, 0, $RDW_INTERNALPAINT)

Return 1
EndFunc   ;==>Animate

Func Degree2Radian($iDegree)
Return ACos(-1) * $iDegree / 180
EndFunc   ;==>Degree2Radian

Func Radian2Degree($iRadian)
Return 180 * $iRadian / ACos(-1)
EndFunc   ;==>Radian2Degree

Func WM_PAINT($hWnd, $iMsg, $wParam, $lParam)
_GDIPlus_GraphicsDrawImage($hGfx_GUIAnimation, $hBmp_GUIAnimation, 0, 0)
EndFunc   ;==>WM_PAINT

Func WM_CTLCOLORSTATIC($hWnd, $iMsg, $wParam, $lParam)
If $hDirection = $lParam Then
_GDIPlus_GraphicsDrawImage($hGfx_Direction, $hBmp_Direction, 0, 0)
Return _WinAPI_GetStockObject($HOLLOW_BRUSH) ;Msg Handled
EndIf
EndFunc   ;==>WM_CTLCOLORSTATIC

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
Static $iFocus = False
If GUICtrlGetHandle($iInput_Start + 6) = $lParam Then
Switch _WinAPI_HiWord($wParam)
Case $EN_CHANGE
If $iFocus Then ChangeDirection(GUICtrlRead($iInput_Start + 6))
Case $EN_SETFOCUS
$iFocus = True
Case $EN_KILLFOCUS
$iFocus = False
EndSwitch
EndIf
EndFunc   ;==>WM_COMMAND

Func ChangeDirection($iAngle = 0)
;If draw is required return immediately
If $iAngle Then

_GDIPlus_GraphicsClear($hGfx_DirectionBitmap, 0xFFF0F0F0)

_GDIPlus_MatrixRotate($hMatrix, $iAngle)
_GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix)

_GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen)

_WinAPI_RedrawWindow($hDirection)
_GDIPlus_MatrixRotate($hMatrix, -$iAngle)

Return 1
EndIf

Local $nAngle = 0, $aDirectionPos = ControlGetPos($hGUI, '', $iDirection)
Do
;Clear the Bimap
_GDIPlus_GraphicsClear($hGfx_DirectionBitmap, 0xFFF0F0F0)

;Get the Angle suspended with the Mouse
$nAngle = Radian2Degree(ATan_((MouseGetPos(1) - $aDirectionPos[1]), (MouseGetPos(0) - ($aDirectionPos[0] + $aDirectionPos[2] / 2))))
_GDIPlus_MatrixRotate($hMatrix, $nAngle) ;Rotate it
_GDIPlus_GraphicsSetTransform($hGfx_DirectionBitmap, $hMatrix) ;Show changes in the Graphics
_GDIPlus_GraphicsDrawLine($hGfx_DirectionBitmap, 0, 0, 45, 0, $hPen) ;Draw the Arrow
_WinAPI_RedrawWindow($hDirection) ;Show the changes in the Control

;Change the Angle in the Input
GUICtrlSetData($iInput_Start + 6, Round($nAngle, 2))

;Reset Angles
_GDIPlus_MatrixRotate($hMatrix, -$nAngle)

;For Degugging purposes only
ToolTip($nAngle)
Until _IsPressed("01") ;Exit when clicked again
ToolTip("")
EndFunc   ;==>ChangeDirection

Func ATan_($y, $x) ;Thanks to FireFox
Local $absx = Abs($x), $absy = Abs($y), $val = 0
Local Const $M_PI = ACos(-1)
If ($x = 0 And $y = 0) Then Return 0
If ($absy - $absx = $absy) Then
;x negligible compared to y
If $y < 0 Then
Return -$M_PI / 2
Else
Return $M_PI / 2
EndIf
EndIf
$val = _Iif($absx - $absy = $absx, 0, ATan($y / $x))
If ($x > 0) Then Return $val;first or fourth quadrant
If ($y < 0) Then Return $val - $M_PI ;third quadrant
Return $val + $M_PI
EndFunc   ;==>ATan_

Func AnimationSetup()
;Get the Rect allowed for Animation
$tWin_Rect = _WinAPI_GetClientRect($hGUI)
$tPoint = DllStructCreate($tagPoint)
DllStructSetData($tagPoint, 1, 0)
DllStructSetData($tagPoint, 2, 0)
_WinAPI_ClientToScreen($hGUI, $tPoint)

;Client Height Width in Screen Coords
$iWidth = DllStructGetData($tPoint, 1) + DllStructGetData($tWin_Rect, 3)
Local $iHeight = DllStructGetData($tPoint, 2) + DllStructGetData($tWin_Rect, 4)

;Exclude the Region under the Controls
$hRgn_Controls = _WinAPI_CreateRectRgn(DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2) + 479, $iWidth, $iHeight)
$hDc_Animate = _WinAPI_GetDCEx($hGUI, $hRgn_Controls, $DCX_EXCLUDERGN)

$hGfx_GUIAnimation = _GDIPlus_GraphicsCreateFromHDC($hDc_Animate)
$hBmp_GUIAnimation = _GDIPlus_BitmapCreateFromGraphics($iWidth, 479, $hGfx_GUIAnimation)
$hGfx_GUIAnimationBitmap = _GDIPlus_ImageGetGraphicsContext($hBmp_GUIAnimation)
_GDIPlus_GraphicsSetSmoothingMode($hGfx_GUIAnimationBitmap, 2)

DllStructSetData($tAnim_Rect, 1, 0)
DllStructSetData($tAnim_Rect, 2, 0)
DllStructSetData($tAnim_Rect, 3, $iWidth)
DllStructSetData($tAnim_Rect, 4, 479)

;Release Memory
$tWin_Rect = 0
$tPoint = 0
_WinAPI_ReleaseDC($hGUI, $hDc_Animate)
_WinAPI_DeleteObject($hRgn_Controls)
EndFunc   ;==>AnimationSetup

Func SetValues()
$iBall_X = Number(GUICtrlRead($iInput_Start))
$iBall_Y = Number(GUICtrlRead($iInput_Start + 1))
$i_WindVelocity = Number(GUICtrlRead($iInput_Start + 2))
$i_GravityAcceleration = Number(GUICtrlRead($iInput_Start + 3))
$iSleep = Number(GUICtrlRead($iInput_Start + 4))
$iColor_Bk = Number(GUICtrlRead($iInput_Start + 5))
$i_WindAngle = Number(GUICtrlRead($iInput_Start + 6))
EndFunc   ;==>SetValues

Func Reset()
GUICtrlSetData($iInput_Start, 10)
GUICtrlSetData($iInput_Start + 1, 300)
GUICtrlSetData($iInput_Start + 2, 9)
GUICtrlSetData($iInput_Start + 3, 0.3)
GUICtrlSetData($iInput_Start + 4, 2)
GUICtrlSetData($iInput_Start + 5, 0xBBAAAA)
GUICtrlSetData($iInput_Start + 6, -60)
ChangeDirection(-60)
EndFunc   ;==>Reset

Func Dispose()
GUIDelete($hGUI)
$tAnim_Rect = 0

;Memory Release
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GDIPlus_ArrowCapDispose($hArrowCap)
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_GraphicsDispose($hGfx_DirectionBitmap)
_GDIPlus_ImageDispose($hBmp_Direction)
_GDIPlus_GraphicsDispose($hGfx_Direction)
_GDIPlus_GraphicsDispose($hGfx_GUIAnimation)
_GDIPlus_GraphicsDispose($hGfx_GUIAnimationBitmap)
_GDIPlus_ImageDispose($hBmp_GUIAnimation)
_GDIPlus_GraphicsDispose($hgFx_Ball)
_GDIPlus_ImageDispose($hBitmap_Ball)
_GDIPlus_Shutdown()
EndFunc   ;==>Dispose

Func ReDrawBall()

;To draw the background of the Ball so that it looks transparent.
If $iColor_Bk < 0 Then $iColor_Bk = _WinAPI_GetSysColor($COLOR_MENU)
_GDIPlus_GraphicsClear($hgFx_Ball, 0xFF000000 + $iColor_Bk)

;Draw the Ball to the Image.
;~ _GDIPlus_GraphicsDrawEllipse($hgFx_Ball, 0, 0, $iBall_Diameter, $iBall_Diameter, $hPen)
_GDIPlus_GraphicsFillEllipse($hgFx_Ball, 0, 0, $iBall_Diameter, $iBall_Diameter, $hBrush)

EndFunc   ;==>ReDrawBall

;From GDIP library
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)

If @error Then Return SetError(@error, @extended, 0)
$GDIP_STATUS = $aResult[0]
Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

;From WINAPIEX library
Func _WinAPI_GetDCEx($hWnd, $hRgn, $iFlags)

Local $Ret = DllCall('user32.dll', 'hwnd', 'GetDCEx', 'hwnd', $hWnd, 'ptr', $hRgn, 'dword', $iFlags)

If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc   ;==>_WinAPI_GetDCEx
The script is implemented with Firefox's code, I would incorporate your(UEZ) code when I get clear with those functions.

Regards :)

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...