Jump to content

GDI+ Draw line


Recommended Posts

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
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...