Jump to content
Sign in to follow this  
tatane

WinAPI and Ellipse drawing

Recommended Posts

tatane

Hi.

Here is a script that draw a circle on the screen. It works fine.


#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GuiSlider.au3>


Global $Circle_Thickness = 2
Global $circleON = False
Global $GUI
Local $iLastSlider = 30

Local $gui_tweaks = GUICreate("Tweaks", 160, 100, -1, -1, BitXOR($GUI_SS_DEFAULT_GUI, $WS_MINIMIZEBOX))

Global $tweak_radius_slider = GUICtrlCreateSlider(5, 35, 150, 30, $TBS_AUTOTICKS)
GUICtrlSetLimit(-1, 400, 30) ; set min/max circle radius
_GUICtrlSlider_SetTicFreq($tweak_radius_slider, 50)

Local $OnOff_checkbox = GUICtrlCreateCheckbox("Circle ON/OFF", 10, 75)

Local $label_radius_value = GUICtrlCreateLabel(GUICtrlRead($tweak_radius_slider), 70, 5)

GUISetState(@SW_SHOW, $gui_tweaks)


While 1

Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
        Case $OnOff_checkbox
            _CircleSwitch()
EndSwitch

$iCurrSlider = GUICtrlRead($tweak_radius_slider)
If $iCurrSlider <> $iLastSlider Then
GUICtrlSetData($label_radius_value, $iCurrSlider)
        If BitAND(GUICtrlRead($OnOff_checkbox), $GUI_CHECKED) = $GUI_CHECKED Then
            _UpdateCircle()
        EndIf
$iLastSlider = $iCurrSlider
EndIf

    Sleep(10)
WEnd

Func _CircleSwitch()
    $circleON = Not $circleON
    If Not $circleON Then
        If WinExists("Circle") Then    GUISetState(@SW_HIDE, $GUI)
    Else
        _UpdateCircle()
    EndIf
EndFunc

Func _UpdateCircle()
    Local $radius = GUICtrlRead($tweak_radius_slider)
    Local $Diameter = $radius * 2

    If WinExists("Circle") Then
        GUIDelete($GUI)
        _CircleCreate($radius, $Diameter)
    Else
        _CircleCreate($radius, $Diameter)
        GUISetState(@SW_SHOW, $GUI)
    EndIf
EndFunc

Func _CircleCreate($rad, $diam)
    $GUI = GUICreate("Circle", $diam, $diam, @DesktopWidth / 2 - $rad, @DesktopHeight / 2 - $rad, $WS_POPUP, $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
    GUISetBkColor(0xFF0000)

    $a = _WinAPI_CreateRoundRectRgn(0, 0, $diam, $diam, $diam, $diam)
    $b = _WinAPI_CreateRoundRectRgn($Circle_Thickness, $Circle_Thickness, ($diam - $Circle_Thickness), ($diam - $Circle_Thickness), $diam, $diam)
    _WinAPI_CombineRgn($a, $a, $b, 3)
    _WinAPI_SetWindowRgn($GUI, $a, 1)
    _WinAPI_DeleteObject($a)
    _WinAPI_DeleteObject($b)

    GUISetState(@SW_SHOW, $GUI)
    GUISetState(@SW_DISABLE, $GUI)
EndFunc

My problem is that I would like to draw a perspective circle (an ellipse) as if the circle was on the floor and you see it at 2 meters from it.

It seems WinAPI_Create RoundRectRgn is not able to do it cause the witdh of the rectangle must be different at the bottom and top.

I saw some GDI+ functions but I don't know if I can keep the "clickable" transparency like in the script example (mandatory).

I hope you have understood me cause my english sucks :P.

Thanks.

Share this post


Link to post
Share on other sites
UEZ

You can use _WinAPI_Ellipse() to create ellipses.

Br,

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
tatane

I'm sorry but this doesn't answer my question. Like I said, the kind of ellipse i would like to draw is in perspective so you don't draw a circle/ellipse within a rectangle but within a trapezium.

The Ellipse function (http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28Ellipse%29;k%28DevLang-C%29;k%28TargetOS-WINDOWS%29&rd=true) allows 4 parameters to make a rectangle not a trapezium.

Moreover i'm not sure that I will be able to click through the transparency of the GUI.

Or maybe I'm wrong and it just slipp ou.

Share this post


Link to post
Share on other sites
UEZ

Try something like this here:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <WinAPIGdi.au3>


Global Const $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0x123456, $hGUI)
_WinAPI_SetLayeredWindowAttributes($hGUI, 0x123456)

GUISetState()

DrawEllipse(300, 300, 300, 100, 0xFF)
Sleep(2000)

_WinAPI_RedrawWindow($hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW))

DrawEllipse(500, 100, 100, 300, 0xFF)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE


Func DrawEllipse($iPosX, $iPosY, $iWidth, $iHeight, $color, $iPenSize = 2)
    Local $hDC = _WinAPI_GetWindowDC($hGUI) ; DC of entire screen (desktop)
    Local $hPen = _WinAPI_CreatePen($PS_SOLID, $iPenSize, $color)
    Local $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0x123456)
    Local $hObj1 = _WinAPI_SelectObject($hDC, $hBrush)
    Local $hObj2 = _WinAPI_SelectObject($hDC, $hPen)
    Local $tRECT = _WinAPI_CreateRect(0, 0, $iWidth, $iHeight)
    _WinAPI_OffsetRect($tRECT, $iPosX, $iPosY)
    _WinAPI_Ellipse($hDC, $tRECT)
    _WinAPI_SelectObject($hDC, $hObj1)
    _WinAPI_SelectObject($hDC, $hObj2)
    _WinAPI_DeleteObject($hPen)
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_ReleaseDC($hGUI, $hDC)
EndFunc   ;==>DrawEllipse

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

Share this post


Link to post
Share on other sites
Malkey

An ellipse within a trapezium would not really be an ellipse. Therefore, all ellipse functions which only draw ellipses in a rectangle can not be used.

See _WinAPI_Ellipse and _WinAPI_PolyBezier functions AutoIt help file.
See GUICtrlSetGraphic in AutoIt help file for Ellipse and Bezier.
See Direct2D by trancexx >here.  
See  a GDI_Plus version of a bezier curve >here

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

Global Const $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0x123456, $hGUI)
_WinAPI_SetLayeredWindowAttributes($hGUI, 0x123456)

GUISetState()

;Points output from example at:-
; http://www.autoitscript.com/forum/topic/82782-gdi-bezier-curve-examples/#entry592598
;Local $aPoints[14][2] = [[13,0],[105,26],[140,26],[183,55],[183,80],[183,110],[145,125], _
;[105,126],[65,124],[32,110],[32,80],[32,55],[70,26],[105,26]]
; To work with _WinAPI_PolyBezier() remove first elements with number of points, and adjust
; dimensions in array, as in next line of code.
Local $aPoints[13][2] = [[105, 26],[140, 26], _             ; 1st point, and control point from 1st point.
                         [183, 55],[183, 80],[183, 110], _  ; control point to next point, next point, and control point fron next point.
                         [145, 125],[105, 126],[65, 124], _ ; control point to next point, next point, and control point fron next point.
                         [32, 110],[32, 80],[32, 55], _     ; control point to next point, next point, and control point fron next point.
                         [70, 26],[105, 26]]                ; control point to last point, and last point.
DrawBezier($aPoints, 0xFF0000); BGR
Sleep(3000)

_WinAPI_RedrawWindow($hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW))

Local $aPoints[13][2] = [[110, 28],[135, 28], _
                         [160, 46],[160, 95],[160, 134], _
                         [135, 200],[110, 200],[75, 200], _
                         [64, 135],[64, 95],[64, 46], _
                         [85, 28],[110, 28]]
DrawBezier($aPoints, 0x0000FF)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE


Func DrawBezier($aPoints, $color, $iPenSize = 2)
    Local $hDC = _WinAPI_GetWindowDC($hGUI) ; DC of entire screen (desktop)
    Local $hPen = _WinAPI_CreatePen($PS_SOLID, $iPenSize, $color) ; BGR
    Local $hObj2 = _WinAPI_SelectObject($hDC, $hPen)
    _WinAPI_PolyBezier($hDC, $aPoints)
    _WinAPI_SelectObject($hDC, $hObj2)
    _WinAPI_DeleteObject($hPen)
    _WinAPI_ReleaseDC($hGUI, $hDC)
EndFunc   ;==>DrawBezier

Share this post


Link to post
Share on other sites
tatane

Thanks both of you.

Il will try your solutions.

EDIT : The drawing parts are ok but because of no region set, I can't click through the transparent GUI and I absolutly need this functionnality. I don't see a way to make a region corresponding to the ellipse drawing...

Edited by tatane

Share this post


Link to post
Share on other sites
UEZ

Sorry, I didn't read the "trapezium" part but Malkey provided a way how to do it.

Thanks Malkey.

Br,

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

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  

×