Subject Re: WIN 11 Borderless Buttons with Rounded Corners
From Mervyn Bick <invalid@invalid.invalid>
Date Thu, 23 Mar 2023 17:05:30 +0200
Newsgroups dbase.getting-started
Attachment(s) Round_corner_button1.cctest_round_corner_button1.wfm

On 2023/03/21 23:55, Michael wrote:
> 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.

This is getting to be more like the shape you want but unfortunately the
pushbutton doesn't have a border.  I have, therefore, changed the
background colour to make the extent of the button visible.

The next step is to see if I can add a border but this may be more of a
challenge.

A revised test form and the custom component file are attached.

I'd appreciate seeing what you come up with.  My email address is
bickmeo at gmail dot com

Mervyn.


/*

   Filename:   Round_Corner_Button1.cc

   Date:       2023-03-21

   Author:     Mervyn Bick

   Revision:   1  Instead of using a dBASE shape object, the function
                    CreateRoundRectRgn() from the Windows32 API is used
                    to creat the region.  This gives control over the rounding
                    of the corners but does not allow for a border.
  
  
   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
                      
*/

class Round_Corner_Button1( parentObj ) of PushButton( parentObj ) custom
   with (this)
      onOpen = class::ONOPEN
      metric = 6        // Pixels
      height = 65.0
      width = 65.0
      text = 'PB'
      fontsize = 15
      systemtheme := false
      colorNormal = "0x40/0xeaeaea"
   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
      z = 30 // rounding for corners
      nFudge = 2  //hide edges in new region      
      x1 = 0
      y1 = 0
      x2 = this.width  
      y2 = this.height
           hrgn1=CreateRoundRectRgn(x1+nFudge,y1+nFudge,y2-nFudge,y2-nFudge,z,z)
      setwindowrgn(this.hwnd,hrgn1,true)
      this.top = this.top
      this.left = this.left
   return

endclass

clear
** END HEADER -- do not remove this line
//
// Generated on 2023-03-23
//
parameter bModal
local f
f = new test_round_corner_button1Form()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class test_round_corner_button1Form of FORM
   set procedure to round_corner_button1.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_BUTTON1(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"
      borderStyle = 3        // None
   endwith

   this.ROUND_CORNER_BUTTON2 = new ROUND_CORNER_BUTTON1(this)
   with (this.ROUND_CORNER_BUTTON2)
      onClick = class::ROUND_CORNER_BUTTON_ONCLICK
      height = 65.0
      left = 341.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 = 406.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 = 122.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 = 341.0
      top = 122.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 = 406.0
      top = 122.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 = 187.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 = 341.0
      top = 187.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 = 406.0
      top = 187.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 = 252.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 = 341.0
      top = 252.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 = 406.0
      top = 252.0
      width = 65.0
      text = "Enter"
      colorNormal = "BtnText/0x966ff2"
   endwith


   function ROUND_CORNER_BUTTON_onClick()
      ? this.text+' clicked'
      return

endclass