Jump to content

Formula for rounding corners


Recommended Posts

Hi all

Okay I'm looking for a bit of help polishing up a script. I was inspired by to try and find a simpler way to render a rounded corner semi-transparent background using a semi-transparent gdi pen (if there was a semi-transparent brush, life would be so much easier). I think I have it but perhaps my math skills are not up for the challenge that corners provide. I showed 2 ways I tried in the below GUI. Both are less than perfect. Can someone help me figure out how to draw the corners?

#include <GUIConstantsEx.au3>
#include <WINAPI.au3>
#include <GDIPlus.au3>

commonbck()

Func commonbck()
    $Gui = GUICreate("", 400,300,-1,-1)
 ;   $bckpic_prime= GUICtrlCreatePic("BkgPic.jpg",0,0,400,300)
 ; GuiCtrlSetState(-1,$GUI_DISABLE)
    $bckpic= GUICtrlCreatePic("",50,50,300, 150)
    GuiCtrlSetState(-1,$GUI_DISABLE)
    background(-1)

    $title=GUICtrlCreateLabel("Transparent background, only one GUI",75,55,260,120)
    GUICtrlSetFont(-1,20,400,1,"Verdana")
    GUICtrlSetColor(-1,"0x000022")
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    GUISetState()

EndFunc

While 1
sleep(50)
        $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE
                Exit
        EndSelect
WEnd

func background($control)
    _GDIPlus_Startup ()
    $hwd=GUICtrlGetHandle($control)
    ;$guiname=_WinAPI_GetParent($hwd)
    $iX=0
    $iY=0
    $iWidth=_WinAPI_GetClientWidth($hwd)
    $iHeight=_WinAPI_GetClientHeight($hwd)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hwd)
    $hBitmap1 = _GDIPlus_BitmapCreateFromGraphics($iWidth+1,$iHeight+1, $hGraphic)
    $hImage1=_GDIPlus_ImageGetGraphicsContext($hBitmap1)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 4)
    $hPen2=_GDIPlus_PenCreate(BitOR(0x32000000,0x000000),1)
;for $p = 0 to $width step 1
$iRadius=14
$midW=$iWidth/2
$midH=$iHeight/2
for $m = 1 to $iRadius
    _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iWidth-$m, $iY + $iRadius, $iX + $iWidth-$m, $iY + $iHeight - $iRadius,$hPen2) ; right line
    _GDIPlus_GraphicsDrawLine($hImage1, $iX+$m, $iY + $iHeight - $iRadius, $iX+$m, $iY + $iRadius,$hPen2)   ; left line
Next
for $m = 0 to $midH
    _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iRadius+1, $iY+$m-1, $iX + $iWidth - $iRadius-1 , $iY+$m-1,$hPen2)       ;top line
    _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iWidth - $iRadius-1 , $iY + $iHeight-$m, $iX + $iRadius+1, $iY-$m + $iHeight,$hPen2) ; bottom line
Next

for $n=1 to $iRadius
    ;variation #1 for corners
 _GDIPlus_GraphicsDrawarc ($hImage1, $iX + $iWidth - ($iRadius * 2)+1, $iY+$n, $iRadius * 2-2, $iRadius * 2-($n*2), 270, 90,$hPen2) ; top right corner
_GDIPlus_GraphicsDrawArc ($hImage1, $iX+1, $iY + $iHeight - ($iRadius *2)+$n, $iRadius * 2-1, $iRadius * 2-($n*2), 90, 90,$hPen2)   ; bottom left corner
    ;variation #2 for corners
_GDIPlus_GraphicsDrawArc ($hImage1, $iX + $iWidth - ($iRadius * 2)+$n+1, $iY + $iHeight - ($iRadius * 2)+$n+1, $iRadius * 2-1-($n*2), $iRadius * 2-($n*2), 0, 90,$hPen2) ; bottom right corner
 _GDIPlus_GraphicsDrawArc ($hImage1, $iX+1+$n, $iY+$n, $iRadius * 2-($n*2)-1, $iRadius * 2-1-($n*2), 180, 90,$hPen2) ; top left corner
Next



 _GDIPlus_PenDispose($hPen2)
    _GDIPlus_GraphicsSetSmoothingMode($hImage1, 2)
    $hBMP1 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($control, 0x0172, 0, $hBMP1))
    _GDIPlus_GraphicsDispose($hImage1)
    _WinAPI_DeleteObject($hBMP1)
    _GDIPlus_BitmapDispose($hBitmap1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown ()
EndFunc
Link to comment
Share on other sites

I don't know if it will help you at all but here is Garys old code for corner rounding. It may even need a touchup since I haven't looked at it for a long time now.

;===============================================================================
; Function Name:   _Gui_RoundCorners()
; Description:   Round the corners of a GUI window
; Syntax:
; Parameter(s):   $h_win -  Form to work with
; Requirement(s):
; Return Value(s):
; Author(s):   Gary Frost (I just renamed the function)
; Example :   _Gui_RoundCorners(WinGetHandle("My Window"), 0, 0, 30, 30)
;===============================================================================

Func _Gui_RoundCorners($h_win, $i_x1, $i_y1, $i_x3, $i_y3)
  Local $XS_pos, $XS_ret, $XS_ret2
  $XS_pos = WinGetPos($h_win)
  $XS_ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $i_x1, "long", $i_y1, "long", $XS_pos[2], "long", $XS_pos[3], "long", $i_x3, "long", $i_y3)
  If $XS_ret[0]Then
    $XS_ret2 = DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $XS_ret[0], "int", 1)
  EndIf
EndFunc   ;==>_Gui_RoundCorners

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

Here an alternative method: http://www.autoitscript.com/forum/index.php?showtopic=97362

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

Link to comment
Share on other sites

A part of this has a rounding corner effect:

You can select what corners to round aswell

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

Thanks for all the input.

Yes I am perhaps reinventing the wheel when so many options already exist. I guess I like to play in autoit and find ways to simplify things. Tip is the gentleman that made both the script I referenced and the one Maffe811 referenced. He used multiple gui's and used Gary's round corner code that Geosoft referenced. It is a viable option and I will use that if I can't make this work with a guictrl.

Uez, yes I am aware of that very cool example. Unfortunately he uses a brush to fill his shape. I am unaware of a way to make a brush produce a semi-transparent colour. I think one of your past posts was the source of how I learned to use a pen to make semi-transparent. So can it be done with a brush :huh2:

Func _GDIPlus_GraphicsFillPath($hGraphics, $hBrush, $hGraphicsPath)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipFillPath", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hGraphicsPath)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, 0)
EndFunc

Thanks again for your posts.

Cheers

Picea892

Link to comment
Share on other sites

It is easy as using pens!

#include <GUIConstantsEx.au3>
#include <WINAPI.au3>
#include <GDIPlus.au3>

commonbck()

Func commonbck()
    $Gui = GUICreate("", 400,300,-1,-1)
 ;   $bckpic_prime= GUICtrlCreatePic("BkgPic.jpg",0,0,400,300)
 ; GuiCtrlSetState(-1,$GUI_DISABLE)
    $bckpic= GUICtrlCreatePic("",50,50,300, 150)
    GuiCtrlSetState(-1,$GUI_DISABLE)
    background(-1)

    $title=GUICtrlCreateLabel("Transparent background, only one GUI",75,55,260,120)
    GUICtrlSetFont(-1,20,400,1,"Verdana")
    GUICtrlSetColor(-1,"0x000022")
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    GUISetState()

EndFunc

While 1
sleep(50)
        $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE
                Exit
        EndSelect
WEnd

func background($control)
    _GDIPlus_Startup ()
    $hwd=GUICtrlGetHandle($control)
    ;$guiname=_WinAPI_GetParent($hwd)
    $iX=0
    $iY=0
    $iWidth=_WinAPI_GetClientWidth($hwd)
    $iHeight=_WinAPI_GetClientHeight($hwd)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hwd)
    $hBitmap1 = _GDIPlus_BitmapCreateFromGraphics($iWidth+1,$iHeight+1, $hGraphic)
    $hImage1=_GDIPlus_ImageGetGraphicsContext($hBitmap1)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 4)
    $hPen2=_GDIPlus_PenCreate(BitOR(0x32000000,0x000000),1)
    $hBrush=_GDIPlus_BrushCreateSolid(0x32000000)
;for $p = 0 to $width step 1
$iRadius=14
$midW=$iWidth/2
$midH=$iHeight/2
;~ for $m = 1 to $iRadius
;~     _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iWidth-$m, $iY + $iRadius, $iX + $iWidth-$m, $iY + $iHeight - $iRadius,$hPen2) ; right line
;~     _GDIPlus_GraphicsDrawLine($hImage1, $iX+$m, $iY + $iHeight - $iRadius, $iX+$m, $iY + $iRadius,$hPen2)   ; left line
;~ Next
;~ for $m = 0 to $midH
;~     _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iRadius+1, $iY+$m-1, $iX + $iWidth - $iRadius-1 , $iY+$m-1,$hPen2)       ;top line
;~     _GDIPlus_GraphicsDrawLine($hImage1, $iX + $iWidth - $iRadius-1 , $iY + $iHeight-$m, $iX + $iRadius+1, $iY-$m + $iHeight,$hPen2) ; bottom line
;~ Next

;~ for $n=1 to $iRadius
;~     ;variation #1 for corners
;~  _GDIPlus_GraphicsDrawarc ($hImage1, $iX + $iWidth - ($iRadius * 2)+1, $iY+$n, $iRadius * 2-2, $iRadius * 2-($n*2), 270, 90,$hPen2) ; top right corner
;~ _GDIPlus_GraphicsDrawArc ($hImage1, $iX+1, $iY + $iHeight - ($iRadius *2)+$n, $iRadius * 2-1, $iRadius * 2-($n*2), 90, 90,$hPen2)   ; bottom left corner
;~     ;variation #2 for corners
;~ _GDIPlus_GraphicsDrawArc ($hImage1, $iX + $iWidth - ($iRadius * 2)+$n+1, $iY + $iHeight - ($iRadius * 2)+$n, $iRadius * 2-1-($n*2), $iRadius * 2-($n*2), 0, 90,$hPen2) ; bottom right corner
;~  _GDIPlus_GraphicsDrawArc ($hImage1, $iX+1+$n, $iY+$n, $iRadius * 2-($n*2)-1, $iRadius * 2-1-($n*2), 180, 90,$hPen2) ; top left corner
;~ Next

_GDIPlus_GraphicsFillRect($hImage1, $iX + $iRadius + 1, $iY, $iWidth - $iRadius * 2 - 1, $iHeight, $hBrush)
_GDIPlus_GraphicsFillRect($hImage1, $iX + 1, $iY + $iRadius, $iRadius, $iHeight - $iRadius * 2, $hBrush)
_GDIPlus_GraphicsFillRect($hImage1, $iWidth - $iRadius, $iY + $iRadius, $iRadius, $iHeight - $iRadius * 2, $hBrush)

_GDIPlus_GraphicsFillPie($hImage1, $iX + $iWidth - ($iRadius * 2), $iY, $iRadius * 2, $iRadius * 2, 270, 90,$hBrush) ; top right corner
_GDIPlus_GraphicsFillPie($hImage1, $iX+1, $iY + $iHeight - ($iRadius *2), $iRadius * 2, $iRadius * 2, 90, 90,$hBrush)   ; bottom left corner
_GDIPlus_GraphicsFillPie($hImage1, $iX + $iWidth - ($iRadius * 2), $iY + $iHeight - ($iRadius * 2), $iRadius * 2, $iRadius * 2, 0, 90,$hBrush) ; bottom right corner
_GDIPlus_GraphicsFillPie($hImage1, $iX, $iY, $iRadius * 2 + 1, $iRadius * 2, 180, 90,$hBrush) ; top left corner

_GDIPlus_BrushDispose($hBrush)

 _GDIPlus_PenDispose($hPen2)
    _GDIPlus_GraphicsSetSmoothingMode($hImage1, 2)
    $hBMP1 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($control, 0x0172, 0, $hBMP1))
    _GDIPlus_GraphicsDispose($hImage1)
    _WinAPI_DeleteObject($hBMP1)
    _GDIPlus_BitmapDispose($hBitmap1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown ()
EndFunc

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

Link to comment
Share on other sites

Uez, hmm, yes it was easy to make a brush use a transparent colour :huh2:;) Geez don't I feel a little silly... I tried doing that...failed and then moved on to using pens, guess I should have tried harder.

That is absolutely perfect, thank you so much for completing the script for me. It is so much easier with _GDIPlus_GraphicsFillPie....

Now I have a really excellent script for my toolkit. I'm certain a variation of this will find it's way into most of the GUIs I produce from now on.

Thanks again.

Picea892

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