Jump to content

Recommended Posts

You have to redraw a portion or all of the GUI content over and over as WM_PAINT events are posted. That is how it works.

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
GUIRegisterMsg($WM_PAINT, "_WM_PAINT")

Local $hGUI = GUICreate("Test", 400, 300), $aPoints[8][2] = [[7],[50, 50],[100, 25],[200, 5],[250, 50],[300, 100],[350, 200],[250, 250]]
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Local $hBmp = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphics)
Local $hBmpGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp)

_GDIPlus_GraphicsFillClosedCurve($hBmpGraphics, $aPoints)

GUISetState()

While GUIGetMsg() <> -3
WEnd

_GDIPlus_GraphicsDispose($hBmpGraphics)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
    Sleep(20)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0)

    Return $GUI_RUNDEFMSG
EndFunc
Link to comment
Share on other sites

So, it basically takes a screenshot of the GUI, and then redraws it when necessary. That would be exactly what I was looking for, and it works great for my example.

Not quite, because...

Is there some way to tell when I should use _GDIPlus_BitmapCreateFromGraphics? A warning of some kind that will signify that the GUI is about to be painted over by another window. If not, I suppose I could just use it after each turn.

drawing to the Graphics object of a Bitmap compatible with the Graphics object $hGraphics, is not the same as drawing directly to the DC of the window. You'll get less flickering and increasing performance by using back-buffer image for painting shapes and stuff, all directly to the Bitmap's Graphics. Then, in one call you can draw the entire Bitmap content to the window Graphics object. You can use _GDIPlus_GraphicsClear to clear the content of the Bitmap's Graphics content.

Link to comment
Share on other sites

Okay, wow, I missed that you were drawing to the Bitmap and not the window. This sounds like a brilliant idea, but I need to work more on my project before I'll be fully able to grasp how awesome this really is. Thanks for the help, Authenticity.

That is how i was thinking as well, Authenticity helped me understand it in this post. the examples there might help you in undestanding it.
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.
Link to comment
Share on other sites

Is it not possible to clear the bitmap to be transparent? I tried this, but it doesn't seem to do anything at all.

_GDIPlus_GraphicsClear($hBmpGraphics1, 0x00000000)

What do you mean with transparency exactly?

Here an example for brush transparency:

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
GUIRegisterMsg($WM_PAINT, "_WM_PAINT")

Local $hGUI = GUICreate("Test", 400, 300), $aPoints[8][2] = [[7],[50, 50],[100, 25],[200, 5],[250, 50],[300, 100],[350, 200],[250, 250]]
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Local $hBmp = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphics)
Local $hBmpGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp)
Local $hBrush = _GDIPlus_BrushCreateSolid(0xA0222222)
Local $hBrush2 = _GDIPlus_BrushCreateSolid(0x8080A0F0)
_GDIPlus_GraphicsSetSmoothingMode($hBmpGraphics, 2)


GUISetState()
Local $i = -50
While GUIGetMsg() <> -3 * Sleep(30)
    _GDIPlus_GraphicsClear($hBmpGraphics, 0x40E0E0E0)
    _GDIPlus_GraphicsFillClosedCurve($hBmpGraphics, $aPoints, $hBrush)
    _GDIPlus_GraphicsFillEllipse($hBmpGraphics, $i, 150, 50, 50, $hBrush2)
    $i += 2
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0)
    If $i > 400 Then $i = -50
WEnd

_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BrushDispose($hBrush2)
_GDIPlus_GraphicsDispose($hBmpGraphics)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
;~  Sleep(20)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0)
    Return $GUI_RUNDEFMSG
EndFunc

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

What about Using the background colour of your gui in your _GDIPlus_GraphicsClear.

GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.
Link to comment
Share on other sites

I need the canvas I'm drawing on to be completely blank and transparent like the image between these dots.

.Posted Image.

Sorry, I cannot follow you. Blank and transparent - how should this be done?

I've written a GDI+ example where the letters rotate on a "transparent canvas"! Maybe this is what you searching for -> Rotating Letters Transparent

Look at the GDI+ examples in my signature for some simple examples. Maybe you can pickup some code...

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

This is because you draw both 800x600 bitmaps to the graphics. You don't need to send WM_PAINT to draw the new content. Either keep 1 image to draw the curve and balls on and then draw to the graphics, or 3 images. 1 for back-buffer and the other 2 for curve and balls. Also, don't clear the window Graphics object, rather the back-buffer.

Edit:

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#AutoIt3Wrapper_UseUpx=Y
#AutoIt3Wrapper_Compression=4
#Autoit3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/SO
#include <Array.au3>
#include <GDIPlus.au3>
#include <Memory.au3>

; Graphic binaries
Local $bBallB = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003249444154285363644005FFD1F8202E2316310690425C18453D3E853039B0066214C2350C45C5C47A92E8E0E3203662E0EA0098525CAEAF60215C0000000049454E44AE426082'
Local $bBallR = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003649444154285363644002FF191880081530323000111A0029C4855194E2530893036B2046215CC350544CAC2749093E0EA22206591100760BBA5107CF97330000000049454E44AE426082'

; Distance traveled
; g: the gravitational acceleration
; a: the angle at which the projectile is launched
; v: the velocity at which the projectile is launched
; y: the initial height of the projectile
; d: the total horizontal distance traveled by the projectile
Local $g = 10
Local $a = 60
Local $v = 75
Local $y = 0
$a = $a / 57.2957795130823 ; Convert angle from degrees to radians
Local $d = (($v * Cos($a)) / $g) * ($v * Sin($a) + Sqrt((($v * Sin($a)) ^ 2) + (2 * $g * $y)))

; Calculate the trajectory
Local $aPoints[1][2], $j = 1
For $i = 0 To $d
    $j += 1
    ReDim $aPoints[$j][2]
    $aPoints[$j - 1][0] = $i
    $aPoints[$j - 1][1] = 600 - ($y + ($i * Tan($a)) - ($g * ($i ^ 2)) / (2 * (($v * Cos($a)) ^ 2)))
Next
$aPoints[0][0] = UBound($aPoints) - 1

;_ArrayDisplay($aPoints)

; Create the GUI;
Local $hWnd = GUICreate("Trajectory Test", 800, 600)
GUISetBkColor(0x000000); Black background
GUISetState()

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hImage = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageFx = _GDIPlus_ImageGetGraphicsContext($hImage)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 1)
Local $hBallImg = _GDIPlus_BinaryToBitmap($bBallR)

GUIRegisterMsg(0x000F, "_WM_PAINT")

; Draw the Trajectory
_GDIPlus_GraphicsDrawCurve($hImageFx, $aPoints, $hPen)

; Draw a red ball following the trajectory
For $i = 1 To $aPoints[0][0]
    _GDIPlus_GraphicsClear($hImageFx)
    _GDIPlus_GraphicsDrawCurve($hImageFx, $aPoints, $hPen)
    _GDIPlus_GraphicsDrawImage($hImageFx, $hBallImg, $aPoints[$i][0] - 5, $aPoints[$i][1] - 5)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Sleep(10)
Next

Do
Until GUIGetMsg() = -3

_GDIPlus_BitmapDispose($hBallImg)
_GDIPlus_GraphicsDispose($hImageFx)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_PenDispose($hPen)
_GDIPlus_Shutdown()



Func _GDIPlus_BinaryToBitmap($Binary)
    Local $bPicData = Binary($Binary)
    Local $iPicLength = BinaryLen($bPicData)
    Local $tPicStruct = DllStructCreate("byte[" & $iPicLength & "]")
    DllStructSetData($tPicStruct, 1, $bPicData)
    Local $pPicMemory = DllStructGetPtr($tPicStruct)
    Local $hMemory = _MemGlobalAlloc($iPicLength, 2)
    Local $pMemory = _MemGlobalLock($hMemory)
    _MemMoveMemory($pPicMemory, $pMemory, $iPicLength)
    _MemGlobalUnlock($hMemory)
    Local $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hMemory, "long", 1, "Int*", 0)
    $pStream = $pStream[3]
    Local $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
    $pBitmap = $pBitmap[2]
    $tPicStruct = 0
    Return $pBitmap
EndFunc   ;==>_GDIPlus_BinaryToBitmap

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
    Sleep(20)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>_WM_PAINT
Edited by Authenticity
Link to comment
Share on other sites

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#AutoIt3Wrapper_UseUpx=Y
#AutoIt3Wrapper_Compression=4
#Autoit3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/SO
#include <Array.au3>
#include <GDIPlus.au3>
#include <Memory.au3>

; Graphic binaries
Local $bBallB = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003249444154285363644005FFD1F8202E2316310690425C18453D3E853039B0066214C2350C45C5C47A92E8E0E3203662E0EA0098525CAEAF60215C0000000049454E44AE426082'
Local $bBallR = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003649444154285363644002FF191880081530323000111A0029C4855194E2530893036B2046215CC350544CAC2749093E0EA22206591100760BBA5107CF97330000000049454E44AE426082'

; Distance traveled
; g: the gravitational acceleration
; a: the angle at which the projectile is launched
; v: the velocity at which the projectile is launched
; y: the initial height of the projectile
; d: the total horizontal distance traveled by the projectile
Local $g = 10
Local $a = 60
Local $v = 75
Local $y = 0
$a = $a / 57.2957795130823 ; Convert angle from degrees to radians
Local $d = (($v * Cos($a)) / $g) * ($v * Sin($a) + Sqrt((($v * Sin($a)) ^ 2) + (2 * $g * $y)))

; Calculate the trajectory
Local $aPoints[1][2], $j = 1
For $i = 0 To $d
    $j += 1
    ReDim $aPoints[$j][2]
    $aPoints[$j - 1][0] = $i
    $aPoints[$j - 1][1] = 600 - ($y + ($i * Tan($a)) - ($g * ($i ^ 2)) / (2 * (($v * Cos($a)) ^ 2)))
Next
$aPoints[0][0] = UBound($aPoints) - 1

;_ArrayDisplay($aPoints)

; Create the GUI;
Local $hWnd = GUICreate("Trajectory Test", 800, 600)
GUISetBkColor(0x000000); Black background
GUISetState()

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hImage = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageFx = _GDIPlus_ImageGetGraphicsContext($hImage)
Local $hImageCurve = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageCurveFx = _GDIPlus_ImageGetGraphicsContext($hImageCurve)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 1)
Local $hBallImg = _GDIPlus_BinaryToBitmap($bBallR)

GUIRegisterMsg(0x000F, "_WM_PAINT")

; Draw the Trajectory
_GDIPlus_GraphicsDrawCurve($hImageCurveFx, $aPoints, $hPen)
_GDIPlus_GraphicsDispose($hImageCurveFx)

; Draw a red ball following the trajectory
For $i = 1 To $aPoints[0][0]
    _GDIPlus_GraphicsClear($hImageFx)
    _GDIPlus_GraphicsDrawImage($hImageFx, $hImageCurve, 0, 0)
    _GDIPlus_GraphicsDrawImage($hImageFx, $hBallImg, $aPoints[$i][0] - 5, $aPoints[$i][1] - 5)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Sleep(10)
Next

Do
Until GUIGetMsg() = -3

_GDIPlus_PenDispose($hPen)
_GDIPlus_BitmapDispose($hBallImg)
_GDIPlus_BitmapDispose($hImageCurve)
_GDIPlus_GraphicsDispose($hImageFx)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()



Func _GDIPlus_BinaryToBitmap($Binary)
    Local $bPicData = Binary($Binary)
    Local $iPicLength = BinaryLen($bPicData)
    Local $tPicStruct = DllStructCreate("byte[" & $iPicLength & "]")
    DllStructSetData($tPicStruct, 1, $bPicData)
    Local $pPicMemory = DllStructGetPtr($tPicStruct)
    Local $hMemory = _MemGlobalAlloc($iPicLength, 2)
    Local $pMemory = _MemGlobalLock($hMemory)
    _MemMoveMemory($pPicMemory, $pMemory, $iPicLength)
    _MemGlobalUnlock($hMemory)
    Local $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hMemory, "long", 1, "Int*", 0)
    $pStream = $pStream[3]
    Local $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
    $pBitmap = $pBitmap[2]
    $tPicStruct = 0
    Return $pBitmap
EndFunc   ;==>_GDIPlus_BinaryToBitmap

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
    Sleep(20)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>_WM_PAINT

$hImageCurve represents the background image with complex structure so you keep it as an image. Of course, you won't draw over $hImageCurve.

Link to comment
Share on other sites

Why do you put a Sleep() in the WM_PAINT function? I can't tell that it's having any effect, and the help file says the function should return as fast as possible.

lol, because I bought this machine 14 years ago. If I'll remove the Sleep call, restoring the window will not paint the shape.

You don't have to return from the handler as fast as possible. The help file is correct; once in a handler function, your window cannot process messages sent via SendMessage API. If you don't mind that your window is not responding for the amount of time you spend in the handler, nothing is wrong then.

Link to comment
Share on other sites

One possibility:

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#AutoIt3Wrapper_UseUpx=Y
#AutoIt3Wrapper_Compression=4
#Autoit3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/SO
#include <Array.au3>
#include <GDIPlus.au3>
#include <Memory.au3>

; Distance traveled
; g: the gravitational acceleration
; a: the angle at which the projectile is launched
; v: the velocity at which the projectile is launched
; y: the initial height of the projectile
; d: the total horizontal distance traveled by the projectile
Local $g = 10
Local $a = 60
Local $v = 75
Local $y = 0
$a = $a / 57.2957795130823 ; Convert angle from degrees to radians
Local $d = (($v * Cos($a)) / $g) * ($v * Sin($a) + Sqrt((($v * Sin($a)) ^ 2) + (2 * $g * $y)))

; Calculate the trajectory
Local $aPoints[1][2], $j = 1
For $i = 0 To $d
    $j += 1
    ReDim $aPoints[$j][2]
    $aPoints[$j - 1][0] = $i
    $aPoints[$j - 1][1] = Round(600 - ($y + ($i * Tan($a)) - ($g * ($i ^ 2)) / (2 * (($v * Cos($a)) ^ 2))), 0)
Next
$aPoints[0][0] = UBound($aPoints) - 1

; Create the GUI
Local $hWnd = GUICreate("Trajectory Test", 800, 600)
GUISetBkColor(0x000000); Black background
GUICtrlCreateLabel("Label", 200, 100, 50, 20)
GUICtrlSetColor(-1, 0xFFFFFF)
GUICtrlCreateInput("Input", 200, 450, 50, 20, 0x01)
GUICtrlSetColor(-1, 0x000000)
GUICtrlCreateButton("Button", 200, 300, 50, 20)
GUICtrlSetColor(-1, 0x000000)

GUISetState()

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hImage = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageFx = _GDIPlus_ImageGetGraphicsContext($hImage)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 1)
Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
Local $hBrush_erase = _GDIPlus_BrushCreateSolid(0xFF000000)

GUIRegisterMsg(0x000F, "_WM_PAINT")

; Draw a red ball following the trajectory
For $i = 1 To $aPoints[0][0]
    _GDIPlus_GraphicsFillEllipse($hImageFx, $aPoints[$i][0] - 10, $aPoints[$i][1] - 10, 22, 22, $hBrush_erase)
    _GDIPlus_GraphicsDrawCurve($hImageFx, $aPoints, $hPen)
    _GDIPlus_GraphicsFillEllipse($hImageFx, $aPoints[$i][0] - 5, $aPoints[$i][1] - 5, 11, 11, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Sleep(10)
Next

Do
Until GUIGetMsg() = -3

_GDIPlus_BrushDispose($hBrush_erase)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hImageFx)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Return 'GUI_RUNDEFMSG'
EndFunc

This will work only for this particular values properly. The button, label and input box will be erased when the coordinates intersect it.

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

I didn't read your example UEZ. I'm just about to try it. It's possible to clip the region of the Graphics object:

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#AutoIt3Wrapper_UseUpx=Y
#AutoIt3Wrapper_Compression=4
#Autoit3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/SO
#include <Array.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Memory.au3>
Opt("GUIOnEventMode", 1)

; Graphic binaries
Local $bBallR = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003649444154285363644002FF191880081530323000111A0029C4855194E2530893036B2046215CC350544CAC2749093E0EA22206591100760BBA5107CF97330000000049454E44AE426082'

; Distance traveled
; g: the gravitational acceleration
; a: the angle at which the projectile is launched
; v: the velocity at which the projectile is launched
; y: the initial height of the projectile
; d: the total horizontal distance traveled by the projectile
Local $g = 10
Local $a = 60
Local $v = 75
Local $y = 0
$a = $a / 57.2957795130823 ; Convert angle from degrees to radians
Local $d = (($v * Cos($a)) / $g) * ($v * Sin($a) + Sqrt((($v * Sin($a)) ^ 2) + (2 * $g * $y)))

; Calculate the trajectory
Local $aPoints[1][2], $j = 1
For $i = 0 To $d
    $j += 1
    ReDim $aPoints[$j][2]
    $aPoints[$j - 1][0] = $i
    $aPoints[$j - 1][1] = 600 - ($y + ($i * Tan($a)) - ($g * ($i ^ 2)) / (2 * (($v * Cos($a)) ^ 2)))
Next
$aPoints[0][0] = UBound($aPoints) - 1

; Create the GUI
Local $hWnd = GUICreate("Trajectory Test", 800, 600)
GUISetBkColor(0x000000); Black background
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")

GUICtrlCreateLabel("Label", 200, 100, 50, 20)
GUICtrlSetColor(-1, 0xFFFFFF)
GUICtrlCreateInput("Input", 200, 450, 50, 20, 0x01)
GUICtrlSetColor(-1, 0x000000)
GUICtrlCreateButton("Button", 200, 300, 50, 20)
GUICtrlSetColor(-1, 0x000000)

GUISetState()

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hImage = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageFx = _GDIPlus_ImageGetGraphicsContext($hImage)
Local $hImageCurve = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageCurveFx = _GDIPlus_ImageGetGraphicsContext($hImageCurve)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 1)
Local $hBallImg = _GDIPlus_BinaryToBitmap($bBallR)

GUIRegisterMsg(0x000F, "_WM_PAINT")
_GDIPlus_GraphicsSetSmoothingMode($hImageCurveFx, 4)

; Draw the Trajectory
_GDIPlus_GraphicsDrawCurve($hImageCurveFx, $aPoints, $hPen)
_GDIPlus_GraphicsDispose($hImageCurveFx)

Local $hRegion = _GDIPlus_RegionCreateFromRect(_GDIPlus_RectFCreate(0, 0, 800, 600))
Local $hChild = _WinAPI_GetWindow($hWnd, $GW_CHILD)
Local $aRect

Do
    $aRect = ControlGetPos($hChild, "", 0)
    _GDIPlus_RegionCombineRect($hRegion, _GDIPlus_RectFCreate($aRect[0], $aRect[1], $aRect[2], $aRect[3]), 3)
    $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
Until Not $hChild

_GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion)
_GDIPlus_RegionDispose($hRegion)

; Draw a red ball following the trajectory
For $i = 1 To $aPoints[0][0]
    _GDIPlus_GraphicsClear($hImageFx)
    _GDIPlus_GraphicsDrawImage($hImageFx, $hImageCurve, 0, 0)
    _GDIPlus_GraphicsDrawImage($hImageFx, $hBallImg, $aPoints[$i][0] - 5, $aPoints[$i][1] - 5)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Sleep(10)
Next

While 1
    Sleep(20)
WEnd

Func _Quit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BitmapDispose($hBallImg)
    _GDIPlus_BitmapDispose($hImageCurve)
    _GDIPlus_GraphicsDispose($hImageFx)
    _GDIPlus_BitmapDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

Func _GDIPlus_BinaryToBitmap($Binary)
    Local $bPicData = Binary($Binary)
    Local $iPicLength = BinaryLen($bPicData)
    Local $tPicStruct = DllStructCreate("byte[" & $iPicLength & "]")
    DllStructSetData($tPicStruct, 1, $bPicData)
    Local $pPicMemory = DllStructGetPtr($tPicStruct)
    Local $hMemory = _MemGlobalAlloc($iPicLength, 2)
    Local $pMemory = _MemGlobalLock($hMemory)
    _MemMoveMemory($pPicMemory, $pMemory, $iPicLength)
    _MemGlobalUnlock($hMemory)
    Local $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hMemory, "long", 1, "Int*", 0)
    $pStream = $pStream[3]
    Local $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
    $pBitmap = $pBitmap[2]
    $tPicStruct = 0
    Return $pBitmap
EndFunc

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
    Sleep(20)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
    Return 'GUI_RUNDEFMSG'
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_GraphicsSetClipRegion
; Description ...: Updates the clipping region of a Graphics object to a region that is the combination of itself and the region
;                  +specified by a Region object
; Syntax.........: _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion[, $iCombineMode = 0])
; Parameters ....: $hGraphics - Pointer to a Graphics object
;                  $hRegion   - Pointer to a Region object to be combined with the clipping region of the Graphics object
;                  $iCombineMode - Regions combination mode:
;                  |0 - The existing region is replaced by the new region
;                  |1 - The existing region is replaced by the intersection of itself and the new region
;                  |2 - The existing region is replaced by the union of itself and the new region
;                  |3 - The existing region is replaced by the result of performing an XOR on the two regions
;                  |4 - The existing region is replaced by the portion of itself that is outside of the new region
;                  |5 - The existing region is replaced by the portion of the new region that is outside of the existing region
; Return values .: Success      - True
;                  Failure      - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion, $iCombineMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetClipRegion", "hwnd", $hGraphics, "hwnd", $hRegion, "int", $iCombineMode)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_GraphicsSetClipRegion

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionCreateFromRect
; Description ...: Creates a region that is defined by a rectangle
; Syntax.........: _GDIPlus_RegionCreateFromRect($tRectF)
; Parameters ....: $tRectF - $tagGDIPRECTF structure that specifies the bounding rectangle of the region
; Return values .: Success      - Pointer to a new Region object
;                  Failure      - 0
; Remarks .......: After you are done with the object, call _GDIPlus_RegionDispose to release the object resources
; Related .......: _GDIPlus_RegionDispose
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionCreateFromRect($tRectF)
    Local $pRectF, $aResult

    $pRectF = DllStructGetPtr($tRectF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateRegionRect", "ptr", $pRectF, "int*", 0)

    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_RegionCreateFromRect

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionCombineRect
; Description ...: Updates a region to the portion of itself that intersects the specified rectangle's interior
; Syntax.........: _GDIPlus_RegionCombineRect($hRegion, $tRectF[, $iCombineMode = 2])
; Parameters ....: $hRegion      - Pointer to a Region object
;                  $tRectF       - $tagGDIPRECTF structure that defines the bounding rectangle
;                  $iCombineMode - Combine mode that specifies how the region is combined with the rectangle:
;                  |0 - The existing region is replaced by the new region
;                  |1 - The existing region is replaced by the intersection of itself and the new region
;                  |2 - The existing region is replaced by the union of itself and the new region
;                  |3 - The existing region is replaced by the result of performing an XOR on the two regions.
;                  +A point is in the XOR of two regions if it is in one region or the other but not in both regions
;                  |4 - The existing region is replaced by the portion of itself that is outside of the new region
;                  |5 - The existing region is replaced by the portion of the new region that is outside of the existing region
; Return values .: Success      - True
;                  Failure      - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionCombineRect($hRegion, $tRectF, $iCombineMode = 2)
    Local $pRectF, $aResult

    $pRectF = DllStructGetPtr($tRectF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCombineRegionRect", "hwnd", $hRegion, "ptr", $pRectF, "int", $iCombineMode)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_RegionCombineRect

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionDispose
; Description ...: Releases a Region object
; Syntax.........: _GDIPlus_RegionDispose($hRegion)
; Parameters ....: $hRegion - Pointer to a Region object
; Return values .: Success      - True
;                  Failure      - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionDispose($hRegion)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeleteRegion", "hwnd", $hRegion)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_RegionDispose
Link to comment
Share on other sites

I didn't read your example UEZ. I'm just about to try it. It's possible to clip the region of the Graphics object:

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w1 -w2 -w3 -w4 -w5 -w6
#AutoIt3Wrapper_UseUpx=Y
#AutoIt3Wrapper_Compression=4
#Autoit3Wrapper_Run_Obfuscator=Y
#Obfuscator_Parameters=/SO
#include <Array.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Memory.au3>
Opt("GUIOnEventMode", 1)

; Graphic binaries
Local $bBallR = '0x89504E470D0A1A0A0000000D494844520000000B0000000B0806000000A9AC77260000000467414D410000B18F0BFC61050000001974455874536F667477617265005061696E742E4E45542076332E352E314EE738F90000003649444154285363644002FF191880081530323000111A0029C4855194E2530893036B2046215CC350544CAC2749093E0EA22206591100760BBA5107CF97330000000049454E44AE426082'

; Distance traveled
; g: the gravitational acceleration
; a: the angle at which the projectile is launched
; v: the velocity at which the projectile is launched
; y: the initial height of the projectile
; d: the total horizontal distance traveled by the projectile
Local $g = 10
Local $a = 60
Local $v = 75
Local $y = 0
$a = $a / 57.2957795130823 ; Convert angle from degrees to radians
Local $d = (($v * Cos($a)) / $g) * ($v * Sin($a) + Sqrt((($v * Sin($a)) ^ 2) + (2 * $g * $y)))

; Calculate the trajectory
Local $aPoints[1][2], $j = 1
For $i = 0 To $d
 $j += 1
 ReDim $aPoints[$j][2]
 $aPoints[$j - 1][0] = $i
 $aPoints[$j - 1][1] = 600 - ($y + ($i * Tan($a)) - ($g * ($i ^ 2)) / (2 * (($v * Cos($a)) ^ 2)))
Next
$aPoints[0][0] = UBound($aPoints) - 1

; Create the GUI
Local $hWnd = GUICreate("Trajectory Test", 800, 600)
GUISetBkColor(0x000000); Black background
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")

GUICtrlCreateLabel("Label", 200, 100, 50, 20)
GUICtrlSetColor(-1, 0xFFFFFF)
GUICtrlCreateInput("Input", 200, 450, 50, 20, 0x01)
GUICtrlSetColor(-1, 0x000000)
GUICtrlCreateButton("Button", 200, 300, 50, 20)
GUICtrlSetColor(-1, 0x000000)

GUISetState()

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hImage = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageFx = _GDIPlus_ImageGetGraphicsContext($hImage)
Local $hImageCurve = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Local $hImageCurveFx = _GDIPlus_ImageGetGraphicsContext($hImageCurve)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 1)
Local $hBallImg = _GDIPlus_BinaryToBitmap($bBallR)

GUIRegisterMsg(0x000F, "_WM_PAINT")
_GDIPlus_GraphicsSetSmoothingMode($hImageCurveFx, 4)

; Draw the Trajectory
_GDIPlus_GraphicsDrawCurve($hImageCurveFx, $aPoints, $hPen)
_GDIPlus_GraphicsDispose($hImageCurveFx)

Local $hRegion = _GDIPlus_RegionCreateFromRect(_GDIPlus_RectFCreate(0, 0, 800, 600))
Local $hChild = _WinAPI_GetWindow($hWnd, $GW_CHILD)
Local $aRect

Do
    $aRect = ControlGetPos($hChild, "", 0)
    _GDIPlus_RegionCombineRect($hRegion, _GDIPlus_RectFCreate($aRect[0], $aRect[1], $aRect[2], $aRect[3]), 3)
    $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
Until Not $hChild

_GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion)
_GDIPlus_RegionDispose($hRegion)

; Draw a red ball following the trajectory
For $i = 1 To $aPoints[0][0]
 _GDIPlus_GraphicsClear($hImageFx)
 _GDIPlus_GraphicsDrawImage($hImageFx, $hImageCurve, 0, 0)
 _GDIPlus_GraphicsDrawImage($hImageFx, $hBallImg, $aPoints[$i][0] - 5, $aPoints[$i][1] - 5)
 _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
 Sleep(10)
Next

While 1
    Sleep(20)
WEnd

Func _Quit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BitmapDispose($hBallImg)
    _GDIPlus_BitmapDispose($hImageCurve)
    _GDIPlus_GraphicsDispose($hImageFx)
    _GDIPlus_BitmapDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

Func _GDIPlus_BinaryToBitmap($Binary)
 Local $bPicData = Binary($Binary)
 Local $iPicLength = BinaryLen($bPicData)
 Local $tPicStruct = DllStructCreate("byte[" & $iPicLength & "]")
 DllStructSetData($tPicStruct, 1, $bPicData)
 Local $pPicMemory = DllStructGetPtr($tPicStruct)
 Local $hMemory = _MemGlobalAlloc($iPicLength, 2)
 Local $pMemory = _MemGlobalLock($hMemory)
 _MemMoveMemory($pPicMemory, $pMemory, $iPicLength)
 _MemGlobalUnlock($hMemory)
 Local $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hMemory, "long", 1, "Int*", 0)
 $pStream = $pStream[3]
 Local $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
 $pBitmap = $pBitmap[2]
 $tPicStruct = 0
 Return $pBitmap
EndFunc

Func _WM_PAINT($hWnd, $iMsg, $iwParam, $ilParam)
 Sleep(20)
 _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)
 Return 'GUI_RUNDEFMSG'
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_GraphicsSetClipRegion
; Description ...: Updates the clipping region of a Graphics object to a region that is the combination of itself and the region
; +specified by a Region object
; Syntax.........: _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion[, $iCombineMode = 0])
; Parameters ....: $hGraphics - Pointer to a Graphics object
; $hRegion - Pointer to a Region object to be combined with the clipping region of the Graphics object
; $iCombineMode - Regions combination mode:
; |0 - The existing region is replaced by the new region
; |1 - The existing region is replaced by the intersection of itself and the new region
; |2 - The existing region is replaced by the union of itself and the new region
; |3 - The existing region is replaced by the result of performing an XOR on the two regions
; |4 - The existing region is replaced by the portion of itself that is outside of the new region
; |5 - The existing region is replaced by the portion of the new region that is outside of the existing region
; Return values .: Success - True
; Failure - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion, $iCombineMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetClipRegion", "hwnd", $hGraphics, "hwnd", $hRegion, "int", $iCombineMode)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsSetClipRegion

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionCreateFromRect
; Description ...: Creates a region that is defined by a rectangle
; Syntax.........: _GDIPlus_RegionCreateFromRect($tRectF)
; Parameters ....: $tRectF - $tagGDIPRECTF structure that specifies the bounding rectangle of the region
; Return values .: Success - Pointer to a new Region object
; Failure - 0
; Remarks .......: After you are done with the object, call _GDIPlus_RegionDispose to release the object resources
; Related .......: _GDIPlus_RegionDispose
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionCreateFromRect($tRectF)
    Local $pRectF, $aResult

    $pRectF = DllStructGetPtr($tRectF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateRegionRect", "ptr", $pRectF, "int*", 0)

    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[2]
EndFunc ;==>_GDIPlus_RegionCreateFromRect

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionCombineRect
; Description ...: Updates a region to the portion of itself that intersects the specified rectangle's interior
; Syntax.........: _GDIPlus_RegionCombineRect($hRegion, $tRectF[, $iCombineMode = 2])
; Parameters ....: $hRegion - Pointer to a Region object
; $tRectF    - $tagGDIPRECTF structure that defines the bounding rectangle
; $iCombineMode - Combine mode that specifies how the region is combined with the rectangle:
; |0 - The existing region is replaced by the new region
; |1 - The existing region is replaced by the intersection of itself and the new region
; |2 - The existing region is replaced by the union of itself and the new region
; |3 - The existing region is replaced by the result of performing an XOR on the two regions.
; +A point is in the XOR of two regions if it is in one region or the other but not in both regions
; |4 - The existing region is replaced by the portion of itself that is outside of the new region
; |5 - The existing region is replaced by the portion of the new region that is outside of the existing region
; Return values .: Success - True
; Failure - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionCombineRect($hRegion, $tRectF, $iCombineMode = 2)
    Local $pRectF, $aResult

    $pRectF = DllStructGetPtr($tRectF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCombineRegionRect", "hwnd", $hRegion, "ptr", $pRectF, "int", $iCombineMode)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_RegionCombineRect

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_RegionDispose
; Description ...: Releases a Region object
; Syntax.........: _GDIPlus_RegionDispose($hRegion)
; Parameters ....: $hRegion - Pointer to a Region object
; Return values .: Success - True
; Failure - False
; Remarks .......: None
; Related .......: None
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_RegionDispose($hRegion)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeleteRegion", "hwnd", $hRegion)

    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_RegionDispose

This is working properly!

I tried to keep it as simple as possible. To use GDIp.au3 is is probably the best way because it has great base of GDI+ functions where you do nice "tricks"!

BR,

UEZ

PS: U R one of my favorite GDI+ masters!

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

  • 2 weeks later...

change

Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)

to

Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.
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...