Announcement

Collapse
No announcement yet.

return , arrow keys focus ??

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

  • return , arrow keys focus ??

    I have this code from some timeback in the forum. I am using it in this large program that I have and it works fine.

    Now was going to post a problem I was having using it in different place. So started to make a small sample code
    to show the problem I was having. But the sample program I tried making does not work. Where is the problem?

    What the code was to do was to enter text in the textbox and press the enter key and focus goes to the done button.
    Then when the focus is in the done button , pressing up arrow or left arrow the focus would return to the textbox.

    This code I do not understand 100% . One thing I left out is the Accelerator code.
    Would like to see if this code can be made to work to do just what is discribe above.

    After this code is fixed will add another sample code to describe the second problem I was having.

    Code:
    #COMPILE EXE
    #INCLUDE "WIN32API.INC"
    
    GLOBAL hDlg AS DWORD , TEXT1 AS STRING
    
    CALLBACK FUNCTION PBMAIN_DlgProc() AS LONG
    '*** ???? VVV *************************************************************************************************
    SELECT CASE CBMSG
    CASE %WM_INITDIALOG
    ' ensure keyboard shortcut visual cues are visible (eg underscored 'L' on LOOKUP btn)
    DIALOG SEND CBHNDL, %WM_CHANGEUISTATE, MAK(LONG, %UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
    
    CASE %WM_COMMAND
    IF CBCTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ' (NB. "Or CB.CtlMsg = 1" for when msg from an accelerator
    SELECT CASE CBCTL ' Which Control ID or Accelerator CMD?
    'CASE %Key_Down
    ' DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0 ' The WM_NEXTDLGCTL message is sent to a dialog box
    ' procedure to set the keyboard focus to a different control
    ' in the Dialog. (0, 0 => next control to receive focus)
    'CASE %Key_UP
    ' DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 1, 0 ' (1, 0 => previous control to receive focus)
    
    CASE %IDOK ' Enter key notification to Dialog
    IF GetFocus = GetDlgItem(CBHNDL, 201) THEN
    'MsgBox "Process now?", %MB_ICONMASK, "" ' option to auto process after last entry
    CONTROL SET FOCUS hDlg,201
    ELSE
    DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0
    END IF
    
    CASE 100 ' DONE Btn clicked
    'MsgBox "Process now?", %MB_ICONMASK, ""
    CONTROL SET FOCUS hDlg,201
    
    END SELECT
    
    END IF
    END SELECT
    '*** ???? ***************************************************************************************************
    END FUNCTION
    
    CALLBACK FUNCTION DONE1() AS LONG
    CONTROL GET TEXT hDlg, 201 TO TEXT1
    CONTROL SET TEXT hDlg, 200, TEXT1
    CONTROL SET FOCUS hDlg, 201
    END FUNCTION
    
    
    FUNCTION PBMAIN() AS LONG
    DIALOG NEW 0, "Dialog 1",,,300,300, %WS_SYSMENU, 0 TO hDlg
    LOCAL result AS LONG
    
    CONTROL ADD LABEL, hDlg, -1,"Enter Selection No. : " , 70, 210, 120, 15,
    CONTROL ADD LABEL, hDlg, 200 ,"TEXTBOX" ,120, 150, 80, 15,
    CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
    CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, CALL DONE1
    CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL XXXX
    CONTROL SET FOCUS hDlg, 201
    
    DIALOG SHOW MODAL hDlg CALL PBMAIN_DlgProc TO result
    END FUNCTION
    Robert

  • #2
    See CASE %IDOK - If focus is textbox you set focus to textbox. Try setting it to button id 100 instead.

    Comment


    • #3
      That worked. Thanks BJ
      Now will work on the other example which is different but may not work there.
      Robert

      Comment


      • #4
        One thing I notice is that when pressing enter, focus goes to control 100 but when pressing enter again
        focus goes from control 100 to 101. Should pressing enter at control 100 not click that control 100 button
        instead of going to control 101?
        Robert

        Comment


        • #5
          No, if focus is not TextBox, your code posts a message to set focus to next control in zorder (%WM_NEXTDLGCTL).
          Normally, Spacebar triggers buttons, but you could insert trap for it under %IDOK, something like, ELSEIF GetFocus = GetDlgItem(CB.HNDL, 100) THEN ' do whatever

          Comment


          • #6
            The original code posted below works just like want in the main program I use. From textbox to button and enter here activates the control.

            So comparing both what is the difference?

            In the sample code I posted the CASE %Key_Down and CASE %Key_UP keys give error. Are this the ones that allow
            the button return to activate the button?

            The error is undefined equate. I have #INCLUDE "WIN32API.INC" and it does not recognize those equates.

            Code:
            CALLBACK FUNCTION PBMAIN_DlgProc()
            SELECT CASE CBMSG
            CASE %WM_SYSCOMMAND
            IF (CBWPARAM AND &HFFF0) = %SC_CLOSE THEN
            '''
            LOCAL lResult AS LONG
            
            DIALOG DISABLE hDlg
            
            lResult = MSGBOX("CLICK OK TO **EXIT PROGRAM**",%MB_OKCANCEL ,"NETWORTH")
            IF lResult=%IDOK THEN GOTO CONT2: ELSE DIALOG ENABLE hDlg: MSGBOX "PROGRAM EXIT CANCELED",,"NETWORTH":_
            CONTROL SET FOCUS hDlg, %TXBU0 : GOTO EXITT
            
            CONT2:
            CLOSE
            DIALOG END hDlg,1
            DIALOG END CBHNDL, 1
            EXITT:
            '''''NEED FIX CANCEL, NOT WORKING ????
            '''
            END IF
            END SELECT
            
            '******** 'Dave Biggs
            SELECT CASE CBMSG
            CASE %WM_INITDIALOG
            ' ensure keyboard shortcut visual cues are visible (eg underscored 'L' on LOOKUP btn)
            DIALOG SEND CBHNDL, %WM_CHANGEUISTATE, MAK(LONG, %UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
            
            CASE %WM_COMMAND
            IF CBCTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ' (NB. "Or CB.CtlMsg = 1" for when msg from an accelerator
            SELECT CASE CBCTL ' Which Control ID or Accelerator CMD?
            CASE %Key_Down
            DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0 ' The WM_NEXTDLGCTL message is sent to a dialog box
            ' procedure to set the keyboard focus to a different control
            ' in the Dialog. (0, 0 => next control to receive focus)
            CASE %Key_UP
            DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 1, 0 ' (1, 0 => previous control to receive focus)
            
            CASE %IDOK ' Enter key notification to Dialog
            IF GetFocus = GetDlgItem(CBHNDL, %TXBX8) THEN
            'MsgBox "Process now?", %MB_ICONMASK, "" ' option to auto process after last entry
            CONTROL SET FOCUS hDlg,%TXBX1
            ELSE
            DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0
            END IF
            
            CASE %TXBU9 ' DONE Btn clicked
            'MsgBox "Process now?", %MB_ICONMASK, ""
            CONTROL SET FOCUS hDlg,%TXBX1
            
            
            END SELECT
            END IF
            '******** 'Dave Biggs
            END SELECT
            END FUNCTION
            Robert

            Comment


            • #7
              %WM_KEYDOWN and %WM_KEYUP might work.
              Rod
              I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

              Comment


              • #8
                '******** 'Dave Biggs
                SELECT CASE CBMSG
                ....etc
                '******** 'Dave Biggs
                I think that code snippet in post #6 is, at least in part, from this thread.

                The thread discussed some of the same issues that have been raised here ie:

                Dialog navigation between controls that have styles which include %WM_TABSTOP.

                Behaviour of Special / Navigational Keys in a dialog (%IDOK, %IDCANCEL) and the 'tab' key.

                How Spacebar / Enter key will behave, depending on the type of control that has keyboard focus.

                The snippet within '******** 'Dave Biggs comments includes code for %Key_Down and %Key_UP notifications. In the original code, those equates were defined using an accelerator table for arrow keys %VK_DOWN and %VK_UP (in lieu of subclassing eg. to capture %WM_KEYDOWN and %WM_KEYUP messages).
                Rgds, Dave

                Comment


                • #9
                  Just in general, I'm not so sure I'd use a non-standard keyboard interface like this.

                  Then again, you may be trying to match something users are already used to as opposed to designing something new.

                  It's worth thinking about. By now users are pretty comfy with "Windows standard" keyboard interface.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Thanks Dave for the ref to old post.

                    Updated sample program. Almost works like I would like but one problem.

                    Enter some text > enter goes to done > enter goes to cancel > arrow back goes to done > enter done button activated

                    Now from here: enter text press enter , goes to done, press enter done button activate and repeat

                    Something here is missing?



                    Code:
                    #COMPILE EXE
                    #INCLUDE "WIN32API.INC"
                    
                    %Key_Down = 401 ' equates for Accelerator keys
                    %Key_Up = 402
                    
                    GLOBAL hDlg AS DWORD , TEXT1 AS STRING
                    
                    CALLBACK FUNCTION PBMAIN_DlgProc() AS LONG
                    '*** ???? VVV *************************************************************************************************
                    SELECT CASE CBMSG
                    CASE %WM_INITDIALOG
                    ' ensure keyboard shortcut visual cues are visible (eg underscored 'L' on LOOKUP btn)
                    DIALOG SEND CBHNDL, %WM_CHANGEUISTATE, MAK(LONG, %UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
                    
                    CASE %WM_COMMAND
                    IF CBCTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ' (NB. "Or CB.CtlMsg = 1" for when msg from an accelerator
                    SELECT CASE CBCTL ' Which Control ID or Accelerator CMD?
                    CASE %Key_Down
                    DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0 ' The WM_NEXTDLGCTL message is sent to a dialog box
                    ' procedure to set the keyboard focus to a different control
                    ' in the Dialog. (0, 0 => next control to receive focus)
                    CASE %Key_UP
                    DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 1, 0 ' (1, 0 => previous control to receive focus)
                    
                    CASE %IDOK ' Enter key notification to Dialog
                    IF GetFocus = GetDlgItem(CBHNDL, 201) THEN
                    'MsgBox "Process now?", %MB_ICONMASK, "" ' option to auto process after last entry
                    CONTROL SET FOCUS hDlg,100
                    ELSE
                    DIALOG POST CBHNDL, %WM_NEXTDLGCTL, 0, 0
                    END IF
                    
                    CASE 100 ' DONE Btn clicked
                    'MsgBox "Process now?", %MB_ICONMASK, ""
                    CONTROL SET FOCUS hDlg,201
                    
                    END SELECT
                    
                    END IF
                    END SELECT
                    '*** ???? ***************************************************************************************************
                    END FUNCTION
                    
                    CALLBACK FUNCTION DONE1() AS LONG
                    CONTROL GET TEXT hDlg, 201 TO TEXT1
                    CONTROL SET TEXT hDlg, 200, TEXT1
                    CONTROL SET FOCUS hDlg, 201
                    END FUNCTION
                    
                    
                    FUNCTION PBMAIN() AS LONG
                    DIALOG NEW 0, "Dialog 1",,,300,300, %WS_SYSMENU, 0 TO hDlg
                    LOCAL result, hAccel AS LONG
                    
                    DIM AC(1) AS ACCELAPI
                    AC(0).FVIRT = %FVIRTKEY
                    AC(0).KEY = %VK_DOWN
                    AC(0).CMD = %Key_Down
                    
                    AC(1).FVIRT = %FVIRTKEY
                    AC(1).KEY = %VK_UP
                    AC(1).CMD = %Key_Up
                    
                    ACCEL ATTACH hDlg, AC() TO hAccel
                    
                    CONTROL ADD LABEL, hDlg, -1,"Enter Selection No. : " , 70, 210, 120, 15,
                    CONTROL ADD LABEL, hDlg, 200 ,"TEXTBOX" ,120, 150, 80, 15,
                    CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
                    CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, CALL DONE1
                    CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL XXXX
                    CONTROL SET FOCUS hDlg, 201
                    
                    DIALOG SHOW MODAL hDlg CALL PBMAIN_DlgProc TO result
                    END FUNCTION
                    Robert

                    Comment


                    • #11
                      Not sure I understand, but DIALOG POST to trigger desired button on %IDOK should give bestter control over action, maybe like this:
                      '
                      Code:
                      #COMPILE EXE
                      #INCLUDE "WIN32API.INC"
                      
                      GLOBAL hDlg AS DWORD , TEXT1 AS STRING
                      
                      '====================================================================
                      CALLBACK FUNCTION PBMAIN_DlgProc() AS LONG
                        '*** ???? VVV *************************************************************************************************
                        SELECT CASE CBMSG
                        CASE %WM_INITDIALOG
                            ' ensure keyboard shortcut visual cues are visible (eg underscored 'L' on LOOKUP btn)
                            DIALOG SEND CBHNDL, %WM_CHANGEUISTATE, MAK(LONG, %UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
                      
                        CASE %WM_COMMAND
                            IF CBCTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ' (NB. "Or CB.CtlMsg = 1" for when msg from an accelerator
                                SELECT CASE CBCTL ' Which Control ID or Accelerator CMD?
                      
                                CASE %IDOK ' Enter key notification
                                    SELECT CASE GetFocus
                                    CASE GetDlgItem(CBHNDL, 201) : CONTROL SET FOCUS CB.HNDL, 100            ' Enter in TextBox
                                    CASE GetDlgItem(CBHNDL, 100) : DIALOG POST CB.HNDL, %WM_COMMAND, MAKLNG(100, %BN_CLICKED), 0 ' Enter on DONE button
                                    CASE GetDlgItem(CBHNDL, 101) : DIALOG POST CB.HNDL, %WM_COMMAND, MAKLNG(101, %BN_CLICKED), 0 ' Enter on Cancel button
                                    END SELECT
                                      
                                CASE 100 ' DONE Btn triggered
                                    MSGBOX "DONE Btn", %MB_ICONMASK, ""
                                    CONTROL SET FOCUS hDlg,101  ' move to Cancel button?
                      
                                CASE 101 ' CANCEL Btn triggered
                                    MSGBOX "CANCEL Btn", %MB_ICONMASK, ""
                                    CONTROL SET FOCUS hDlg,201  ' move to TextBox?
                      
                            END SELECT
                        END IF
                      
                        END SELECT
                        '*** ???? ***************************************************************************************************
                      END FUNCTION
                      
                      '====================================================================
                      CALLBACK FUNCTION DONE1() AS LONG
                        CONTROL GET TEXT hDlg, 201 TO TEXT1
                        CONTROL SET TEXT hDlg, 200, TEXT1
                        CONTROL SET FOCUS hDlg, 201
                      END FUNCTION
                      
                      '====================================================================
                      FUNCTION PBMAIN() AS LONG
                        LOCAL result AS LONG
                      
                        DIALOG NEW 0, "Dialog 1",,,300,300, %WS_SYSMENU, 0 TO hDlg
                      
                        CONTROL ADD LABEL, hDlg, -1,"Enter Selection No. : " , 70, 210, 120, 15,
                        CONTROL ADD LABEL, hDlg, 200 ,"TEXTBOX" ,120, 150, 80, 15,
                        CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
                        CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, CALL DONE1
                        CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL XXXX
                        CONTROL SET FOCUS hDlg, 201
                      
                        DIALOG SHOW MODAL hDlg CALL PBMAIN_DlgProc TO result
                      END FUNCTION
                      '

                      Comment


                      • #12
                        PS, remove accel stuff there, because left/up arrow keys on buttons works just the same anyway, moving to prev control.

                        Comment


                        • #13
                          Borje Hagsten, a little different but it is what I was looking for.
                          Below is code for my second question (code modified some) that I was looking for and it works with your sample code.
                          Thanks everyone for your help and comments.

                          Code:
                          #COMPILE EXE
                          #INCLUDE "WIN32API.INC"
                          
                          GLOBAL hDlg AS DWORD , TEXT1 AS STRING
                          
                          CALLBACK FUNCTION DIALOG2 AS LONG
                          CONTROL KILL hDlg, 200
                          CONTROL KILL hDlg, 201
                          CONTROL KILL hDlg, 100
                          CONTROL KILL hDlg, 101
                          CONTROL KILL hDlg, 400
                          
                          CONTROL ADD LABEL, hDlg, 300,"DIALG2 Selection No. : " , 70, 210, 120, 15,
                          
                          CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
                          CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, 'CALL xxxx
                          CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL yyyy
                          CONTROL SET FOCUS hDlg, 201
                          END FUNCTION
                          
                          CALLBACK FUNCTION PBMAIN_DlgProc() AS LONG
                          SELECT CASE CBMSG
                          CASE %WM_INITDIALOG
                          ' ensure keyboard shortcut visual cues are visible (eg underscored 'L' on LOOKUP btn)
                          DIALOG SEND CBHNDL, %WM_CHANGEUISTATE, MAK(LONG, %UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
                          
                          CASE %WM_COMMAND
                          IF CBCTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ' (NB. "Or CB.CtlMsg = 1" for when msg from an accelerator
                          SELECT CASE CBCTL ' Which Control ID or Accelerator CMD?
                          
                          CASE %IDOK ' Enter key notification
                          SELECT CASE GetFocus
                          CASE GetDlgItem(CBHNDL, 201) : CONTROL SET FOCUS CB.HNDL, 100 ' Enter in TextBox
                          CASE GetDlgItem(CBHNDL, 100) : DIALOG POST CB.HNDL, %WM_COMMAND, MAKLNG(100, %BN_CLICKED), 0 ' Enter on DONE button
                          CASE GetDlgItem(CBHNDL, 101) : DIALOG POST CB.HNDL, %WM_COMMAND, MAKLNG(101, %BN_CLICKED), 0 ' Enter on Cancel button
                          END SELECT
                          
                          CASE 100 ' DONE Btn triggered
                          'MSGBOX "DONE Btn", %MB_ICONMASK, ""
                          'CONTROL SET FOCUS hDlg,101 ' move to Cancel button?
                          CONTROL KILL hDlg, 200
                          CONTROL KILL hDlg, 201
                          CONTROL KILL hDlg, 100
                          CONTROL KILL hDlg, 101
                          CONTROL KILL hDlg, 400
                          
                          CONTROL ADD LABEL, hDlg, 300,"DIALG2 Selection No. : " , 70, 210, 120, 15,
                          
                          CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
                          CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, 'CALL xxxx SOME OTHER CALLBACK
                          CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL yyyy
                          CONTROL SET FOCUS hDlg, 201
                          
                          CASE 101 ' CANCEL Btn triggered
                          MSGBOX "CANCEL Btn", %MB_ICONMASK, ""
                          CONTROL SET FOCUS hDlg,201 ' move to TextBox?
                          
                          END SELECT
                          END IF
                          
                          END SELECT
                          END FUNCTION
                          
                          'CALLBACK FUNCTION DONE1() AS LONG
                          ' CONTROL GET TEXT hDlg, 201 TO TEXT1
                          ' CONTROL SET TEXT hDlg, 200, TEXT1
                          ' CONTROL SET FOCUS hDlg, 201
                          'END FUNCTION
                          
                          FUNCTION PBMAIN() AS LONG
                          DIALOG NEW 0, "Dialog 1",,,300,300, %WS_SYSMENU, 0 TO hDlg
                          LOCAL result AS LONG
                          
                          CONTROL ADD LABEL, hDlg,400,"DIALOG1 Selection No. : " , 70, 210, 120, 15
                          CONTROL ADD LABEL, hDlg, 200 ,"TEXTBOX" ,120, 150, 80, 15,
                          CONTROL ADD TEXTBOX, hDlg, 201 ,"" , 50, 230, 80, 15,
                          CONTROL ADD BUTTON, hDlg, 100 ,"&1 DONE" ,140, 230, 50, 15, CALL DIALOG2 ' DONE1
                          CONTROL ADD BUTTON, hDlg, 101 ,"&0 Cancel" ,200, 230, 50, 15, 'CALL XXXX
                          CONTROL SET FOCUS hDlg, 201
                          
                          DIALOG SHOW MODAL hDlg CALL PBMAIN_DlgProc TO result
                          END FUNCTION
                          Robert

                          Comment

                          Working...
                          X