Announcement

Collapse
No announcement yet.

how to detect when a date selected from date time picker / calendar dialog box object

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • how to detect when a date selected from date time picker / calendar dialog box object

    I have a DDT dialog box created with power basic forms 1.51. There is a date time picker object in the dialog box to allow the user to select the date. I am able to extract the selected date, but I cannot figure out how to determine when the user has made a date selection (because when they make a date selection, I want to gray out other options in the dialog box, etc.). Any advice?

    I used the following statement to add the date time picker to the dialog box:

    CONTROL ADD "SysDateTimePick32", hDlg, %IDC_SYSDATETIMEPICK32_1, "SysDateTimePick32_1", 335, 165, 115, 15, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %DTS_SHORTDATEFORMAT, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    I also have the following statement which adds a radio button to the dialog box. This radio button should be highlighted if the user selects a date from the date time picker. (I am trying to detect when the user selects a date so that I can automatically set this radio button to on.)

    CONTROL ADD OPTION, hDlg, %IDC_OPTION5, "Use Calendar For Input", 335, 151, 115, 15
    When my code detects that the user pressed the OK button on the dialog box, I am able to successfully store whatever date is set in the date time picker with the following statement. See how the %IDC_SYSDATETIMEPICK32_1 control identifier set in the CONTROL ADD "SysDateTimePick32" statement can be used to transfer the value to my variable.

    CONTROL GET TEXT CBHNDL, %IDC_SYSDATETIMEPICK32_1 TO SelectedDateVariable$
    However, when I try to use CASE %IDC_SYSDATETIMEPICK32_1 to detect a change to that field while processing control notifications, nothing happens. (See my callback function below.) It seems that the custom control SysDateTimePick32 is sending back a different type of notification, so I will not detect anything by looking for a notification on %IDC_SYSDATETIMEPICK32_1.

    What CASE block am I supposed to add under the CASE %WM_COMMAND block in the ShowDIALOG1Proc callback function in order to detect that a date was selected via the SysDateTimePick32 control?

    CALLBACK FUNCTION ShowDIALOG1Proc()
    LOCAL lRes AS LONG
    LOCAL MDNok,Daysok,Daysblankok,tempdays AS STRING

    SELECT CASE AS LONG CBMSG
    CASE %WM_INITDIALOG
    ' Initialization handler

    CASE %WM_NCACTIVATE
    STATIC hWndSaveFocus AS DWORD
    IF ISFALSE CBWPARAM THEN
    ' Save control focus
    hWndSaveFocus = GetFocus()
    ELSEIF hWndSaveFocus THEN
    ' Restore control focus
    SetFocus(hWndSaveFocus)
    hWndSaveFocus = 0
    END IF

    CASE %WM_COMMAND
    ' Process control notifications

    SELECT CASE AS LONG CBCTL


    ' if entry made in calender box, automatically select that radio button
    'PROBLEM: MAKING A SELECTION FROM THE DATE TIME PICKER DOES NOT INVOKE THIS CASE
    CASE %IDC_SYSDATETIMEPICK32_1
    CONTROL SET OPTION CBHNDL, %IDC_OPTION5, %IDC_OPTION1, %IDC_OPTION5

    ' [Remainer of Case statements for other dialog box objects removed from posted code for simplicity]

    END SELECT
    END SELECT
    END FUNCTION

  • #2
    The date time picker is a common control and uses %WM_NOTIFY

    here is an example

    Code:
    #PBFORMS CREATED V1.52
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other   
    ' PB/Forms metastatements are placed at the beginning and 
    ' end of "Named Blocks" of code that should be edited     
    ' with PBForms only. Do not manually edit or delete these 
    ' metastatements or PB/Forms will not be able to reread   
    ' the file correctly.  See the PB/Forms documentation for 
    ' more information.                                       
    ' Named blocks begin like this:    #PBFORMS BEGIN ...     
    ' Named blocks end like this:      #PBFORMS END ...       
    ' Other PB/Forms metastatements such as:                  
    '     #PBFORMS DECLARATIONS                               
    ' are used by PB/Forms to insert additional code.         
    ' Feel free to make changes anywhere else in the file.    
    '------------------------------------------------------------------------------
    
    #COMPILE EXE
    #DIM ALL
    
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES 
    %USEMACROS = 1
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #IF NOT %DEF(%COMMCTRL_INC)
        #INCLUDE "COMMCTRL.INC"
    #ENDIF
    #INCLUDE "PBForms.INC"
    #PBFORMS END INCLUDES
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS 
    %IDD_DIALOG1             =  101
    %IDC_SYSDATETIMEPICK32_1 = 1001
    %IDC_TEXTBOX1            = 1002
    #PBFORMS END CONSTANTS
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _
            %ICC_INTERNET_CLASSES)
    
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
      LOCAL pNMHDR AS NMHDR PTR  'For notifications
      local lTmp as long
      LOCAL WorkDate AS SystemTime
      
      SELECT CASE AS LONG CBMSG
        CASE %WM_INITDIALOG
            'Make the date not selected
            CONTROL SEND cbhndl, %IDC_SYSDATETIMEPICK32_1, %DTM_SETSYSTEMTIME, %GDT_NONE, 0
    
        CASE %WM_NCACTIVATE
            STATIC hWndSaveFocus AS DWORD
            IF ISFALSE CBWPARAM THEN
                ' Save control focus
                hWndSaveFocus = GetFocus()
            ELSEIF hWndSaveFocus THEN
                ' Restore control focus
                SetFocus(hWndSaveFocus)
                hWndSaveFocus = 0
            END IF
    
        CASE %WM_COMMAND
            ' Process control notifications
            SELECT CASE AS LONG CBCTL
                CASE %IDC_SYSDATETIMEPICK32_1
    
                CASE %IDC_TEXTBOX1
    
            END SELECT
    
        case %WM_NOTIFY
          pNMHDR = CBLPARAM
    
          SELECT CASE @pNMHDR.idFrom  'What common control sent the notification
            CASE %IDC_SYSDATETIMEPICK32_1 'Date time picker
              CONTROL SEND cbhndl, %IDC_SYSDATETIMEPICK32_1, %DTM_GETSYSTEMTIME, 0, VARPTR(WorkDate) TO lTmp
    
              if lTmp = %GDT_VALID then  'Valid date selected
                control DISABLE cbhndl, %IDC_TEXTBOX1
              else
                'Date not selected in date control
                control enable cbhndl, %IDC_TEXTBOX1
              end if
            end select
      END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Dialog1", 467, 190, 201, 121, %WS_POPUP OR _
            %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
        CONTROL ADD "SysDateTimePick32", hDlg, %IDC_SYSDATETIMEPICK32_1, _
            "SysDateTimePick32_1", 11, 10, 89, 15, %WS_CHILD OR %WS_VISIBLE OR _
            %WS_TABSTOP OR %DTS_SHOWNONE OR %DTS_SHORTDATEFORMAT, _
            %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR
        CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "Disabled when a date is " + _
            "selected", 11, 70, 173, 17
    #PBFORMS END DIALOG
    
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------

    Comment


    • #3
      The date picker control sends a number of notification messages having symbolic names beginning with "DTN_".

      Look 'em up. I guarantee you will find one which tells you the user has changed the date selection.

      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Thank you Carlo for the example. I incorporated your SELECT CASE block for %WM_NOTIFY into my code and it works great.

        The one oversight on my part was tabbing. My date picker control had the %WS_TABSTOP style (put there by default by the Power Basic Forms GUI builder) without the ON/OFF checkbox that you have in your example. So if someone was tabbing through my fields and tabbed to the date picker object on their way to some other object, the program would be notified that the date picker was invoked (even though the user did not do anything in that field) and the program would subsequently responded as if the user picked a date.

        It was simple enough for me to avoid this problem--I just removed the %WS_TABSTOP style so the user cannot tab to or through the date picker. They can only reach the date picker object via the mouse. If I needed my date picker to be reachable by tabbing, I would have incorporated your ON/OFF checkbox, which is a nice approach.

        Scott

        Comment


        • #5
          >The one oversight on my part was tabbing....

          No it wasn't. You just did not look at which .notification message the control generated when it gained the keyboard focus.

          Call me a purist but it's totally silly toremove the WS_TABSTOP style - IF you want it to be a tabstop - because your WM_NOTIFY code (conveniently not shown) is incomplete.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Michael,

            In my case, the oversight was not noticing the PB Forms assigned %WS_TABSTOP to this style, because my user interface is better if tabbing bypasses the date picker object. I just overlooked this issue, until I incorporated Carlos's code, which made the tabbing issue more obvious.

            Sorry I didn't post my WM_NOTIFY code. I took it directly from Carlos's reply with trivial modification. Here is my code. Out of curiosity, which notification message(s) should I be looking for if I wanted a different behavior than this code gives?

            case %WM_NOTIFY

            pNMHDR = CBLPARAM

            SELECT CASE @pNMHDR.idFrom 'What common control sent the notification
            CASE %IDC_SYSDATETIMEPICK32_1 'Date time picker
            CONTROL SEND cbhndl, %IDC_SYSDATETIMEPICK32_1, %DTM_GETSYSTEMTIME, 0, VARPTR(WorkDate) TO lTmp

            if lTmp = %GDT_VALID then 'Valid date selected

            CONTROL SET OPTION CBHNDL, RadioButtonGrp1(5), RadioButtonGrp1(1), RadioButtonGrp1(RadioButtonGrp1idx) ' set the radio button #5 on . This is the radio button next to the calendar date time picker

            CONTROL SET TEXT CBHNDL, %IDC_TEXTBOX3, "" ' clear any text from a text box which should be empty if the calendar is used

            else
            'Date not selected in date control
            end if
            end select
            Last edited by S Stamp; 15 Aug 2009, 07:16 PM.

            Comment


            • #7
              Code:
              SELECT CASE @pNMHDR.idFrom 'What common control sent the notification
                     CASE %IDC_SYSDATETIMEPICK32_1 'Date time picker
                     {stuff}
              This code assumes that every notification message sent by the control is the one you are interested in. If I have followed this problem correctly, you are interested only when you are told the user has changed the date.

              That being the case you need to add an additional test
              Code:
              SELECT CASE @pNMHDR.idFrom 'What common control sent the notification
                      CASE %IDC_SYSDATETIMEPICK32_1 'Date time picker
                            IF  @pNMHDR.code  = %DTN_DATETIMECHANGE THEN 
                                    LOCAL  pNMDTC   AS NMDATETIMECHANGE PTR
                                    pNMDTC =  pNMHDR 
                                           lTmp  =  @pNMDTC.st  ' get the new time nw selected
                             ....
              You need to check that @pNMHDR.code to see what the control is telling you has happened. Right now your code is 'doing its thing' every time the control tells you anything.

              Checking the NMHDR.code is a habit you should acquire, as it will be used whenever you work with any of the Microsoft Common Controls (listview, treeview, toolbar, date-time picker, others).

              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment

              Working...
              X