Subject Re: Datepicker for Date field
From Mervyn Bick <invalid@invalid.invalid>
Date Tue, 4 Jan 2022 19:50:45 +0200
Newsgroups dbase.getting-started
Attachment(s) date_picker_grid.wfm

On 2022/01/02 18:19, Milind Nighojkar wrote:
> Can we open datepicker on say leftdblclick on a date field in a grid?
> Regards
> Milind Nighojkar

A DateTimePicker is unfortunately not one of the possible controls that
can be set as the editor control for a column in a grid.  One can,
however, make it look as if it's possible. :-)


The attached example uses a hidden DateTimePicker for each column of
dates in the grid.  A LeftDblClick on a cell holding a date places the
appropriate DatetimPicker over the cell and makes it visible.

Mervyn.


clear
** END HEADER -- do not remove this line
//
// Generated on 2022-01-04
//
parameter bModal
local f
f = new date_picker_gridForm()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class date_picker_gridForm of FORM
   with (this)
      onOpen = class::FORM_ONOPEN
      metric = 6        // Pixels
      height = 411.0
      left = 270.0
      top = 42.0
      width = 619.0
      text = ""
   endwith

   this.DBASESAMPLES1 = new DATABASE(this)
   with (this.DBASESAMPLES1)
      left = 46.0
      width = 78.0
      height = 37.0
      databaseName = "DBASESAMPLES"
      active = true
   endwith

   this.ORDERS1 = new QUERY(this)
   with (this.ORDERS1)
      width = 45.0
      height = 37.0
      database = form.dbasesamples1
      sql = "select * from ORDERS.DBF"
      active = true
   endwith

   with (this.ORDERS1.rowset)
      onNavigate = class::ROWSET_ONNAVIGATE
   endwith

   this.GRID1 = new GRID(this)
   with (this.GRID1)
      dataLink = form.orders1.rowset
      columns["COLUMN1"] = new GRIDCOLUMN(form.GRID1)
      with (columns["COLUMN1"])
         dataLink = form.orders1.rowset.fields["orderid"]
         editorType = 1        // EntryField
         width = 110.0
      endwith
      columns["COLUMN2"] = new GRIDCOLUMN(form.GRID1)
      with (columns["COLUMN2"])
         dataLink = form.orders1.rowset.fields["customerid"]
         editorType = 3        // SpinBox
         width = 130.0
      endwith
      columns["COLUMN3"] = new GRIDCOLUMN(form.GRID1)
      with (columns["COLUMN3"])
         dataLink = form.orders1.rowset.fields["orderdate"]
         editorType = 3        // SpinBox
         width = 120.0
      endwith
      columns["COLUMN4"] = new GRIDCOLUMN(form.GRID1)
      with (columns["COLUMN4"])
         dataLink = form.orders1.rowset.fields["employeeid"]
         editorType = 3        // SpinBox
         width = 130.0
      endwith
      columns["COLUMN5"] = new GRIDCOLUMN(form.GRID1)
      with (columns["COLUMN5"])
         dataLink = form.orders1.rowset.fields["shipdate"]
         editorType = 3        // SpinBox
         width = 120.0
      endwith
      with (columns["COLUMN1"].headingControl)
         value = "OrderID"
      endwith

      with (columns["COLUMN2"].editorControl)
         rangeMax = 100
         rangeMin = 1
      endwith

      with (columns["COLUMN2"].headingControl)
         value = "CustomerID"
      endwith

      with (columns["COLUMN3"].editorControl)
         onLeftDblClick = class::EDITORCONTROL_ONLEFTDBLCLICK
         rangeMax = {2001-03-10}
         rangeMin = {2000-11-30}
      endwith

      with (columns["COLUMN3"].headingControl)
         value = "OrderDate"
      endwith

      with (columns["COLUMN4"].editorControl)
         rangeMax = 100
         rangeMin = 1
      endwith

      with (columns["COLUMN4"].headingControl)
         value = "EmployeeID"
      endwith

      with (columns["COLUMN5"].editorControl)
         onLeftDblClick = class::EDITORCONTROL_ONLEFTDBLCLICK1
         rangeMax = {2001-02-05}
         rangeMin = {2000-10-28}
      endwith

      with (columns["COLUMN5"].headingControl)
         value = "ShipDate"
      endwith

      headingHeight = 22.0
      cellHeight = 22.0
      height = 212.0
      left = 35.0
      top = 160.0
      width = 516.0
   endwith

   this.DATETIMEPICKER1 = new DATETIMEPICKER(this)
   with (this.DATETIMEPICKER1)
      visible = false
      height = 22.0
      left = 173.0
      top = 1.0
      width = 122.0
      dataLink = form.orders1.rowset.fields["orderdate"]
      format = 2        // Short Date with Century
   endwith

   with (this.DATETIMEPICKER1.dropDown)
      showTodayDate = false
   endwith

   this.TEXT1 = new TEXT(this)
   with (this.TEXT1)
      height = 22.0
      left = 79.0
      top = 48.0
      width = 593.0
      text = "Click on cell in a date column then Left Double Click on the celll to show Date Picker"
   endwith

   this.DATETIMEPICKER2 = new DATETIMEPICKER(this)
   with (this.DATETIMEPICKER2)
      visible = false
      height = 22.0
      left = 314.0
      top = 1.0
      width = 122.0
      dataLink = form.orders1.rowset.fields["shipdate"]
      format = 2        // Short Date with Century
   endwith

   with (this.DATETIMEPICKER2.dropDown)
      showTodayDate = false
   endwith

   this.RADIOBUTTON1 = new RADIOBUTTON(this)
   with (this.RADIOBUTTON1)
      height = 24.0
      left = 35.0
      top = 83.0
      width = 420.0
      text = "DateTimePicker calendar opens automatically."
      group = true
      value = true
   endwith

   this.RADIOBUTTON2 = new RADIOBUTTON(this)
   with (this.RADIOBUTTON2)
      height = 24.0
      left = 35.0
      top = 112.0
      width = 420.0
      text = "User to open DateTimePicker calendar manually."
   endwith

   this.rowset = this.orders1.rowset

   function editorControl_onLeftDblClick(flags, col, row)
      getcursorpos(form.point)  //form.point is position on screen
      cmd = 'nCol_width = form.grid1.columns["column'+form.grid1.currentcolumn+'"].width'
      &cmd
      form.datetimepicker1.width = nCol_width //set dattimepicker width to match width of selected date column
      nX_org_scr =  form.point.getx(form.point,0) //save screen coordinates for initial leftDblClick in date column
      nY_org_scr =  form.point.gety(form.point,4) //   "
      screentoclient(form.hwnd,form.point)  //form.point is now position in form
      nX_org_frm =  form.point.getx(form.point,0) //save form coordinates for initial leftDblClick in date column
      nY_org_frm =  form.point.gety(form.point,4) //   "
      form.colpoint.setx(form.grid1.left+30,0)  // set position in 1st coloumn on same row.  skip indicator column
      form.colpoint.sety(ny_org_frm)
      clienttoscreen(form.hwnd,form.colpoint)  //convert colpoint from form position to screen position
      nX_colpt = form.colpoint.getx(form.colpoint,0) //get screen coordinates for mouseclick
      ny_colpt = form.colpoint.gety(form.colpoint,4)
      form.rmMouse.screenLeftClick(nX_colpt,nY_colpt )  //click in left column in same row
      nCol = form.grid1.currentcolumn  //save column number of 1st column displayed
      setcursorpos(nX_org_scr,nY_org_scr) //set cursor back to where leftDblClick was made in date column
      form.rmMouse.screenLeftClick(nX_Org_scr,nY_org_scr )  //click in left column in same row
      nLeft = 25 //width of indicator column
      for n = nCol to form.grid1.currentcolumn - 1
           cmd = 'form.grid1.columns["column'+n+'"].width'
           nLeft += &cmd
      next
      form.datetimepicker1.left = nLeft + form.grid1.left      
      nRows =   int((form.point.gety(form.point,4)-form.grid1.top)/(form.grid1.cellheight+1))
      nTop = form.grid1.top
      nFudge = 2
      form.datetimepicker1.top = nTop+nFudge+((form.grid1.cellheight+1)*nrows)
      form.datetimepicker1.visible = true  
      //datetimepicker1 moved over selected cell and made visible
      
      if form.radiobutton1.value = true
         //set up form.colpoint to be over the datetimepicker drop-down button.
         //coordinates are set up using form values.  These coordinates then need
         //to be converted to the screen values which are required for setcursorpos()
         //and rmMouse.screenLeftClick()
         screentoclient(form.hwnd,form.colpoint)
         form.colpoint.setx(form.datetimepicker1.left+form.datetimepicker1.width-5) //set x coordinate almost to right hand end
         //nY is still pointing to the selected row.
         clienttoscreen(form.hwnd,form.colpoint)
         nX_drop_scr =  form.colpoint.getx(form.colpoint,0) //save screen coordinates for initial leftDblClick in date column
         nY_drop_scr =  form.colpoint.gety(form.colpoint,4) //   "
         setcursorpos(nX_drop_scr,nY_drop_scr)
         form.rmMouse.screenLeftClick(nX_drop_scr,nY_drop_scr )    
         endif
      return


   function editorControl_onLeftDblClick1(flags, col, row)
      getcursorpos(form.point)  //form.point is position on screen
      cmd = 'nCol_width = form.grid1.columns["column'+form.grid1.currentcolumn+'"].width'
      &cmd
      form.datetimepicker2.width = nCol_width //set dattimepicker width to match width of selected date column
      nX_org_scr =  form.point.getx(form.point,0) //save screen coordinates for initial leftDblClick in date column
      nY_org_scr =  form.point.gety(form.point,4) //   "
      screentoclient(form.hwnd,form.point)  //form.point is now position in form
      nX_org_frm =  form.point.getx(form.point,0) //save form coordinates for initial leftDblClick in date column
      nY_org_frm =  form.point.gety(form.point,4) //   "
      form.colpoint.setx(form.grid1.left+30,0)  // set position in 1st coloumn on same row.  skip indicator column
      form.colpoint.sety(ny_org_frm)
      clienttoscreen(form.hwnd,form.colpoint)  //convert colpoint from form position to screen position
      nX_colpt = form.colpoint.getx(form.colpoint,0) //get screen coordinates for mouseclick
      ny_colpt = form.colpoint.gety(form.colpoint,4)
      form.rmMouse.screenLeftClick(nX_colpt,nY_colpt )  //click in left column in same row
      nCol = form.grid1.currentcolumn  //save column number of 1st column displayed
      setcursorpos(nX_org_scr,nY_org_scr) //set cursor back to where leftDblClick was made in date column
      form.rmMouse.screenLeftClick(nX_Org_scr,nY_org_scr )  //click in left column in same row
      nLeft = 25 //width of indicator column
      for n = nCol to form.grid1.currentcolumn - 1
           cmd = 'form.grid1.columns["column'+n+'"].width'
           nLeft += &cmd
      next
      form.datetimepicker2.left = nLeft + form.grid1.left      
      nRows =   int((form.point.gety(form.point,4)-form.grid1.top)/(form.grid1.cellheight+1))
      nTop = form.grid1.top
      nFudge = 2
      form.datetimepicker2.top = nTop+nFudge+((form.grid1.cellheight+1)*nrows)
      form.datetimepicker2.visible = true  
      //datetimepicker2 moved over selected cell and made visible
      
      if form.radiobutton1.value = true
         //set up form.colpoint to be over the datetimepicker drop-down button.
         //coordinates are set up using form values.  These coordinates then need
         //to be converted to the screen values which are required for setcursorpos()
         //and rmMouse.screenLeftClick()
         screentoclient(form.hwnd,form.colpoint)
         form.colpoint.setx(form.datetimepicker2.left+form.datetimepicker2.width-5) //set x coordinate almost to right hand end
         //nY is still pointing to the selected row.
         clienttoscreen(form.hwnd,form.colpoint)
         nX_drop_scr =  form.colpoint.getx(form.colpoint,0) //save screen coordinates for initial leftDblClick in date column
         nY_drop_scr =  form.colpoint.gety(form.colpoint,4) //   "
         setcursorpos(nX_drop_scr,nY_drop_scr)
         form.rmMouse.screenLeftClick(nX_drop_scr,nY_drop_scr )    
         endif      return

   function rowset_onNavigate(type, nRows)
      this.parent.parent.datetimepicker1.visible = false
      this.parent.parent.datetimepicker2.visible = false
      return

   function form_onOpen
      set procedure to :duflp:rmMouseevents.cc
      form.rmMouse = new rmMouseevents(form)
      if type("GetCursorPos") # "FP"
         extern CLOGICAL GetCursorPos(CPTR) user32
      endif
      if type("SetCursorPos") # "FP"
         extern CLOGICAL SetCursorPos(CINT,CINT) user32
      endif
      if type("ScreenToClient") # "FP"
          extern clogical ScreenToClient(chandle,cptr) user32
      endif
      if type("ClientToScreen") # "FP"
          extern clogical ClientToScreen(chandle,cptr) user32
      endif
      form.point =  new point()
      form.colpoint = new point()

      return
      

endclass