Jump to content
Sign in to follow this  
Paulie

Optomize Challenge

Recommended Posts

Paulie

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

Share this post


Link to post
Share on other sites
JFee

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

Share this post


Link to post
Share on other sites
smashly

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

Share this post


Link to post
Share on other sites
Zedna

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

Share this post


Link to post
Share on other sites
weaponx

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

Share this post


Link to post
Share on other sites
Zedna

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

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  

×