Subject Re: WIN 11 Borderless Buttons with Rounded Corners
From Michael <michael@abstractservices.com.au>
Date Tue, 21 Mar 2023 17:55:32 -0400
Newsgroups dbase.getting-started

Wow! Mervyn,

I am lost for words, your a living legend!

That code works nicely, yes, if the buttons are small the graphic quality around the edges is pixelated but you can turn off the border and the thin border of the button can be coloured so it actually comes up ok on a larger sized button.

I may not be able to use it across the board but will definately solve my login screen presentation. If you send me you email address and I will send some screen shots/videos of the results.

I think this is workable, I cannot thank you enough Mervyn, it has saved me alot of work.

Truly, Thank you,

Michael.

Mervyn Bick Wrote:

> On 2023/03/21 10:15, michael wrote:
> > Hi Guys,
> >
> > Ok, I will give you greater detail in what I am trying to do. Here is a history and request in point form,
> ....
> > 3. I need to take it up a notch, so launching a new brand, website, social media campaign to mirrow the new demographics and current rounded windows style. See pic 2. this is where I am trying to get to and its a design of where we need to be in the current market.
>
> In the past I have "borrowed" code from Marc van den Berghen to create
> circular pushbuttons.  This used CreateEllipticRgn() from the Windows32
> API.  CreateRoundRectRgn() from the API creates a rectangular region
> with rounded corners, which can be altered to suit, but I haven't (yet
> :-) ) managed to get this to work properly.
>
> The attached custom pushbutton comes close but it uses
> CreateEllipticRgn() and relies on a dBASE shape object to provide the
> line round the pushbutton.  The rounding of the corners is unfortunately
> not adjustable.
>
> The custom control uses an onOpen event handler internally.  If your
> existing pushbuttons use an onOpen event handler it will be necessary to
> insert a call to the custom control's onOpen event handler before any
> other code.
>
> It is easy enough to write a little program that will add the set
> procedure line immediately after a form's class definition and then
> replace 'new PUSHBUTTON(this)' with 'new ROUND_CORNER_BUTTON(this)'.
>
> The custom control requires the form metric to be set to pixels.  The
> easiest way is to open each form in the IDE, change the metric and then
> save.  Acceptable for a few form but a PITA if there are many forms.
> Again, it's not a problem to change top, left, width and height values
> in a program but the factors to apply depend on the original metric.
>
> Mervyn.
>  /*
>  
>    Filename:   Round_Corner_Button.cc
>  
>    Date:       2023-03-21
>  
>    Author:     Mervyn Bick
>  
>    
>    Description: Round_Corner_Button is a pushbutton based on an idea
>                           (and code) "borrowed" from  Marc van den Berghen's
>                                                         article "The Form Factory" in issue 21 of the dBulletin.
>                                                         https://www.jpmartel.com/bulletin.htm
>                                                         
>                                                         The custom control should be used on a form where
>                                                         the metric property is set to pixels.
>                                                         
>                                                         In the designer the pushbutton will present as a square.
>                                                         Resize as appropriate keeping the height and width about
>                                                         the same.  When the form opens the pushbutton will set its
>                                                         width to match the height.  This ensures any text remains
>                                                         centered.
>                                                         
>                                                         If it is necessary to assign an event handler to the onOpen
>                      event the onOpen event in the custom class must be executed
>                      before any other code.
>                                                         
>                                                          function ROUNDBUTTON1_onOpen()
>                                                                 roundbutton::onOpen()
>                         // Other code                        
>                                                                 return
>                        
>                        
>                       In theory,   CreateRoundRectRgn() from the Windows32 API
>                       should create the required shape.  This function allows the
>                       rounding of the corners to be set as required.  Unfortunately
>                       I have not managed to implement this (yet) so I've used
>                       CreateEllipticRgn() combined with a dBASE shape object.   The
>                       dBASE shape object does not allow the rounding of the corners
>                       to be adjusted.
>  
>  */
>
> class Round_Corner_Button( parentObj ) of PushButton( parentObj ) custom
>    with (this)
>       onOpen = class::ONOPEN
>       metric = 6        // Pixels
>       height = 65.0
>       width = 65.0
>       fontsize = 15
>       text = 'PB'
>       systemtheme := false
>    endwith
>
>   function onopen
>            local hrgn1
>                 if this.width <> this.height
>                    this.width = this.height
>       endif        
>             if type("SetWindowRgn") # "FP"        
>                         extern CINT SetWindowRgn(CHANDLE, CHANDLE, CLOGICAL) user32
>            endif
>                 if type("CreateRoundRectRgn") # "FP"
>                         extern chandle  CreateRoundRectRgn(cint,cint,cint,cint,cint,cint) gdi32
>                 endif
>       if type("CreateEllipticRgn") # "FP"
>                         extern chandle  CreateEllipticRgn(cint,cint,cint,cint) gdi32
>                 endif
>       x1 = this.left
>       y1 = this.top
>       x2 = this.left+this.width
>       y2 = this.top+this.height
> //           hrgn1=CreateRoundRectRgn(x1,y1,x2,y2,1,1)
>            hrgn1=CreateEllipticRgn(this.width-5,5,5,this.width-5)
>       setwindowrgn(this.hwnd,hrgn1,true)
>       class::addring()
>    return
>         
>         function addRing
>       this.outline = new shape(this.parent)
>       this.outline.shapestyle := 4
>       this.outline.colorNormal := this.colorNormal
>       this.outline.top = this.top
>       this.outline.left = this.left
>       this.outline.width = this.width
>       this.outline.height = this.height
>       this.outline.penwidth := 1
>         return
>         
> endclassclear
> ** END HEADER -- do not remove this line
> //
> // Generated on 2023-03-21
> //
> parameter bModal
> local f
> f = new test_round_corner_buttonForm()
> if (bModal)
>    f.mdi = false // ensure not MDI
>    f.readModal()
> else
>    f.open()
> endif
>
> class test_round_corner_buttonForm of FORM
>    set procedure to round_corner_button.cc additive
>    with (this)
>       metric = 6        // Pixels
>       height = 499.0
>       left = 115.0
>       top = 5.0
>       width = 570.0
>       text = "Test round corner buttons"
>       systemTheme = true
>    endwith
>
>    this.ROUND_CORNER_BUTTON1 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON1)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 276.0
>       top = 58.0
>       width = 65.0
>       text = "1"
>    endwith
>
>    this.ROUND_CORNER_BUTTON2 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON2)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 353.0
>       top = 58.0
>       width = 65.0
>       text = "2"
>    endwith
>
>    this.ROUND_CORNER_BUTTON3 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON3)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 430.0
>       top = 58.0
>       width = 65.0
>       text = "3"
>    endwith
>
>    this.ROUND_CORNER_BUTTON4 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON4)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 276.0
>       top = 131.0
>       width = 65.0
>       text = "4"
>    endwith
>
>    this.ROUND_CORNER_BUTTON5 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON5)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 353.0
>       top = 131.0
>       width = 65.0
>       text = "5"
>    endwith
>
>    this.ROUND_CORNER_BUTTON6 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON6)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 430.0
>       top = 131.0
>       width = 65.0
>       text = "6"
>    endwith
>
>    this.ROUND_CORNER_BUTTON7 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON7)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 276.0
>       top = 204.0
>       width = 65.0
>       text = "7"
>    endwith
>
>    this.ROUND_CORNER_BUTTON8 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON8)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 353.0
>       top = 204.0
>       width = 65.0
>       text = "8"
>    endwith
>
>    this.ROUND_CORNER_BUTTON9 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON9)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 430.0
>       top = 204.0
>       width = 65.0
>       text = "9"
>    endwith
>
>    this.ROUND_CORNER_BUTTON10 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON10)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 276.0
>       top = 278.0
>       width = 65.0
>       text = "X"
>    endwith
>
>    this.ROUND_CORNER_BUTTON11 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON11)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 353.0
>       top = 278.0
>       width = 65.0
>       text = "0"
>    endwith
>
>    this.ROUND_CORNER_BUTTON12 = new ROUND_CORNER_BUTTON(this)
>    with (this.ROUND_CORNER_BUTTON12)
>       onClick = class::ROUND_CORNER_BUTTON_ONCLICK
>       height = 65.0
>       left = 430.0
>       top = 278.0
>       width = 65.0
>       text = "Enter"
>       colorNormal = "BtnText/0x966ff2"
>    endwith
>
>
>    function ROUND_CORNER_BUTTON_onClick()
>       ? this.text+' clicked'
>       return
>
> endclass
>