Jump to content

Recommended Posts

Posted

Hi all, this is my first time ever working with the GuiCtrlCreateGraphic and GuiCtrlSetGraphic functions. I'm making just a little screen saver thing that is supposed to look like a radar. However, because i am new to these functions, I'm not sure how i can optomize this to get rid of the crazy amount of flicker... I'm thinking it is because i create and delete so many controls, i but i don't know how else to erase a line i have drawn with $GUI_GR_LINE

I know this is probably the most CPU intensive way possible to do this, but i can't find any other way.. Halp plz!

#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>
#include <Math.au3>
HotKeySet("{ESC}", "Quit")

$GUI = GUICreate("RADAR",1290, 1034, -1,-1, $WS_POPUP)
    GUISetBkColor(0x182310)
    $Rings = GUICtrlCreateGraphic(100,0, 1280, 1024)
    GUICtrlSetBkColor(-1, 0x182310)
    GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 5)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x008800)
    GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 100,100, 1024-200, 1024-200)
    GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 0,0, 1024, 1024)
    GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 200,200, 1024-400, 1024-400)
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 1024/2,0)
    GUICtrlSetGraphic(-1, $GUI_GR_LINE, 1024/2,1024)
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0,1024/2)
    GUICtrlSetGraphic(-1, $GUI_GR_LINE, 1024,1014/2)
    $CX = 1024/2+100
    $Cy = 1024/2
    Dim $Pos[361][2]
    For $Deg = 0 to 360
    $Time = _Radian($Deg)
    $x= Int($Cx+ Sin($Time)*1024/2)
    $y= Int($CY+ Cos($Time)*1024/2)
    $Pos[$Deg][0] =$x
    $Pos[$Deg][1] =$y
    Next
    GUISetState()
    For $i = 360 to 0 Step -1
    $Line = GUICtrlCreateGraphic(0,0, 0, 0)
    GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 10)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00EE00)
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $Cx,$Cy)
    GUICtrlSetGraphic(-1, $GUI_GR_LINE, $Pos[$i][0],$Pos[$i][1])
    GUICtrlSetGraphic($Line, $GUI_GR_Refresh)
    Sleep(100)
    GUICtrlDelete($Line)
    Next

Func Quit()
    Exit
EndFunc
Posted

I would love to know the same thing. I avoid using graphic controls for this very reason. I wish there was a better alternative to them.

Regards,Josh

Posted

Hi paulie, here's similar with GDIPlus.

It doesn't have the flickering for the background Rador, but the moving radar line still flickers.

#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Math.au3>
HotKeySet("{ESC}", "Quit")

Global $AppW = @DesktopWidth, $AppH = @DesktopHeight, $hGraphic, $hPen, $hPen2, $hPen3

$GUI = GUICreate("RADAR", $AppW, $AppH, 0, 0, $WS_POPUP)
GUISetBkColor(0x182310)
$Label = GUICtrlCreateLabel("", (($AppW - $AppH)/2) + 3, 0, $AppH, $AppH)
$hLabel = GUICtrlGetHandle($Label)

Dim $Pos[361][2]
For $Deg = 0 to 360
    $Time = _Radian($Deg)
    $x= Int($AppH/2+ Sin($Time)*$AppH/2)
    $y= Int($AppH/2+ Cos($Time)*$AppH/2)
    $Pos[$Deg][0] = $x
    $Pos[$Deg][1] = $y
Next
GUISetState()

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hLabel)
$hPen = _GDIPlus_PenCreate(0xFF00EE00, 6)
$hPen2 = _GDIPlus_PenCreate(0xFF182310, 6)
$hPen3 = _GDIPlus_PenCreate(0xFF008800, 6)
For $i = 360 to 0 Step -1
    If $i < 360 Then _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i+1][0], $Pos[$i+1][1], $hPen2)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 3, 3, $AppH - 6, $AppH -6, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 106, 106, $AppH - 212, $AppH - 212, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 209, 209, $AppH - 418, $AppH - 418, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, 0, $AppH/2, $AppH, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, 0, $AppH/2, $AppH, $AppH/2, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i][0], $Pos[$i][1], $hPen)
    Sleep(50)
    If $i = 0 Then $i = 360 
Next

Func Quit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Cheers

Posted (edited)

Absolutely no flickering :-)

and also implemented WM_PAINT so you will not lost your painted image after covering by another application.

#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Math.au3>
HotKeySet("{ESC}", "Quit")

Global $AppW = @DesktopWidth, $AppH = @DesktopHeight
Global $hGraphic, $hPen, $hPen2, $hPen3, $hBackBrush, $i

$GUI = GUICreate("RADAR", $AppW, $AppH, 0, 0, $WS_POPUP)
GUISetBkColor(0x182310)
$Label = GUICtrlCreateLabel("", (($AppW - $AppH)/2) + 3, 0, $AppH, $AppH)
$hLabel = GUICtrlGetHandle($Label)

Dim $Pos[361][2]
For $Deg = 0 to 360
    $Time = _Radian($Deg)
    $x= Int($AppH/2+ Sin($Time)*$AppH/2)
    $y= Int($AppH/2+ Cos($Time)*$AppH/2)
    $Pos[$Deg][0] = $x
    $Pos[$Deg][1] = $y
Next

Global $hdc = _WinAPI_GetDC($hLabel) ; draw on label
Global $memory_dc = _WinAPI_CreateCompatibleDC($hdc)
Global $memory_bm = _WinAPI_CreateCompatibleBitmap($hdc, $AppW, $AppH)
_WinAPI_SelectObject($memory_dc, $memory_bm)

_GDIPlus_Startup()
;~ $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hLabel)
$hGraphic = _GDIPlus_GraphicsCreateFromHDC($memory_dc)
$hPen = _GDIPlus_PenCreate(0xFF00EE00, 6)
;~ $hPen2 = _GDIPlus_PenCreate(0xFF182310, 6)
$hPen3 = _GDIPlus_PenCreate(0xFF008800, 6)
$hBrushBack = _WinAPI_CreateSolidBrush(0x182310)

$trect = DllStructCreate($tagRECT) ; for _WinAPI_FillRect()
DllStructSetData($trect, 'Left', 0)
DllStructSetData($trect, 'Top', 0)
DllStructSetData($trect, 'Right', $AppH)
DllStructSetData($trect, 'Bottom', $AppH)
$prect = DllStructGetPtr($trect)

GUIRegisterMsg($WM_PAINT, 'MY_WM_PAINT')
GUISetState()

For $i = 360 to 0 Step -1
 _RePaint()
    Sleep(50)
    If $i = 0 Then $i = 360 
Next

Func Quit()
 _WinAPI_ReleaseDC($hLabel, $hdc)
 _WinAPI_DeleteDC($memory_dc)
 _WinAPI_DeleteObject($memory_bm)
 
    _GDIPlus_PenDispose($hPen)
;~     _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
 _WinAPI_DeleteObject($hBrushBack)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    $trect = 0
    Exit
EndFunc

Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam)
;~     _WinAPI_RedrawWindow($hLabel, 0, 0, $RDW_UPDATENOW) ; force redraw of label
 _RePaint()
;~     _WinAPI_RedrawWindow($hLabel, 0, 0, $RDW_VALIDATE) ; then force no-redraw of label
 Return $GUI_RUNDEFMSG
EndFunc

; Note: $i is global variable
Func _RePaint()
 ; all drawing is done onto invisible memory DC/bitmap/graphic first
 _WinAPI_FillRect($memory_dc, $prect, $hBrushBack) ; clear background
;~     If $i < 360 Then _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i+1][0], $Pos[$i+1][1], $hPen2)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 3, 3, $AppH - 6, $AppH -6, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 106, 106, $AppH - 212, $AppH - 212, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 209, 209, $AppH - 418, $AppH - 418, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, 0, $AppH/2, $AppH, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, 0, $AppH/2, $AppH, $AppH/2, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i][0], $Pos[$i][1], $hPen)
 ; copy whole content of memory DC to Window/label DC (screen)
 _WinAPI_BitBlt( $hdc, 0, 0, $AppW, $AppH, $memory_dc, 0, 0, $SRCCOPY)
EndFunc
Edited by Zedna
Posted

Hey Paulie, monoceres and I had been working on something exactly like this. You should ask him about it.

Posted

Simplified version:

_GDIPlus_GraphicsClear() instead of _WinAPI_FillRect()

#include <GUIConstantsEX.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Math.au3>
HotKeySet("{ESC}", "Quit")

Global $AppW = @DesktopWidth, $AppH = @DesktopHeight
Global $hGraphic, $hPen, $hPen2, $hPen3, $i

$GUI = GUICreate("RADAR", $AppW, $AppH, 0, 0, $WS_POPUP)
GUISetBkColor(0x182310)
$Label = GUICtrlCreateLabel("", (($AppW - $AppH)/2) + 3, 0, $AppH, $AppH)
$hLabel = GUICtrlGetHandle($Label)

Dim $Pos[361][2]
For $Deg = 0 to 360
    $Time = _Radian($Deg)
    $x= Int($AppH/2+ Sin($Time)*$AppH/2)
    $y= Int($AppH/2+ Cos($Time)*$AppH/2)
    $Pos[$Deg][0] = $x
    $Pos[$Deg][1] = $y
Next

Global $hdc = _WinAPI_GetDC($hLabel) ; draw on label
Global $memory_dc = _WinAPI_CreateCompatibleDC($hdc)
Global $memory_bm = _WinAPI_CreateCompatibleBitmap($hdc, $AppW, $AppH)
_WinAPI_SelectObject($memory_dc, $memory_bm)

_GDIPlus_Startup()
;~ $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hLabel)
$hGraphic = _GDIPlus_GraphicsCreateFromHDC($memory_dc)
$hPen = _GDIPlus_PenCreate(0xFF00EE00, 6)
;~ $hPen2 = _GDIPlus_PenCreate(0xFF182310, 6)
$hPen3 = _GDIPlus_PenCreate(0xFF008800, 6)

GUIRegisterMsg($WM_PAINT, 'MY_WM_PAINT')
GUISetState()

For $i = 360 to 0 Step -1
 _RePaint()
    Sleep(50)
    If $i = 0 Then $i = 360 
Next

Func Quit()
 _WinAPI_ReleaseDC($hLabel, $hdc)
 _WinAPI_DeleteDC($memory_dc)
 _WinAPI_DeleteObject($memory_bm)
 
    _GDIPlus_PenDispose($hPen)
;~     _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam)
;~     _WinAPI_RedrawWindow($hLabel, 0, 0, $RDW_UPDATENOW) ; force redraw of label
 _RePaint()
;~     _WinAPI_RedrawWindow($hLabel, 0, 0, $RDW_VALIDATE) ; then force no-redraw of label
 Return $GUI_RUNDEFMSG
EndFunc

; Note: $i is global variable
Func _RePaint()
 ; all drawing is done onto invisible memory DC/bitmap/graphic first
 _GDIPlus_GraphicsClear($hGraphic, 0xFF182310) ; clear background
;~     If $i < 360 Then _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i+1][0], $Pos[$i+1][1], $hPen2)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 3, 3, $AppH - 6, $AppH -6, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 106, 106, $AppH - 212, $AppH - 212, $hPen3)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 209, 209, $AppH - 418, $AppH - 418, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, 0, $AppH/2, $AppH, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, 0, $AppH/2, $AppH, $AppH/2, $hPen3)
    _GDIPlus_GraphicsDrawLine($hGraphic, $AppH/2, $AppH/2, $Pos[$i][0], $Pos[$i][1], $hPen)
 ; copy whole content of memory DC to Window/label DC (screen)
 _WinAPI_BitBlt( $hdc, 0, 0, $AppW, $AppH, $memory_dc, 0, 0, $SRCCOPY)
EndFunc

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...