Subject Re: USE of ENTER KEY
From Mervyn Bick <invalid@invalid.invalid>
Date Tue, 21 Feb 2017 16:09:18 +0200
Newsgroups dbase.getting-started
Attachment(s) test_grid_callback.wfm

On 2017-02-21 8:53 AM, Mustansir Ghor wrote:
> Hello Everyone
>
> In a grid which event will be fired on pressing the "ENTER" key

If you open a form with a grid in the designer and select the grid you
will be able to see all the events in the Inspector.  Most of the events
are triggered by mouse clicks.

A grid does not have key and onKey events which can be used to test for
the Enter key for an entryfield. The grid's only event that is triggered
by the Enter key is the onSelChange event.

Pressing the Enter key when a grid has focus moves the cursor to the
next field in the selected row.  When the Enter key is pressed while the
cursor is on the last field in the row focus moves to the first field in
the next row.  Each time the Enter key is pressed the onSelChange event
fires.  Unfortunately the onSelChange also fires if the user clicks on
an unselected cell and there is no easy way to tell if the event fired
because the Enter key was pressed, if the Tab key was pressed or if the
mouse was clicked.

It needs a bit of coding but there is a way to trap for the Enter key
(actually any key) in a grid if you are using dBASE 8 or higher.  Using
the CALLBACK command you can install a keyboard hook which allows you to
see all the keyboard input to the grid.

A little example is attached.  Pressing the Tab key will move the
selected cell and the onSelChange event will fire.  Clicking on an
unselected cell will fire the onSelChange event.  Pressing the Enter key
will trigger the onSelChange event but it will also be trapped by the
keyboard hook.

Keyboard hooks are a powerful tool for dBASE programmers.  One can even
use them to "swallow" keystrokes so that they never get passed on tho
Windows for action.

Mervyn.




if file('test_grid_callback.dbf')
   // drop table test_grid_callback
endif

if not file('test_grid_callback.dbf')
   create table test_grid_callback (id autoinc,job_no character(5),customer character(15),address1 character(15),address2 character(15),address3 character(15),;
     description character(50),complete boolean)
    
   use test_grid_callback
   generate 200
   go top
   for n = 1 to 200
       replace job_no with '1'+str(N,3,0,'0')  
       SKIP
   next
   go top
   replace customer  with 'Abel'
   SKIP
   replace customer  with 'Baker'
   SKIP
   replace customer  with 'Charlie'
   SKIP
   replace customer  with 'Delta'
   SKIP
   replace customer  with 'Echo'
   SKIP
        
   use  

endif
clear
** END HEADER -- do not remove this line
//
// Generated on 2017-02-21
//
parameter bModal
local f
f = new test_rid_callbackForm()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class test_rid_callbackForm of FORM
   with (this)
      canClose = class::FORM_CANCLOSE
      onOpen = class::FORM_ONOPEN
      height = 31.6818
      left = 39.8571
      top = 2.5
      width = 134.8571
      text = ""
      scrollBar = 2        // Auto
   endwith

   this.TEST_GRID_CALLBACK1 = new QUERY(this)
   with (this.TEST_GRID_CALLBACK1)
      left = 2.0
      top = 1.0
      sql = 'select * from "test_grid_callback.DBF"'
      active = true
   endwith

   this.GRID1 = new GRID(this)
   with (this.GRID1)
      onSelChange = class::GRID1_ONSELCHANGE
      dataLink = form.test_grid_callback1.rowset
      height = 22.5
      left = 12.0
      top = 6.0
      width = 103.0
   endwith

   this.rowset = this.test_grid_callback1.rowset

   function form_onOpen()
   clear
      #include winuser.h
      if type("dBGetCurrentThreadId") # "FP"
         extern CULONG dBGetCurrentThreadId() kernel32 from "GetCurrentThreadId"
      endif
      if type("dBGetWindowLong") # "FP"
         extern CLONG dBGetWindowLong(CHANDLE, CINT) user32 from "GetWindowLongW"
      endif
      if type("dBSetWindowsHookEx") # "FP"
         extern CLONG dBSetWindowsHookEx(CINT, CPTR, CHANDLE, CULONG) user32 from "SetWindowsHookExW"
      endif
      if type("dBUnhookWindowsHookEx") # "FP"
         extern CLOGICAL dBUnhookWindowsHookEx(CHANDLE) user32 from "UnhookWindowsHookEx"
      endif
      if type("dBCallNextHookEx") # "FP"
         extern CLONG dBCallNextHookEx(CHANDLE, CINT, CUINT, CUINT) user32 from "CallNextHookEx"
      endif
                CALLBACK CLONG hookWndProc(CINT, CUINT, CUINT) OBJECT this
      this.hookProc = GetCallAddress(class::HOOKWNDPROC)
      this.hInst = dBGetWindowLong(this.hwnd, GWL_HINSTANCE)
      this.hook = dBSetWindowsHookEx(WH_KEYBOARD, this.hookProc, this.hInst, dBGetCurrentThreadId())
      form.grid1.setFocus()
      return
        

   function GRID1_onSelChange()
      ? 'grid1 onSelChange'
      return

   function form_canClose
      dBUnhookWindowsHookEx(this.hook)
      return true



   function hookWndproc(hCode, wParam, lParam)
      if wParam = VK_RETURN and hcode = 0 and not bitset(lparam,31)
         if upper(form.activeControl.name) = 'GRID1'      
            ? form.activeControl.name + '  Enter pressed'
         endif
      endif
     return dBCallNextHookEx(this.hook, hCode, wParam, lParam)


endclass