Subject Re: pushbutton
From Mervyn Bick <invalid@invalid.invalid>
Date Wed, 30 Nov 2022 10:15:30 +0200
Newsgroups dbase.getting-started

On 2022/11/28 20:42, Mustansir Ghor wrote:
> Dear All
> When Pushputton gets focus in dbase 2019, I need to press Enter button twice to execute the push button whereas same form if I run in dbase 11 plus the pushbutton executes with focus on it by pressing it only once.
> If anybody has any clue where I need to correct pls advice me.

This is a bug that first appeared in dBASE 12 and has continued on into
dBASE 2019.

I have created a custom pushbutton ( that uses the
CALLBACK command to trap when the user presses the Enter key while the
pushbutton has focus.  This immediately triggers the pushbutton's
onClick event.

Ken, you may want to consider this control for inclusion in the dUFLP.

An example form and the custom control are attached.


** END HEADER -- do not remove this line
// Generated on 2022-11-30
parameter bModal
local f
f = new ghor_mbForm()
if (bModal)
   f.mdi = false // ensure not MDI

class ghor_mbForm of FORM
   set procedure to additive
   with (this)
      onOpen = class::FORM_ONOPEN
      metric = 0        // Chars
      height = 8.5455
      left = -3.4286
      top = 1.3182
      width = 122.2857
      text = ""

   this.CBCUSTOMER = new COMBOBOX(this)
   with (this.CBCUSTOMER)
      height = 1.5
      left = 6.0
      top = 3.5
      width = 39.0
      fontSize = 14.0
      dataSource = 'array {"MUSTANSIR","GHOR","DAR","TZ"}'
      style = 1        // DropDown

   this.EAMOUNT = new ENTRYFIELD(this)
   with (this.EAMOUNT)
      height = 1.5
      left = 51.0
      top = 3.5
      width = 18.0
      fontSize = 14.0
      value = ""
      validRequired = true

   this.PBSAVE = new PB_ONE_PRESS(this)
   with (this.PBSAVE)
      onClick = class::PBSAVE_ONCLICK
      height = 1.5
      left = 77.0
      top = 3.5
      width = 14.0
      text = "Display It"

   this.TEXT1 = new TEXT(this)
   with (this.TEXT1)
      height = 1.0
      left = 7.0
      top = 6.0
      width = 54.0
      text = "Text1"

   function PBSAVE_onClick()
         form.text1.text=form.cbcustomer.value+" has following balance "+form.eamount.value

   function form_onOpen()
          height = 8.5
     left = 20.0
     top = 3.0
     width = 120.0


class pb_one_press(parentObj) of pushbutton(parentObj) custom



   Date:       2022-11-30

   Author:     Mervyn Bick



      Starting with dBASE 12 and continuing in dBASE 2019, if a user Tabs
                to a pushbutton control it takes two presses of the Enter key to trigger
                the pushbutton's onClick event.   If the user uses the mouse to click on
                the pushbutton the onClick event fires immediately.
                This custom pushbutton triggers the object's onClick event immediately
                if the user tabs to the control and then preses the Enter key.  
                The custom control works without a problem in dBASE 11 so there should
                be no adverse effects if this bug is ever fixed for dBASE 2019.

      This custom control will only work with dBASE Plus 8 and later as the
      CALLBACK feature in not avaiable in earlier versions of dBASE.

   with (this)
      onOpen = CLASS::onOpen
      onClose = CLASS::onClose

   function onOpen()
      #include winuser.h
      if type("GetWindowLongA") # "FP"
         extern CLONG GetWindowLongA(CHANDLE, CINT) user32
      if type("SetWindowLongA") # "FP"
         extern CLONG SetWindowLongA(CHANDLE, CINT, CLONG) user32
      if type("CallWindowProcA") # "FP"
         extern CLONG CallWindowProcA(CPTR, CHANDLE, CUINT, CUINT, CUINT) user32
           if type("this.oldproc") = 'U'
                        this.oldproc = GetWindowLongA(this.hwnd, GWL_WNDPROC)
                        CALLBACK CLONG wndproc(CHANDLE, CUINT, CUINT, CUINT) OBJECT this
                        this.newproc = GetCallAddress(class::wndproc)
                        SetWindowLongA(this.hwnd, GWL_WNDPROC, this.newproc)

   function onClose
      if type("this.oldproc") = "FP"
         if this.oldproc <> null and not empty(this.oldproc)
         // must restore original window procedure for pushbutton
         SetWindowLongA(this.hwnd, GWL_WNDPROC, this.oldproc)      
         RELEASE CALLBACK wndproc OBJECT this

   function wndproc(hwnd,umsg,wparam,lparam)
                  if umsg = WM_CHAR  and wParam = VK_RETURN
                     //Enter key pressed while object has focus
       return CallWindowProcA(this.oldproc, hwnd, uMsg, wParam, lParam)