Jump to content
Sign in to follow this  
TheReveller

GDI+ Draw line

Recommended Posts

TheReveller

Hello,

With GDI+ functions, we are able to draw lines from (x1,y1) to (x2,y2) but is there a way to set an ID for that line and then to select the line and modify its (x1,y1) and (x2,y2) coordinates without have to redraw ?

At this moment, when I want to modify the coordinates of a line I just restart the drawing with the new coordinates but that makes the screen to flash...

Thanks.

Share this post


Link to post
Share on other sites
UEZ

Hello,

With GDI+ functions, we are able to draw lines from (x1,y1) to (x2,y2) but is there a way to set an ID for that line and then to select the line and modify its (x1,y1) and (x2,y2) coordinates without have to redraw ?

At this moment, when I want to modify the coordinates of a line I just restart the drawing with the new coordinates but that makes the screen to flash...

Thanks.

To avoid flickering you have to use the double buffering technique!

You can check GDI+ examples thread to learn more about double buffering!

You cannot change a line without redrawing it!

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

Share this post


Link to post
Share on other sites
TheReveller

Thanks, but can you explain me fast what does it consist ?

I mean, I have to move many different lines on a fullscreen window and the background color is not black...

Thanks.

By the way, your visual effects are cool.

Share this post


Link to post
Share on other sites
TheReveller

Your scripts are absolutly amazing ! I love maths and I want to learn more about many things I saw in your scripts.

But I'm still wondering about how I can move a line without flashing the screen, I can't figure it out because all the animations are on a black or white background.

Can you do some easy example of a fullscreen transparent (40%) window and in that window you draw a red line with one point attached to the mouse move and that without flashing ?

Is it possible ?

Thanks.

Share this post


Link to post
Share on other sites
Malkey

TheReveller

This script draws one end of a line that follows the mouse with no GUI background colour and no flickering.

Malkey

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
Opt('MustDeclareVars', 1)
Global $sPos
_Main()

Func _Main()
    Local $hGUI, $hWnd, $hGraphic, $hPen, $msg

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300, -1, -1)
    $hWnd = WinGetHandle("GDI+")
    GUISetState()

    ; Draw line
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $hPen = _GDIPlus_PenCreate(0xFF609900, 2)
    _AntiAlias($hGraphic)
    
    ; Loop until user exits
    do
        $msg = GUIGetMsg()
        if $msg = $GUI_EVENT_MOUSEMOVE Then
            _WinAPI_RedrawWindow($hGUI, "", "", BitOR($WM_ERASEBKGND, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))
            _GDIPlus_GraphicsDrawLine($hGraphic, 10, 150, MouseGetPos(0), MouseGetPos(1), $hPen)
        EndIf
        
    until $msg = $GUI_EVENT_CLOSE
    ; Clean up resources
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

EndFunc   ;==>_Main

Func _AntiAlias($hGraphics)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_AntiAlias

Share this post


Link to post
Share on other sites
TheReveller

That's exactly the fast and easy thing I was looking for ! _WinAPI_RedrawWindow($hGUI, "", "", BitOR($WM_ERASEBKGND, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) (Even if I really don't understand the parameters)

And can you give me more info about the parameters of this : DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)

Thanks.

At least with this, only my lines may flash a little bit if I refresh many big lines, but not the full screen.

One last thing now, but I don't think it's possible... I draw many lines and there is a ToolTip() following my cursor and when the tooltip moves over the lines, it kinda erase a part of the line, so I have to refresh the draw... Do you have any idea ?

I'll also take a look at this when I'll have more time (meaning not in april... that's why I used the easy function above)

Start playing with this double buffering template.

http://www.autoitscript.com/forum/index.ph...mp;#entry617017

Just redraw the line each loop with a new position.

Edited by TheReveller

Share this post


Link to post
Share on other sites
Malkey

That's exactly the fast and easy thing I was looking for ! _WinAPI_RedrawWindow($hGUI, "", "", BitOR($WM_ERASEBKGND, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) (Even if I really don't understand the parameters)

And can you give me more info about the parameters of this : DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)

Thanks.

At least with this, only my lines may flash a little bit if I refresh many big lines, but not the full screen.

One last thing now, but I don't think it's possible... I draw many lines and there is a ToolTip() following my cursor and when the tooltip moves over the lines, it kinda erase a part of the line, so I have to refresh the draw... Do you have any idea ?

About GdipSetSmoothingMode there is this,

SmoothingModeDefault = 0

SmoothingModeHighSpeed = 1

SmoothingModeHighQuality = 2

SmoothingModeNone = 3

SmoothingModeAntiAlias = 4

and

http://msdn.microsoft.com/en-us/library/ms534173(VS.85).aspx

And, this example is the same as above but with a GUIRegisterMsg() which auto-calls the MY_PAINT() function. This should redraw the line after a tool tip erases the line.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
Opt('MustDeclareVars', 1)
Global $hGUI, $hGraphic, $hPen

_Main()

Func _Main()
    Local $msg

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300, -1, -1)
    GUISetState()
    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    ; Draw line
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
    _AntiAlias($hGraphic)

    ; Loop until user exits
    Do
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_MOUSEMOVE Then
            _WinAPI_RedrawWindow($hGUI, "", "", BitOR($WM_ERASEBKGND, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))
            _GDIPlus_GraphicsDrawLine($hGraphic, 10, 150, MouseGetPos(0), MouseGetPos(1), $hPen)
        EndIf

    Until $msg = $GUI_EVENT_CLOSE
    ; Clean up resources
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

EndFunc   ;==>_Main

Func _AntiAlias($hGraphics)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_AntiAlias

Func MY_PAINT($hwnd, $msg, $wParam, $lParam)
    ; Check, if the GUI with the Graphic should be repainted
    If $hwnd = $hGUI Then
        _WinAPI_RedrawWindow($hGUI, "", "", BitOR($WM_ERASEBKGND, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))
        _GDIPlus_GraphicsDrawLine($hGraphic, 10, 150, MouseGetPos(0), MouseGetPos(1), $hPen)
    EndIf
EndFunc   ;==>MY_PAINT

Share this post


Link to post
Share on other sites
TheReveller

Many thanks !

You answered all my questions with a code I can easily add in my script without having to do modifications everywhere.

Share this post


Link to post
Share on other sites
TheReveller

It's not that much important, but I noticed that with all this if I have more than about 240 lines, it freezes.

Eh, well, since I'm making lines and dots with a small line, that means in reality about 480 total lines drawn...

But it's ok, I set a maximum of 200 lines and it shall be more than enough.

Edited by TheReveller

Share this post


Link to post
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
Sign in to follow this  

×