Monday, May 6, 2013

ActiveX DTPicker (MSComCtl2.DTPicker.2) on a grid, how to...


I created a post in Weblogs in 2009 on how to use the ActiveX DateTime Picker (MSComCtl2.DTPicker.2) on a grid where in addition to the instructions, I shared a sample form to show how it can be done.  But that sample form was now lost in Weblogs and while the instructions there are clear, I failed to include some more steps on the further adjustments I did the day after said blog was posted.  And so when a foxite forum member sought assistance in "taming" that elusive ActiveX DTPicker inside the grid and I pointed to my Weblogs article on that, there are missing steps.

Worse, I myself forgot exactly how I have done that last time because I forgot to save a copy of the sample form I shared before.  Not to mention I actually do not use that activex DTPicker and only has done that blog last time out of curiosity.

Anyway, since I became curious again on how I did that last time plus maybe some may need it again, I experimented again on that problem and got it working again, LOL.  So I am recreating the steps needed to make it work in a grid in this blog.

Instructions on creating a sample form:

Create an empty form, on its load event, paste these:

Create Cursor junk (xdate Date, xSelect l)
For lnloop = 1 To 10
      Insert Into junk Values (Date()+m.lnloop,.F.)
Next
GO TOP


* Drag a grid on the form, make ColumnCount = 1

* Ctrl-click on Column 1 then click the activex control (olecontrol) then click back on the grid

* Choose Microsoft Date and Time Picker 6, click OK

* Adjust row height so DTPicker can fit properly

* Navigate to that datepicker object and change its Visible property to .F.  We need to make it invisible because if you don't, the first run of the form will show said object somewhere inside the grid but not exactly on the column it is bound to.  Plus we don't need to see it yet.  We will toggle visibility later

* Now, on the column where we placed that activex object, there will be two controls, i.e., Text1 (default) and OleControl1 (activex dtpicker).  Leave the CurrentControl to the textbox (text1) because without it, you won't see the dates.  This activex DTPicker has a very nasty habit of blanking the entire column so it can show itself on the active cell. So we need Text1 to show the dates on inactive cells and the DTPicker on active cell.

* Set that column's Sparse property to .F.


Okay the first steps are completed, now we need to manipulate via codes:

* On grid init event, set the DynamicCurrentControl property:
this.column1.DynamicCurrentControl="IIF(xselect,'olecontrol1','text1')"


Notice that we are using xSelect logical field of the cursor junk.  That is the missing condition I have done last time to make this "taming" work properly.  The trick is when we click on a cell, we should turn it's value to .T. so it can show the DTPicker.  And when the DTPicker looses focus, we should replace its value back to .F.

* On Text1's Click Event, put these codes:
* Update DTPicker with the cell's date value
With This.Parent.olecontrol1
      .Year = Year(junk.xdate)
      .Month = Month(junk.xdate)
      .Day = Day(junk.xdate)
Endwith

This.Parent.CurrentControl = 'olecontrol1'
This.Parent.olecontrol1.Visible = .T.
Replace xselect With .T.  In junk


* on DTPicker's LostFocus event:
this.Parent.CurrentControl = 'text1'
this.Visible = .F.
REPLACE xselect WITH .f. IN junk
* also replace your date field with the value of this DTPicker




And that is it!  I hope this is clearer and more complete this time.  Cheers!

7 comments:

  1. Hey Jun,
    This is great man, i just follow your instructions and i got it, VERY NICE...
    Ernesto

    ReplyDelete
  2. Hey Jun,
    What about if set up column count =2, then i will create another header2, will i will change the caption to Today is, so i want to display there like "Friday", so i meant if the date in the grid just before and open the calendar, i would like the seond column to display the today's date like "Friday" and so on for each row displayed, how to do that ?
    Ernesto

    ReplyDelete
  3. Jun,
    What i was trying to accomplish i got with this in the load event:
    Create Cursor junk (xdate Date,xSelect l,Tos c(10))
    For lnloop = 0 To 30 && i extended for 30 days
    Insert Into junk Values (Date()+m.lnloop,.F.,CDOW(DATE()+m.lnloop))
    Next
    GO TOP

    Ernesto

    ReplyDelete
    Replies
    1. Hey great! Glad you made it working, I read late, LOL!

      Delete
  4. Thank you for a wonderfully clear and practical implementation instruction for DatePicker control in a VFP Grid! Very much appreciated!!

    ReplyDelete