Subject Select multiple records in a grid
From Mervyn Bick <invalid@invalid.invald>
Date Wed, 19 Sep 2018 22:40:24 +0200
Newsgroups dbase.getting-started
Attachment(s) test_multigridselect.wfm

On 2018-09-19 6:31 PM, Kinsley wrote:
> OK perhaps I need to ask a different question. If I want to allow a user to select multiple rows in a grid without having to add a new field to a dbfile how do I go about it? What is the best solution for this? I'm no expert in DBase coding so the simpler the solution the better if I am honest.

Normally all one needs to do is set the grid's multiselect property true
and then hold down the control key while clicking on a record in the grid.

A problem is that the top record is always selected when the grid opens.
  If the user doesn't want to include this record in the selection it
has to be deliberately de-selected by holding down the control key and
then clicking on the record.

The attached example emulates holding down the control key and clicking
on the first record to de-select it when the grid opens.  The user can
then select the required records.

If you uncomment the code in the onMouseOver and onMouseOut event
handlers the user need not use the control key to select multiple
records.  This is, however, not standard practice so it may not be a
good idea.  Up to you.


if file('test_multiselect.dbf')
   // drop table test_multiselect

if not file('test_multiselect.dbf')
   create table test_multiselect (id autoinc,data character(10))

   use test_multiselect
   generate 10


** END HEADER -- do not remove this line
// Generated on 2014/02/18
parameter bModal
local f
f = new test_multigridselectForm()
if (bModal)
   f.mdi = false // ensure not MDI

class test_multigridselectForm of FORM
   with (this)
      onOpen = class::FORM_ONOPEN
      onClose = class::FORM_ONCLOSE
      height = 18.9091
      left = 68.4286
      top = 1.5909
      width = 45.5714
      text = ""

   this.CHILDTEST1 = new QUERY()
   this.CHILDTEST1.parent = this
   with (this.CHILDTEST1)
      left = -0.2857
      top = 0.0455
      sql = 'select * from "test_multiselect.DBF"'
      active = true

   this.GRID1 = new GRID(this)
   with (this.GRID1)
      onOpen = class::GRID1_ONOPEN
      onMouseOver = class::GRID1_ONMOUSEOVER
      onMouseOut = class::GRID1_ONMOUSEOUT
      dataLink = form.childtest1.rowset
      multiSelect = true
      height = 10.6364
      left = 4.0
      top = 2.8636
      width = 36.5714

   this.PUSHBUTTON1 = new PUSHBUTTON(this)
   with (this.PUSHBUTTON1)
      onClick = class::PUSHBUTTON1_ONCLICK
      height = 1.7727
      left = 15.1429
      top = 14.9545
      width = 15.2857
      text = "Clear selection"

   this.TEXTLABEL1 = new TEXTLABEL(this)
   with (this.TEXTLABEL1)
      height = 1.0
      left = 16.1429
      top = 0.8636
      width = 12.2857
      text = "Select records"

   this.rowset = this.childtest1.rowset

   function GRID1_onMouseOut(flags, col, row)
//      class::setcontrolkey(0,1)   //release control key

   function GRID1_onMouseOver(flags, col, row)
//      class::setcontrolkey(1,0)   //hold down contol key

   function GRID1_onOpen

   function PUSHBUTTON1_onClick
      local aGrid
      aGrid = new array()
      aGrid = form.grid1.selected()
      for n = 1 to aGrid.size

   function form_onClose
      class::setcontrolkey(0,1)   //make quite sure control key is released

   function form_onOpen
      #include winuser.h
      if type("SendMessage") # "FP"
          extern clong SendMessage(chandle,cuint,clong,clong) user32 ;
                from "SendMessageA"
      if type("GetKeyboardState") # "FP"
         extern CVOID GetKeyboardState(CPTR) User32
      if type("SetKeyboardState") # "FP"
         extern CVOID SetKeyboardState(CPTR) User32

   function setcontrolkey(onoff,nstate)
      local keybuffer,state
      keybuffer = Space(256)
      If onoff # 0              
      return state

   function deselectEntry
      local point