Jump to content

Some questions about a GDI+ program


gigi1
 Share

Recommended Posts

hi, this is my first big project with GDI+,

it tries to simulate gravity motion (this is the most difficult), but also uniformly accelerated motion and constant motion,

it also shows additional informations, and allow the user to pause, change simulation speed, and more features i'm constantly improving and adding.

well, here's the code

#include <GDIPlus.au3>
HotKeySet("{ESC}", "ExitProgram")
HotKeySet("{SPACE}", "TogglePause")
HotKeySet("{+}", "RaiseSpeed")
HotKeySet("{-}", "LowerSpeed")
Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", -1)
Global $PenAxes, $Pen, $Brush, $Graphics, $BitMap, $Buffer, $CapAxes, $CapNorm
Global $CircleDiameter = 15, $CircleRadius = $CircleDiameter/2
Global $x, $x0, $vx, $vx0, $ax
Global $y, $y0, $vy, $vy0, $ay
Global $MainGui, $msg, $Version = "version 0.2 (beta), December 2010"
Global $MenuFile, $MenuFileNew, $MenuFileExit, $MenuShow, $MenuShowAcceleration, $MenuShowSpeed, $MenuShowAxes, $MenuShowCenter, $MenuShowCorpse, $MenuShowInfo, $MenuShowDelete
Global $MenuMotion, $MenuModeGravity, $MenuModeConstant, $MenuModeAcceleration, $MenuHelp, $MenuHelpAbout
Global $ShowAcceleration=True, $ShowSpeed=True, $ShowAxes=True, $ShowCenter=True, $ShowCorpse=True, $ShowInfo=True, $ShowDelete=False
Global $ModeGravity=True, $ModeConstant=False, $ModeAcceleration=False
Global $HotKeysON = True, $Pause, $Timer, $SimulationSpeed, $Distance, $Angle, $aABS, $vABS
Global $GuiWidth = 800, $GuiHeight = 600
Global $Width=$GuiWidth-10, $HWidth = $Width/2  ;$Width=the drawing part width, $HWidth=half of this, $GuiWidth= the width of the GUI (which is a little larger due to borders)
Global $Height=$GuiHeight-50, $HHeight = $Height/2
Global $hFormat, $hFamily, $hFont, $tLayout, $aInfo[3]
$MainGui = GUICreate("GDI+", $GuiWidth, $GuiHeight, @DesktopWidth/2-$GuiWidth/2, @DesktopHeight/2-$GuiHeight/2, BitOR(0x00010000, 0x00020000, 0x00040000))
    GUISetBkColor(0x000000, $MainGui)
$MenuFile = GUICtrlCreateMenu("File")
    $MenuFileNew = GUICtrlCreateMenuItem("New", $MenuFile)
    $MenuFileExit = GUICtrlCreateMenuItem("Exit", $MenuFile)
$MenuShow = GUICtrlCreateMenu("Show")
    $MenuShowAcceleration = GUICtrlCreateMenuItem("Show acceleration vector", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowSpeed = GUICtrlCreateMenuItem("Show speed vector", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowAxes = GUICtrlCreateMenuItem("Show axes", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowCenter = GUICtrlCreateMenuItem("Show body at the center", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowCorpse = GUICtrlCreateMenuItem("Show moving body", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowInfo = GUICtrlCreateMenuItem("Show extra info", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowDelete = GUICtrlCreateMenuItem("Disable cancellation", $MenuShow)
$MenuMotion = GUICtrlCreateMenu("Type of motion")
    $MenuModeGravity = GUICtrlCreateMenuItem("Gravitational motion", $MenuMotion)
    GUICtrlSetState(-1, 1)
    $MenuModeConstant = GUICtrlCreateMenuItem("Uniform motion", $MenuMotion)
    $MenuModeAcceleration = GUICtrlCreateMenuItem("Uniformly accelerated motion", $MenuMotion)
$MenuHelp = GUICtrlCreateMenu("Help")
    $MenuHelpAbout= GUICtrlCreateMenuItem("About", $MenuHelp)

GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$Graphics = _GDIPlus_GraphicsCreateFromHWND($MainGui)
$BitMap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $Graphics)
$Buffer = _GDIPlus_ImageGetGraphicsContext($BitMap)
_GDIPlus_GraphicsClear($Buffer)
$PenAxes = _GDIPlus_PenCreate(0xFFFFFFFF, 1, 2)
$CapAxes = _GDIPlus_ArrowCapCreate(40, 40, False)
_GDIPlus_PenSetCustomEndCap($PenAxes, $CapAxes)
$Pen = _GDIPlus_PenCreate(0xFFFFFFFF, 1, 2)
$CapNorm = _GDIPlus_ArrowCapCreate(10, 10, False)
_GDIPlus_PenSetCustomEndCap($Pen, $CapNorm)
$Brush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
ResizedWindow()
;===============ENG: MOTION STARTING INSTRUCTIONS=============
;pixel coordinates in the Cartesian plane
;speed in pixel/hundredth of a second
;speed in pixel/hundredth of a second³
;===============ITA: ISTRUZIONI DI INIZIO MOTO================
;Coordinate in pixel nel piano cartesiano
;velocità in pixel/centesimo di secondo
;accelerazioni in pixel/centesimo di secondo³
$Pause=False
$SimulationSpeed=1
$x = 0      ;ITA: posizione di partenza, x e y
$y = +200   ;ENG: starting position x and y
$vx = 6 ;ITA: velocità di partenza, x e y
$vy = 0     ;ENG: starting speed x and y
$ay = 0     ;ITA: accelerazione di partenza (quasi ininfluente, eccetto per il moto accellerato)
$ax = 0     ;ENG: starting acceleration (almost irrilevant, exept for the accelerated motion)
;========================================================
$Timer=TimerInit()
AdlibRegister("Draw", 30)                   ;this makes the function "Draw" execute every 30ms
GUISetOnEvent(-3, "ExitProgram")
GUISetOnEvent(-5, "ResizedWindow")
GUISetOnEvent(-6, "ResizedWindow")
GUISetOnEvent(-12, "ResizedWindow")
Func ResizedWindow()
    Local $Size[4]
    TogglePause()
    $Size=WinGetPos($MainGui)
    $GuiWidth=$Size[2]
    $GuiHeight=$Size[3]
    $Width=$GuiWidth-20
    $Height=$GuiHeight-65
    $HWidth=$Width/2
    $HHeight=$Height/2
    _GDIPlus_BitmapDispose($Bitmap)
    _GDIPlus_GraphicsDispose($Graphics)
    _GDIPlus_GraphicsDispose($Buffer)
    $Graphics = _GDIPlus_GraphicsCreateFromHWND($MainGui)
    $BitMap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $Graphics)
    $Buffer = _GDIPlus_ImageGetGraphicsContext($BitMap)
    TogglePause()
EndFunc
GUICtrlSetOnEvent($MenuFileNew, "MenuFileNew")      ;calls to functions when GUI button are pressed
GUICtrlSetOnEvent($MenuFileExit, "ExitProgram")
GUICtrlSetOnEvent($MenuShowAcceleration, "MenuShowAcceleration")
GUICtrlSetOnEvent($MenuShowSpeed, "MenuShowSpeed")
GUICtrlSetOnEvent($MenuShowAxes, "MenuShowAxes")
GUICtrlSetOnEvent($MenuShowCenter, "MenuShowCenter")
GUICtrlSetOnEvent($MenuShowCorpse, "MenuShowCorpse")
GUICtrlSetOnEvent($MenuShowInfo, "MenuShowInfo")
GUICtrlSetOnEvent($MenuShowDelete, "MenuShowDelete")
GUICtrlSetOnEvent($MenuModeGravity, "MenuModeGravity")
GUICtrlSetOnEvent($MenuModeAcceleration, "MenuModeAcceleration")
GUICtrlSetOnEvent($MenuModeConstant, "MenuModeConstant")
GUICtrlSetOnEvent($MenuHelpAbout, "MenuHelpAbout")

While 1         ;this is the only infinite cycle left... GUI events are handled by GUICtrlSetOnEvent, drawing is called every 30ms
    If WinActive($MainGui)=0 And $HotKeysON=True Then           ;enable/disable hotkeys when window is/isnt active
        HotKeySet("{ESC}")
        HotKeySet("{SPACE}")
        HotKeySet("{+}")
        HotKeySet("{-}")
        $HotKeysON=False
    ElseIf WinActive($MainGui)=$MainGui And $HotKeysON=False Then
        HotKeySet("{ESC}", "exitprogram")
        HotKeySet("{SPACE}", "TogglePause")
        HotKeySet("{+}", "RaiseSpeed")
        HotKeySet("{-}", "LowerSpeed")
        $HotKeysON=True
    EndIf
WEnd
Func draw()
    If $ShowDelete=False Then   _GDIPlus_GraphicsClear($Buffer)         ;Begins drawing part
    If $ShowAxes=True Then DisegnaAssi()
    If $ShowInfo=True Then
        ScriviLettereInizializza(8)     ;"ScriviLettereInizializza" = "WriteLettersInitialize" in italian
        ScriviLettere($Buffer, "y acceleration= "&$ay, 5, 0, 300, 15, $Brush)       ;"ScriviLettere"="WriteLetters" in italian
        ScriviLettere($Buffer, "y speed= "&$vy, 5, 15, 300, 15, $Brush)
        ScriviLettere($Buffer, "y = "&$y, 5, 30, 300, 15, $Brush)
        ScriviLettere($Buffer, "x = "&$x, 5, $Height-45, 300, 15, $Brush)
        ScriviLettere($Buffer, "x speed= "&$vx, 5, $Height-30, 300, 15, $Brush)
        ScriviLettere($Buffer, "x acceleration= " &$ax, 5, $Height - 15, 300, 15, $Brush)
        ScriviLettere($Buffer, "Distance from origin = "&$Distance, $Width-215, 0, 205, 15, $Brush)
        ScriviLettere($Buffer, "Acceleration = "&$aABS, $Width-185, 15, 200, 15,$Brush)
        ScriviLettere($Buffer, "Speed = "&$vABS, $Width-155, 30, 160, 15, $Brush)
        ScriviLettere($Buffer, "Angle = "&$Angle, $Width-150, 45, 150, 15, $Brush)
        ScriviLettere($Buffer, $SimulationSpeed&"x", $Width-20, $Height-75, 20, 15, $Brush)
        ScriviLettere($Buffer, "FPS: "&1000/TimerDiff($Timer), $Width-67, $Height-60, 67, 15, $Brush)
        $Timer = TimerInit()
        ScriviLettere($Buffer, "Press ESC to exit", $Width-95, $Height-45, 90, 15, $Brush)
        ScriviLettere($Buffer, "Press SPACE to pause", $Width-123, $Height-30, 118, 15, $Brush)
        ScriviLettere($Buffer, "Press + or - to change simulation speed", $Width-205, $Height-15, 200, 15, $Brush)
        ScriviLettereChiudi()       ;"ScriviLettereChiudi"="WriteLettersClose" in italian
    EndIf
    If $Pause=True Then
        ScriviLettereInizializza(14)
        ScriviLettere($Buffer, "PAUSE", $HWidth-36, $Height*2/3, 100, 20, $Brush)
        ScriviLettereChiudi()
    EndIf
    If $ShowSpeed=True Then _GDIPlus_GraphicsDrawLine($Buffer, $HWidth+$x, $HHeight-$y, $HWidth+$x+$vx*10, $HHeight-$y-$vy*10, $Pen)    ;disegna velocità - draw speed vector
    If $ShowAcceleration=True Then _GDIPlus_GraphicsDrawLine($Buffer, $HWidth+$x, $HHeight-$y, $HWidth+$x+$ax*50, $HHeight-$y-$ay*50, $Pen) ;disegna accelerazione - draw acceleration vector
    If $ShowCorpse=True Then _GDIPlus_GraphicsFillEllipse($Buffer, $HWidth+$x-$CircleRadius, $HHeight-$y-$CircleRadius, $CircleDiameter, $CircleDiameter, $Brush) ;disegna cerchio in movimento - draw moving corpse
    If $ShowCenter=True Then _GDIPlus_GraphicsDraWEllipse($Buffer, $HWidth-25, $HHeight-25, 50, 50, $Pen) ;disegna cerchio al centro degli assi - draw corpse at the center
    _GDIPlus_GraphicsDrawImageRect($Graphics, $BitMap, 0, 0, $Width, $Height)           ;copy image to screen - end of drawing part

    If $Pause=False Then
        For $i=1 To $SimulationSpeed Step 1     ;more simulation speed means more cycles of calculations for every drawing
            $x0 = $x
            $y0 = $y
            $vx0 = $vx
            $vy0 = $vy
            If $ModeGravity=True Then           ;gravity mode calculations
                $x = $x0+$vx0+$ax/2
                $y = $y0+$vy0+$ay/2
                $vx = $x-$x0
                $vy = $y-$y0
                $vABS=Sqrt($vx^2+$vy^2)
                $Distance=Sqrt($x^2+$y^2)
                If $Distance < $CircleDiameter Then $Pause=True
                $aABS=(20000)/$Distance^2
                $Angle = ATan($y/$x)*57.2957795130823
                If $x<0 Then $Angle = $Angle+180
                If $x>0 And $y<0 Then $Angle = $Angle+360
                $ax=-$aABS*Cos($Angle/57.2957795130823)
                $ay=-$aABS*Sin($Angle/57.2957795130823)
            ElseIf $ModeConstant=True Then              ;constant motion calculations
                $ax = 0
                $ay = 0
                $aABS = 0
                If $x0+$vx < -$HWidth+$CircleRadius Or $x0+$vx > $HWidth-$CircleRadius Then $vx = -$vx
                If $y0+$vy < -$HHeight+$CircleRadius Or $y0+$vy > $HHeight-$CircleRadius Then $vy = -$vy
                $x = $x0+$vx
                $y = $y0+$vy
                If $x < -$HWidth Or $x > $HWidth Then $x = 0
                If $y < -$HHeight Or $y > $HHeight Then $y = 0
                $vABS=Sqrt($vx^2+$vy^2)
                $Distance=Sqrt($x^2+$y^2)
                $Angle = ATan($y/$x)*57.2957795130823
            ElseIf $ModeAcceleration=True Then          ;constant accellerated motion calculations
                $ax=Abs($ax)
                $ay=Abs($ay)
                If $x > 0 And $ax <> 0 Then $ax = -$ax
                If $y > 0 And $ay <> 0 Then $ay = -$ay
                $x = $x0+$vx0+$ax/2
                $y = $y0+$vy0+$ay/2
                $vx = $x-$x0
                $vy = $y-$y0
                $vABS=Sqrt($vx^2+$vy^2)
                $Distance=Sqrt($x^2+$y^2)
                $Angle = ATan($y/$x)*57.2957795130823
            EndIf
        Next
    EndIf
EndFunc
#region GUI Functions
Func MenuFileNew()
    $Pause = True
    $SimulationSpeed=1
    $x=0
    $y=200
    $vx=10
    $vy=0
    $ax=0
    $ay=0
EndFunc
Func MenuShowAcceleration()
    If BitAND(GUICtrlRead($MenuShowAcceleration), 1)=1 Then
        GUICtrlSetState($MenuShowAcceleration, 4)
        $ShowAcceleration = False
    Else
        GUICtrlSetState($MenuShowAcceleration, 1)
        $ShowAcceleration = True
    EndIf
EndFunc
Func MenuShowSpeed()
    If BitAND(GUICtrlRead($MenuShowSpeed), 1)=1 Then
        GUICtrlSetState($MenuShowSpeed, 4)
        $ShowSpeed = False
    Else
        GUICtrlSetState($MenuShowSpeed, 1)
        $ShowSpeed = True
    EndIf
EndFunc
Func MenuShowAxes()
    If BitAND(GUICtrlRead($MenuShowAxes), 1)=1 Then
        GUICtrlSetState($MenuShowAxes, 4)
        $ShowAxes = False
    Else
        GUICtrlSetState($MenuShowAxes, 1)
        $ShowAxes = True
    EndIf
EndFunc
Func MenuShowCenter()
    If BitAND(GUICtrlRead($MenuShowCenter), 1)=1 Then
        GUICtrlSetState($MenuShowCenter, 4)
        $ShowCenter = False
    Else
        GUICtrlSetState($MenuShowCenter, 1)
        $ShowCenter = True
    EndIf
EndFunc
Func MenuShowCorpse()
    If BitAND(GUICtrlRead($MenuShowCorpse), 1)=1 Then
        GUICtrlSetState($MenuShowCorpse, 4)
        $ShowCorpse = False
    Else
        GUICtrlSetState($MenuShowCorpse, 1)
        $ShowCorpse = True
    EndIf
EndFunc
Func MenuShowInfo()
    If BitAND(GUICtrlRead($MenuShowInfo), 1)=1 Then
        GUICtrlSetState($MenuShowInfo, 4)
        $ShowInfo = False
    Else
        GUICtrlSetState($MenuShowInfo, 1)
        $ShowInfo = True
    EndIf
EndFunc
Func MenuShowDelete()
    If BitAND(GUICtrlRead($MenuShowDelete), 1)=1 Then
        GUICtrlSetState($MenuShowDelete, 4)
        $ShowDelete = False
    Else
        GUICtrlSetState($MenuShowDelete, 1)
        $ShowDelete = True
    EndIf
EndFunc
Func MenuModeGravity()
    If BitAND(GUICtrlRead($MenuModeGravity), 4)=4 Then
        GUICtrlSetState($MenuModeGravity, 1)
        GUICtrlSetState($MenuModeConstant, 4)
        GUICtrlSetState($MenuModeAcceleration, 4)
        $ModeGravity = True
        $ModeConstant = False
        $ModeAcceleration = False
    EndIf
EndFunc
Func MenuModeAcceleration()
    If BitAND(GUICtrlRead($MenuModeAcceleration), 4)=4 Then
        GUICtrlSetState($MenuModeGravity, 4)
        GUICtrlSetState($MenuModeConstant, 4)
        GUICtrlSetState($MenuModeAcceleration, 1)
        $ModeAcceleration = True
        $ModeConstant = False
        $ModeGravity = False
    EndIf
EndFunc
Func MenuModeConstant()
    If BitAND(GUICtrlRead($MenuModeConstant), 4)=4 Then
        GUICtrlSetState($MenuModeGravity, 4)
        GUICtrlSetState($MenuModeConstant, 1)
        GUICtrlSetState($MenuModeAcceleration, 4)
        $ModeConstant = True
        $ModeAcceleration = False
        $ModeGravity = False
    EndIf
EndFunc
Func MenuHelpAbout()
    MsgBox(0, "GDI+", "Program by Giorgio, "&$Version)
EndFunc
#endregion

Func DisegnaAssi()
    _GDIPlus_GraphicsDrawLine($Buffer, 0, $HHeight, $Width,  $HHeight, $PenAxes)    ;asse x - x axis
    _GDIPlus_GraphicsDrawLine($Buffer, $HWidth, $Height, $HWidth, 0, $PenAxes)  ;asse y - y axis
    ScriviLettereInizializza(16, "Arial", 2)
    ScriviLettere($Buffer, "y", $Width/2 - 22, 40, 20, 30, $Brush)          ;writes "x" and "y"
    ScriviLettere($Buffer, "x", $Width-60, $Height/2+5, 15, 30, $Brush)
    ScriviLettereChiudi()
EndFunc


;=========ENG->Func "ScriviLettereInizializza" = "WriteLettersInitialize" in italian===============
;initializes a string writing
;[parameter1: Font size = 12]
;[parameter2: Font = "Arial"
;[parameter3: style = 0 {0 = Normal. 1 = Bold. 2 = Italic. 4 = Underline. 8 = Strikethrough}]
;=========ITA->Func ScriviLettereInizializza=======================================================
;[parametro1: dimensione carattere = 12]
;[parametro2: font = "Arial"]
;[parametro3: stile = 0 {0 = Normal. 1 = Bold. 2 = Italic. 4 = Underline. 8 = Strikethrough}]
Func ScriviLettereInizializza($nSize = 12, $hFontinput = "Arial", $iStyle = 0)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ($hFontinput)
    $hFont = _GDIPlus_FontCreate ($hFamily, $nSize, $iStyle)
EndFunc


;=========ENG->Func ScriviLettere [="WriteLetters" in italian]==============================
;parameter1: $Graphics
;parameter2: message to be written
;parameter3: point x of the structure containing the string
;parameter4: point y of the structure containing the string
;parameter5: width of the structure containing the string
;parameter6: height of the structure containing the string
;parameter7: $Brush
;=========ITA->Func ScriviLettere===========================================================
;parametro1: $Graphics
;parametro2: messaggio da scrivere
;parametro3: punto x della struttura che contiene la string
;parametro4: punto y della struttura che contiene la string
;parametro5: larghezza della struttura che contiene la string
;parametro6: altezza della struttura che contiene la string
;parametro7: $Brush
Func ScriviLettere($hGraphic, $sString, $nX, $nY, $nWidth, $nHeight, $hBrush)
    $tLayout = _GDIPlus_RectFCreate($nX, $nY, $nWidth, $nHeight)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
EndFunc
Func ScriviLettereChiudi()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
EndFunc

Func TogglePause()
    If $Pause = False Then
        $Pause = True
    Else
        $Pause= False
    EndIf
EndFunc

Func RaiseSpeed()
    $SimulationSpeed += 1
EndFunc

Func LowerSpeed()
    If $SimulationSpeed > 1 Then $SimulationSpeed -= 1
EndFunc

Func exitprogram()
    GUIDelete($MainGui)
    _GDIPlus_PenDispose($PenAxes)
    _GDIPlus_PenDispose($Pen)
    _GDIPlus_ArrowCapDispose($CapAxes)
    _GDIPlus_ArrowCapDispose($CapNorm)
    _GDIPlus_BrushDispose ($Brush)
    _GDIPlus_BitmapDispose($Bitmap)
    _GDIPlus_GraphicsDispose($Graphics)
    _GDIPlus_GraphicsDispose($Buffer)
    _GDIPlus_Shutdown()
    Exit
EndFunc

it was italian, i turned most of it in english, but sorry anyway for bad english.

Here's the questions:

-Why FPS are so low? I'm comparing with games that easily hit 60FPS or more. is it me or AutoIt limits?

-It notably go faster when "additional info" are disabled ("Show" menu). i guess it is because of less calculations to do... i tryed to change Sleep() duration in relation to FPS to compensate but i didn't succeed. anyway to fix this?

-this is a windowed release. i started with a fullscreen one that had show/hide (like axes, informations, vectors) functions activated with Checkboxes and Radio buttons, that worked fine. Now functions are activated by clicking on the menu, but there is a heavy delay between click and actual activation. anyway to fix that?

also, general opinions are welcome.

thanks!

edit: updated the script - added disabled hotkeys when window is not active, changed the 0x speed, added the $HWidth and $HHeight variables to reduce calculations

edit2: solved most problems - added resize support, improved general performances.

Edited by gigi1
Link to comment
Share on other sites

If you reduce speed such that the $simulationspeed reaches 0 then it seems to lock up with no way of resuming. Maybe this to fix...

nm (plus sign involves a shift key).

setting a speed other than 0x and hitting space resumed normal function.

Func LowerSpeed()
    If $SimulationSpeed > 1 Then $SimulationSpeed = $SimulationSpeed -1
EndFunc
Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

The main problem is the calculation! You need to try to optimize the math, e.g. not calculate constants every time.

I'm not so good in optimization (Spiff59 is much better :() but here my try:

#include <GDIPlus.au3>
HotKeySet("{esc}", "exitprogram")
HotKeySet("{space}", "TogglePause")
HotKeySet("{+}", "RaiseSpeed")
HotKeySet("{-}", "LowerSpeed")
Opt('MustDeclareVars', 1)
Global $PenAxes, $Pen, $Brush, $Graphics, $BitMap, $Buffer, $CapAxes, $CapNorm
Global $CircleDiameter = 15, $CircleRadius = $CircleDiameter/2
Global $x, $x0, $vx, $vx0, $ax
Global $y, $y0, $vy, $vy0, $ay
Global $MainGui, $msg, $Version = "version 0.2 (beta), December 2010"
Global $MenuFile, $MenuFileNew, $MenuFileExit, $MenuShow, $MenuShowAcceleration, $MenuShowSpeed, $MenuShowAxes, $MenuShowCenter, $MenuShowCorpse, $MenuShowInfo, $MenuShowDelete
Global $MenuMotion, $MenuModeGravity, $MenuModeConstant, $MenuModeAcceleration, $MenuHelp, $MenuHelpAbout
Global $ShowAcceleration=True, $ShowSpeed=True, $ShowAxes=True, $ShowCenter=True, $ShowCorpse=True, $ShowInfo=True, $ShowDelete=False
Global $ModeGravity=True, $ModeConstant=False, $ModeAcceleration=False
Global $Pause, $Timer, $SimulationSpeed, $Distance, $Angle, $aABS, $vABS
Global $Width = 1000
Global $Height = 700
Global $W2=$Width/2
Global $H2=$Height/2
Global $hFormat, $hFamily, $hFont, $tLayout, $aInfo[3]
$MainGui = GUICreate("GDI+", $Width, $Height)
    GUISetBkColor(0x000000, $MainGui)
$MenuFile = GUICtrlCreateMenu("File")
    $MenuFileNew = GUICtrlCreateMenuItem("New", $MenuFile)
    $MenuFileExit = GUICtrlCreateMenuItem("Exit", $MenuFile)
$MenuShow = GUICtrlCreateMenu("Show")
    $MenuShowAcceleration = GUICtrlCreateMenuItem("Show acceleration vector", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowSpeed = GUICtrlCreateMenuItem("Show speed vector", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowAxes = GUICtrlCreateMenuItem("Show axes", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowCenter = GUICtrlCreateMenuItem("Show body at the center", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowCorpse = GUICtrlCreateMenuItem("Show moving body", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowInfo = GUICtrlCreateMenuItem("Show extra info", $MenuShow)
    GUICtrlSetState(-1, 1)
    $MenuShowDelete = GUICtrlCreateMenuItem("Disable cancellation", $MenuShow)
$MenuMotion = GUICtrlCreateMenu("Type of motion")
    $MenuModeGravity = GUICtrlCreateMenuItem("Gravitational motion", $MenuMotion)
    GUICtrlSetState(-1, 1)
    $MenuModeConstant = GUICtrlCreateMenuItem("Uniform motion", $MenuMotion)
    $MenuModeAcceleration = GUICtrlCreateMenuItem("Uniformly accelerated motion", $MenuMotion)
$MenuHelp = GUICtrlCreateMenu("Help")
    $MenuHelpAbout= GUICtrlCreateMenuItem("About", $MenuHelp)


GUISetState(@SW_SHOW)


_GDIPlus_Startup()
$Graphics = _GDIPlus_GraphicsCreateFromHWND($MainGui)
$BitMap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $Graphics)
$Buffer = _GDIPlus_ImageGetGraphicsContext($BitMap)
_GDIPlus_GraphicsSetSmoothingMode($Buffer, 2)
_GDIPlus_GraphicsClear($Buffer)
$PenAxes = _GDIPlus_PenCreate(0xFFFFFFFF, 1, 2)
$CapAxes = _GDIPlus_ArrowCapCreate(40, 40, False)
_GDIPlus_PenSetCustomEndCap($PenAxes, $CapAxes)
$Pen = _GDIPlus_PenCreate(0xFFFFFFFF, 1, 2)
$CapNorm = _GDIPlus_ArrowCapCreate(10, 10, False)
_GDIPlus_PenSetCustomEndCap($Pen, $CapNorm)
$Brush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
;===============ENG: MOTION STARTING INSTRUCTIONS=============
;pixel coordinates in the Cartesian plane
;speed in pixel/hundredth of a second
;speed in pixel/hundredth of a second³
;===============ITA: ISTRUZIONI DI INIZIO MOTO================
;Coordinate in pixel nel piano cartesiano
;velocità in pixel/centesimo di secondo
;accelerazioni in pixel/centesimo di secondo³
$Pause=False
$SimulationSpeed=1
$x = 0      ;ITA: posizione di partenza, x e y
$y = +200   ;ENG: starting position x and y
$vx = 10    ;ITA: velocità di partenza, x e y
$vy = 0     ;ENG: starting speed x and y
$ay = 0     ;ITA: accelerazione di partenza (quasi ininfluente, eccetto per il moto accellerato)
$ax = 0     ;ENG: starting acceleration (almost irrilevant, exept for the accelerated motion)
;========================================================
$Timer=TimerInit()
AdlibRegister("Draw", 15)

While 1
    $msg = GUIGetMsg()
    Switch($msg)
        Case -3, $MenuFileExit ; -3 OR $MenuFileExit
            exitprogram()
        Case $MenuHelpAbout
            MsgBox(0, "GDI+", "Program by Giorgio, "&$Version)
        Case $MenuShowAcceleration
            If BitAND(GUICtrlRead($MenuShowAcceleration), 1) = 1 Then
                GUICtrlSetState($MenuShowAcceleration, 4)
                $ShowAcceleration = False
            Else
                GUICtrlSetState($MenuShowAcceleration, 1)
                $ShowAcceleration = True
            EndIf
        Case $MenuShowSpeed
            If BitAND(GUICtrlRead($MenuShowSpeed), 1)=1 Then
                GUICtrlSetState($MenuShowSpeed, 4)
                $ShowSpeed = False
            Else
                GUICtrlSetState($MenuShowSpeed, 1)
                $ShowSpeed = True
            EndIf
        Case $MenuShowAxes
            If BitAND(GUICtrlRead($MenuShowAxes), 1)=1 Then
                GUICtrlSetState($MenuShowAxes, 4)
                $ShowAxes = False
            Else
                GUICtrlSetState($MenuShowAxes, 1)
                $ShowAxes = True
            EndIf
        Case $MenuShowCenter
            If BitAND(GUICtrlRead($MenuShowCenter), 1)=1 Then
                GUICtrlSetState($MenuShowCenter, 4)
                $ShowCenter = False
            Else
                GUICtrlSetState($MenuShowCenter, 1)
                $ShowCenter = True
            EndIf
        Case $MenuShowCorpse
            If BitAND(GUICtrlRead($MenuShowCorpse), 1)=1 Then
                GUICtrlSetState($MenuShowCorpse, 4)
                $ShowCorpse = False
            Else
                GUICtrlSetState($MenuShowCorpse, 1)
                $ShowCorpse = True
            EndIf
        Case $MenuShowInfo
            If BitAND(GUICtrlRead($MenuShowInfo), 1)=1 Then
                GUICtrlSetState($MenuShowInfo, 4)
                $ShowInfo = False
            Else
                GUICtrlSetState($MenuShowInfo, 1)
                $ShowInfo = True
            EndIf
        Case $MenuShowDelete
            If BitAND(GUICtrlRead($MenuShowDelete), 1)=1 Then
                GUICtrlSetState($MenuShowDelete, 4)
                $ShowDelete = False
            Else
                GUICtrlSetState($MenuShowDelete, 1)
                $ShowDelete = True
            EndIf
        Case $MenuModeGravity
            If BitAND(GUICtrlRead($MenuModeGravity), 4)=4 Then
                GUICtrlSetState($MenuModeGravity, 1)
                GUICtrlSetState($MenuModeConstant, 4)
                GUICtrlSetState($MenuModeAcceleration, 4)
                $ModeGravity = True
                $ModeConstant = False
                $ModeAcceleration = False
            EndIf
        Case $MenuModeAcceleration
            If BitAND(GUICtrlRead($MenuModeAcceleration), 4)=4 Then
                GUICtrlSetState($MenuModeGravity, 4)
                GUICtrlSetState($MenuModeConstant, 4)
                GUICtrlSetState($MenuModeAcceleration, 1)
                $ModeAcceleration = True
                $ModeConstant = False
                $ModeGravity = False
            EndIf
        Case $MenuModeConstant
            If BitAND(GUICtrlRead($MenuModeConstant), 4)=4 Then
                GUICtrlSetState($MenuModeGravity, 4)
                GUICtrlSetState($MenuModeConstant, 1)
                GUICtrlSetState($MenuModeAcceleration, 4)
                $ModeConstant = True
                $ModeAcceleration = False
                $ModeGravity = False
            EndIf
        Case $MenuFileNew
            $Pause = True
            $SimulationSpeed=1
            $x=0
            $y=200
            $vx=10
            $vy=0
            $ax=0
            $ay=0
    EndSwitch

WEnd

Func Draw()
    If $ShowDelete=False Then   _GDIPlus_GraphicsClear($Buffer)         ;Begins drawing part
    If $ShowAxes=True Then DisegnaAssi()
    If $ShowInfo=True Then
        ScriviLettereInizializza(8)     ;"ScriviLettereInizializza" = "WriteLettersInitialize" in italian
        ScriviLettere($Buffer, "y acceleration= "&$ay, 5, 0, 300, 15, $Brush)       ;"ScriviLettere"="WriteLetters" in italian
        ScriviLettere($Buffer, "y speed= "&$vy, 5, 15, 300, 15, $Brush)
        ScriviLettere($Buffer, "y = "&$y, 5, 30, 300, 15, $Brush)
        ScriviLettere($Buffer, "x = "&$x, 5, $Height-65, 300, 15, $Brush)
        ScriviLettere($Buffer, "x speed= "&$vx, 5, $Height-50, 300, 15, $Brush)
        ScriviLettere($Buffer, "x acceleration= " &$ax, 5, $Height - 35, 300, 15, $Brush)
        ScriviLettere($Buffer, "Distance from origin = "&$Distance, $Width-215, 0, 205, 15, $Brush)
        ScriviLettere($Buffer, "Acceleration = "&$aABS, $Width-185, 15, 200, 15,$Brush)
        ScriviLettere($Buffer, "Speed = "&$vABS, $Width-155, 30, 160, 15, $Brush)
        ScriviLettere($Buffer, "Angle = "&$Angle, $Width-150, 45, 150, 15, $Brush)
        ScriviLettere($Buffer, $SimulationSpeed&"x", $Width-30, $Height-95, 35, 15, $Brush)
        ScriviLettere($Buffer, "FPS: "&1000/TimerDiff($Timer), $Width-77, $Height-80, 70, 15, $Brush)
        $Timer = TimerInit()
        ScriviLettere($Buffer, "Press ESC to exit", $Width-105, $Height-65, 130, 15, $Brush)
        ScriviLettere($Buffer, "Press SPACE to pause", $Width-130, $Height-50, 200, 15, $Brush)
        ScriviLettere($Buffer, "Press + or - to change simulation speed", $Width-213, $Height-35, 270, 15, $Brush)
        ScriviLettereChiudi()       ;"ScriviLettereChiudi"="WriteLettersClose" in italian
    EndIf
    If $ShowSpeed=True Then _GDIPlus_GraphicsDrawLine($Buffer, $W2+$x, $H2-$y, $W2+$x+$vx*10, $H2-$y-$vy*10, $Pen)    ;disegna velocità - draw speed vector
    If $ShowAcceleration=True Then _GDIPlus_GraphicsDrawLine($Buffer, $W2+$x, $H2-$y, $W2+$x+$ax*50, $H2-$y-$ay*50, $Pen) ;disegna accelerazione - draw acceleration vector
    If $ShowCorpse=True Then _GDIPlus_GraphicsFillEllipse($Buffer, $W2+$x-$CircleRadius, $H2-$y-$CircleRadius, $CircleDiameter, $CircleDiameter, $Brush) ;disegna cerchio in movimento - draw moving corpse
    If $ShowCenter=True Then _GDIPlus_GraphicsDraWEllipse($Buffer, $W2-25, $H2-25, 50, 50, $Pen) ;disegna cerchio al centro degli assi - draw corpse at the center
    _GDIPlus_GraphicsDrawImageRect($Graphics, $BitMap, 0, 0, $Width, $Height)           ;copy image to screen - end of drawing part
    If $Pause=False Then
        For $i=1 To $SimulationSpeed    ;more simulation speed means more cycles of calculations for every drawing
            $x0 = $x
            $y0 = $y
            $vx0 = $vx
            $vy0 = $vy
            If $ModeGravity=True Then           ;gravity mode calculations
                $x = $x0+$vx0+$ax/2
                $y = $y0+$vy0+$ay/2
                $vx = $x-$x0
                $vy = $y-$y0
                $vABS=Sqrt($vx*$vx+$vy*$vy)
                $Distance=Sqrt($x*$x+$y*$y)
                If $Distance < $CircleDiameter Then $Pause=True
                $aABS=(50000)/($Distance*$Distance)
                $Angle = ATan($y/$x)*57.2957795130823
                If $x<0 Then $Angle += 180
                If $x>0 And $y<0 Then $Angle += 360
                $ax=-$aABS*Cos($Angle/57.2957795130823)
                $ay=-$aABS*Sin($Angle/57.2957795130823)
            ElseIf $ModeConstant=True Then              ;constant motion calculations
                $ax = 0
                $ay = 0
                $aABS = 0
                If $x0+$vx < -$W2+$CircleRadius Or $x0+$vx > $W2-$CircleRadius Then $vx = -$vx
                If $y0+$vy < -$H2+$CircleRadius Or $y0+$vy > $H2-$CircleRadius Then $vy = -$vy
                $x = $x0+$vx
                $y = $y0+$vy
                If $x < -$W2 Or $x > $W2 Then $x = 0
                If $y < -$H2 Or $y > $H2 Then $y = 0
                $vABS=Sqrt($vx*$vx+$vy*$vy)
                $Distance=Sqrt($x*$x+$y*$y)
                $Angle = ATan($y/$x)*57.2957795130823
            ElseIf $ModeAcceleration=True Then          ;constant accellerated motion calculations
                $ax=Abs($ax)
                $ay=Abs($ay)
                If $x > 0 And $ax <> 0 Then $ax = -$ax
                If $y > 0 And $ay <> 0 Then $ay = -$ay
                $x = $x0+$vx0+$ax/2
                $y = $y0+$vy0+$ay/2
                $vx = $x-$x0
                $vy = $y-$y0
                $vABS=Sqrt($vx*$vx+$vy*$vy)
                $Distance=Sqrt($x*$x+$y*$y)
                $Angle = ATan($y/$x)*57.2957795130823
            EndIf
        Next
    EndIf
EndFunc

Func DisegnaAssi()
    _GDIPlus_GraphicsDrawLine($Buffer, 0, $H2, $Width,  $H2, $PenAxes)  ;asse x - x axis
    _GDIPlus_GraphicsDrawLine($Buffer, $W2, $Height, $W2, 0, $PenAxes)    ;asse y - y axis
    ScriviLettereInizializza(16, "Arial", 2)
    ScriviLettere($Buffer, "y", $W2 - 22, 40, 20, 30, $Brush)          ;writes "x" and "y"
    ScriviLettere($Buffer, "x", $Width-60, $H2+5, 15, 30, $Brush)
    ScriviLettereChiudi()
EndFunc


;=========ENG->Func "ScriviLettereInizializza" = "WriteLettersInitialize" in italian===============
;initializes a string writing
;[parameter1: Font size = 12]
;[parameter2: Font = "Arial"
;[parameter3: style = 0 {0 = Normal. 1 = Bold. 2 = Italic. 4 = Underline. 8 = Strikethrough}]
;=========ITA->Func ScriviLettereInizializza=======================================================
;[parametro1: dimensione carattere = 12]
;[parametro2: font = "Arial"]
;[parametro3: stile = 0 {0 = Normal. 1 = Bold. 2 = Italic. 4 = Underline. 8 = Strikethrough}]
Func ScriviLettereInizializza($nSize = 12, $hFontinput = "Arial", $iStyle = 0)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ($hFontinput)
    $hFont = _GDIPlus_FontCreate ($hFamily, $nSize, $iStyle)
EndFunc


;=========ENG->Func ScriviLettere [="WriteLetters" in italian]==============================
;parameter1: $Graphics
;parameter2: message to be written
;parameter3: point x of the structure containing the string
;parameter4: point y of the structure containing the string
;parameter5: width of the structure containing the string
;parameter6: height of the structure containing the string
;parameter7: $Brush
;=========ITA->Func ScriviLettere===========================================================
;parametro1: $Graphics
;parametro2: messaggio da scrivere
;parametro3: punto x della struttura che contiene la string
;parametro4: punto y della struttura che contiene la string
;parametro5: larghezza della struttura che contiene la string
;parametro6: altezza della struttura che contiene la string
;parametro7: $Brush
Func ScriviLettere($hGraphic, $sString, $nX, $nY, $nWidth, $nHeight, $hBrush)
    $tLayout = _GDIPlus_RectFCreate($nX, $nY, $nWidth, $nHeight)
;~  $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $tLayout, $hFormat, $hBrush)
EndFunc
Func ScriviLettereChiudi()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
EndFunc

Func TogglePause()
    If $Pause = False Then
        $Pause = True
    Else
        $Pause= False
    EndIf
EndFunc

Func exitprogram()
    GUIDelete($MainGui)
    _GDIPlus_PenDispose($PenAxes)
    _GDIPlus_PenDispose($Pen)
    _GDIPlus_ArrowCapDispose($CapAxes)
    _GDIPlus_ArrowCapDispose($CapNorm)
    _GDIPlus_BrushDispose ($Brush)
    _GDIPlus_BitmapDispose($Bitmap)
    _GDIPlus_GraphicsDispose($Graphics)
    _GDIPlus_GraphicsDispose($Buffer)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Func RaiseSpeed()
    $SimulationSpeed += 1
EndFunc

Func LowerSpeed()
    If $SimulationSpeed > 0 Then $SimulationSpeed -= 1
EndFunc

Btw, nice physics :graduated:

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Thanks, it goes much faster!

i've didn't knew about the AdlibRegister() function, but there is a problem with that, it does not change things to visualize.

i mean, if i use AdlibRegister, and then toggle show axes, or vectors, or change motion type, it does not change. Maybe the AdlibRegister makes the Draw function not to accept external variables?

another question: if i round numbers every time, does it go faster because of less calculations, or slower because rounding is another calculation?

Link to comment
Share on other sites

I would say "much faster" is a little bit exaggerated :graduated:

With AdlibRegister("Draw", 40) it is working for me.

You can use GUICtrlSetOnEvent() function to control the menu items, too.

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

Link to comment
Share on other sites

thanks, i solved most of the problems.

the Adlibregister() stuff works now. it didn't because there was a sleep(10) inside the function called every 15 ms.

i switched every control in GUICtrlSetOnEvent(), and runs better now.

i also added the possibility to resize and maximize.

i will keep improving the script, thanks again for your help and remember that general feedbacks are always welcome!

(note: i updated the script in the first post)

Link to comment
Share on other sites

Add to line 103 (just after $Buffer = _GDIPlus_ImageGetGraphicsContext($BitMap)) the line _GDIPlus_GraphicsSetSmoothingMode($Buffer, 2) to get a smoother display.

Here another version how to you can resize a window when you are using GDI+

Simple GDI+ Clock:

;coded by UEZ 2011 build 2011-04-11
;~ #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_Obfuscated.au3"
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_UPX_Parameters=--brute --crp-ms=999999 --all-methods --all-filters

#include <Date.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#Include <Timers.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)

Global $hGUI, $hGraphics, $hBackbuffer, $hBitmap, $hPen1, $hPen2, $hPen3, $hPen4
Global $iX = 600, $iY = $iX
Global Const $p2_hm = $iX / 35
Global Const $p3_hm = $iX / 35
Global Const $p4_hm = $iX / 100
Global $newY = $iX, $newX = $iY
Global Const $minSize = $iX * 0.25
Global Const $maxSize = $iX * 1.5
Global Const $cX = $iX * 0.5, $cY = $iY * 0.5
Global Const $deg = ACos(-1) / 180
Global Const $radius = $iX * 0.85, $cR = $radius * 0.50
Global Const $cR1 = $cR * 0.90, $cR2 = $cR * 0.20
Global Const $cR3 = $cR * 0.80, $cR4 = $cR * 0.15
Global Const $cR5 = $cR * 0.50, $cR6 = $cR * 0.10
Global $sek = @SEC * 6 - 90
Global $min = @MIN * 6 + (@SEC / 10) - 90
Global $std = @HOUR * 30 + (@MIN / 2) - 90
Global Const $fs = $iY / 30, $tms = $iY / 20, $tmh = $iY * 0.725
Global $x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4, $x5, $x6, $y5, $y6, $tm
; Initialize GDI+
_GDIPlus_Startup()

Global $title = "GDI+ Simple Clock by UEZ 2011 / "
$hGUI = GUICreate($title, $iX, $iY, -1, -1, $WS_SIZEBOX + $WS_MINIMIZEBOX)
If @OSBuild < 7600 Then WinSetTrans($hGui,"", 0xFF) 
GUISetState()

$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

; Using antialiasing
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hBackbuffer, "int", 3)

; Create a Pen object
$hPen1 = _GDIPlus_PenCreate(0xFF800010, 4)
$hPen2 = _GDIPlus_PenCreate(0xA01010F0,  $p2_hm)
$hPen3 = _GDIPlus_PenCreate(0xA01010F0,  $p3_hm)
$hPen4 = _GDIPlus_PenCreate(0x9010D040,  $p4_hm)

Global Const  $LineCapRound = 2,  $LineCapTriangle = 3, $DashCapFlat = 0
Global $hPath, $hCustomLineCap, $avCaps
Global $avPoints[3][2] = [[2], [0, 0], [0, 0]]

$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddLines($hPath, $avPoints)
$hCustomLineCap = _GDIPlus_CustomLineCapCreate(0, $hPath)
_GDIPlus_CustomLineCapSetStrokeCaps($hCustomLineCap, $LineCapTriangle, $LineCapRound)
$avCaps = _GDIPlus_CustomLineCapGetStrokeCaps($hCustomLineCap)
_GDIPlus_PenSetLineCap($hPen2, $avCaps[0], $avCaps[1], $DashCapFlat)
_GDIPlus_PenSetLineCap($hPen3, $avCaps[0], $avCaps[1], $DashCapFlat)
_GDIPlus_PenSetLineCap($hPen4, $avCaps[0], $avCaps[1], $DashCapFlat)

Global $ws = WinGetPos($hGUI)
Global $ratio = $ws[3] / $ws[2]
Global $font = "Comic Sans MS"
If FileExists(@WindowsDir & "\fonts\showg.ttf") Then $font = "Showcard Gothic"

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

AdlibRegister("Ticker", 50)

GUIRegisterMsg($WM_SIZE, "WM_SIZE")
GUIRegisterMsg($WM_SIZING, "WM_SIZING")
GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")
GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")

Global $timer = 100,  $speak = False, $speak_init = True, $SpeakingClock = True
Global $oVoice = ObjCreate("SAPI.SpVoice")
If @error Then
    $speak_init = False
Else
    $oVoice.Rate = -3
EndIf

GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113
DllCall("User32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", $timer, "int", 0)

AdlibRegister( "SpeakingClock", 1000)

While Sleep(100000000)
WEnd

Func Draw()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xF0FFFFFF)

    _GDIPlus_GraphicsDrawLine($hBackbuffer, $cX - $cR, $cY, $cX - $cR + 35, $cY, $hPen1)
    _GDIPlus_GraphicsDrawLine($hBackbuffer, $cX + $cR, $cY, $cX + $cR - 35, $cY, $hPen1)
    _GDIPlus_GraphicsDrawLine($hBackbuffer, $cX, $cY - $cR, $cX, $cY - $cR + 35, $hPen1)
    _GDIPlus_GraphicsDrawLine($hBackbuffer, $cX, $cY + $cR, $cX, $cY + $cR - 35, $hPen1)
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, $cX - $cR, $cY - $cR, $radius, $radius, $hPen1)

    For $i = 0 To 11
        _GDIPlus_GraphicsDrawString($hBackbuffer, $i + 1, -$fs / 2 + $cX + Cos(-45 + $i * 29.7 * $deg) * $cR3, -$fs * 0.9 + $cY + Sin(-45 + $i * 29.7 * $deg) * $cR3, $font, $fs)
    Next
    If Int(StringLeft(_NowTime(4), 2) / 12) Then
        $tm = "PM"
    Else
        $tm = "AM"
    EndIf
    _GDIPlus_GraphicsDrawString($hBackbuffer, $tm,  -$tms * 1.1 + $cX, $tmh, $font, $tms)

    $x5 = $cX + Cos($std * $deg) * $cR5
    $y5 = $cY + Sin($std * $deg) * $cR5
    _GDIPlus_GraphicsDrawLine($hBackbuffer, $x5, $y5, $cX, $cY, $hPen2) ;hours

    $x3 = $cX + Cos($min * $deg) * $cR3
    $y3 = $cY + Sin($min * $deg) * $cR3
    _GDIPlus_GraphicsDrawLine($hBackbuffer, $x3, $y3, $cX, $cY, $hPen3) ;minutes

    $x1 = $cX + Cos($sek * $deg) * $cR1
    $y1 = $cY + Sin($sek * $deg) * $cR1
    $x2 = $cX + Cos(($sek + 180) * $deg) * $cR2
    $y2 = $cY + Sin(($sek + 180) * $deg) * $cR2
    _GDIPlus_GraphicsDrawLine($hBackbuffer, Floor($x1), Floor($y1), Floor($x2), Floor($y2), $hPen4) ;seconds

    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, $cX - 3, $cY - 3, 6, 6, $hPen1)

;~  _GDIPlus_GraphicsDrawString($hBackbuffer, @HOUR & ":" & @MIN & ":" & @SEC, 0, 0)
    WinSetTitle($hGui, "", $title & @HOUR & ":" & @MIN & ":" & @SEC)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iX, $iY)
    _WinAPI_RedrawWindow($hGUI)
EndFunc

Func SpeakingClock()
    If  $min = -90.00 And $speak_init And $SpeakingClock Then $oVoice.Speak("It is " & Mod(@HOUR, 12) & " " & $tm, 1)
EndFunc

Func WM_ERASEBKGND($hWnd, $Msg, $wParam, $lParam)
    Local $hGraphicsTemp = _GDIPlus_GraphicsCreateFromHDC($wParam)
    _GDIPlus_GraphicsDrawImageRect($hGraphicsTemp, $hBitmap, 0, 0, $iX, $iY)
    _GDIPlus_GraphicsDispose($hGraphicsTemp)
    Return True
EndFunc   ;==>_WM_ERASEBKGND

Func WM_SIZE($hWnd, $Msg, $wParam, $lParam)
    $iX = BitAND($lParam, 0x0000FFFF)
    $iY = BitShift(BitAND($lParam, 0xFFFF0000), 16)
;~  ConsoleWrite("x: " & $iX & ", y: " & $iY & @CRLF)
    _WinAPI_RedrawWindow($hGUI)
    Return "GUI_RUNDEFMSG"
EndFunc

Func WM_SIZING($hWnd, $iMsg, $wParam, $lParam)
    Local $sRect = DllStructCreate("Int[4]", $lParam)
    Local $left = DllStructGetData($sRect, 1, 1)
    Local $top = DllStructGetData($sRect, 1, 2)
    Local $right = DllStructGetData($sRect, 1, 3)
    Local $bottom = DllStructGetData($sRect, 1, 4)

    Switch $wParam ;drag side or corner
        Case 1, 2, 4, 7
            $newY = ($right - $left) * $ratio
            DllStructSetData($sRect, 1, DllStructGetData($sRect, 1, 2) + $newY, 4)
        Case Else
            $newX = ($bottom - $top) / $ratio
            DllStructSetData($sRect, 1, DllStructGetData($sRect, 1, 1) + $newX, 3)
    EndSwitch
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_SIZING

Func WM_GETMINMAXINFO($hWnd, $Msg, $wParam, $lParam)
    Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($minmaxinfo, 7, $minSize) ; min X
    DllStructSetData($minmaxinfo, 8, $minSize) ; min Y
    DllStructSetData($minmaxinfo, 9, $maxSize) ; max X
    DllStructSetData($minmaxinfo, 10, $maxSize) ; max Y
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_GETMINMAXINFO

Func Ticker()
    $sek = @SEC * 6 - 90
    $min = @MIN * 6 + (@SEC * 0.10) - 90
    $std = @HOUR * 30 + (@MIN * 0.50) - 90
EndFunc

Func _Exit()
    AdlibUnRegister("Ticker")
    AdlibUnRegister("SpeakingClock")
    $oVoice = 0
    GUIRegisterMsg($WM_TIMER, "")
    GUIRegisterMsg($WM_GETMINMAXINFO, "")
    GUIRegisterMsg($WM_SIZE, "")
    GUIRegisterMsg($WM_ERASEBKGND, "")
    GUIRegisterMsg($WM_SIZING, "")

    ; Clean up GDI+ resources
    _GDIPlus_CustomLineCapDispose($hCustomLineCap)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PenDispose($hPen1)
    _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_PenDispose($hPen4)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
    Exit
EndFunc

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreatePath", "int", $iFillMode, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_PathAddLines($hPath, $aPoints)
    Local $iI, $iCount, $pPoints, $tPoints, $aResult
    $iCount = $aPoints[0][0]
    $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, "uint", "GdipAddPathLine2", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_PathAddLines

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeletePath", "hwnd", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_PathDispose

Func _GDIPlus_CustomLineCapCreate($hPathFill, $hPathStroke, $iLineCap = 0, $nBaseInset = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateCustomLineCap", "hwnd", $hPathFill, "hwnd", $hPathStroke, "int", $iLineCap, "float", $nBaseInset, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[5]
EndFunc   ;==>_GDIPlus_CustomLineCapCreate

Func _GDIPlus_CustomLineCapSetStrokeCaps($hCustomLineCap, $iStartCap, $iEndCap)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetCustomLineCapStrokeCaps", "hwnd", $hCustomLineCap, "int", $iStartCap, "int", $iEndCap)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_CustomLineCapSetStrokeCaps

Func _GDIPlus_CustomLineCapGetStrokeCaps($hCustomLineCap)
    Local $aCaps[2], $aResult
    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetCustomLineCapStrokeCaps", "hwnd", $hCustomLineCap, "int*", 0, "int*", 0)
    If @error Then Return SetError(@error, @extended, -1)
    If $aResult[0] Then Return -1
    $aCaps[0] = $aResult[2]
    $aCaps[1] = $aResult[3]
    Return $aCaps
EndFunc   ;==>_GDIPlus_CustomLineCapGetStrokeCap

Func _GDIPlus_PenSetLineCap($hPen, $iStartCap, $iEndCap, $iDashCap)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetPenLineCap197819", "hwnd", $hPen, "int", $iStartCap, "int", $iEndCap, "int", $iDashCap)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_PenSetLineCap

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...