Sign in to follow this  
Followers 0
tatane

WinAPI and Ellipse drawing

7 posts in this topic

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

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

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

#4 ·  Posted (edited)

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

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

#6 ·  Posted (edited)

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

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  
Followers 0