Announcement

Collapse
No announcement yet.

Focus to button

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

  • Focus to button

    How do I set the focus on a button?

    "CONTROL SET FOCUS CB.HNDL, %IDC_BUTTON2" does not work.

    Code:
    #COMPILER PBWIN 10
    #COMPILE EXE
    #DIM ALL
    
    %UNICODE = 1
    #INCLUDE ONCE "WIN32API.INC"
    
    
    %IDD_DIALOG1 =  101
    %IDC_BUTTON1 = 1001
    %IDC_BUTTON2 = 1002
    
    
    CALLBACK FUNCTION ShowDIALOG1Proc()
        SELECT CASE AS LONG CB.MSG
        CASE %WM_INITDIALOG
    CONTROL SET FOCUS CB.HNDL, %IDC_BUTTON2
        CASE %WM_COMMAND
            SELECT CASE AS LONG CB.CTL
            CASE %IDC_BUTTON1
                IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                    MSGBOX "%IDC_BUTTON1=" + FORMAT$(%IDC_BUTTON1), _
                        %MB_TASKMODAL
                END IF
            CASE %IDC_BUTTON2
                IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                    MSGBOX "%IDC_BUTTON2=" + FORMAT$(%IDC_BUTTON2), _
                        %MB_TASKMODAL
                END IF
            END SELECT
        END SELECT
    END FUNCTION
    
    
    FUNCTION PBMAIN()
    LOCAL lRslt AS LONG
    LOCAL hDlg  AS DWORD
    
        DIALOG NEW 0, "Dialog1", 70, 70, 250, 134, %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 BUTTON, hDlg, %IDC_BUTTON1, "Button1", 60, 50, 55, 25
        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Button2", 125, 50, 55, 25
    
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    END FUNCTION

  • #2
    Bernhard,
    Don't you need to set focus after the button becomes visible, which it is not in INITDIALOG?
    Last edited by Gary Beene; 18 Jun 2017, 01:50 PM.

    Comment


    • #3
      Like Gary says, so here's a way:

      Edited - hm, tested and it only worked once. Strange..
      Code:
          CASE %WM_INITDIALOG
              DIALOG POST CB.HNDL, %WM_USER, 0, 0
      
          CASE %WM_USER
              CONTROL SET FOCUS CB.HNDL, %IDC_BUTTON2
      Last edited by Borje Hagsten; 18 Jun 2017, 04:00 PM.

      Comment


      • #4
        Strange:
        When I start the program and then activate another program and back again, then the focus is set.

        Comment


        • #5
          A solution tha works here is tabbing to next control (button 2) via code:
          Code:
              CASE %WM_INITDIALOG
                  Keybd_Event %VK_TAB, 0, 0, 0                 ' press tab key
                  Keybd_Event %VK_TAB, 0, %KEYEVENTF_KEYUP, 0  ' release tab key
          Edited - This assumes that button 2 is 2:nd (next) control in tab order. Which it is in this example.

          Comment


          • #6
            Hey,

            Not seeing button darker border or dotted frame on a new window is normal behavior,
            it does not mean that the focus is not set.
            Here is some code to experiment with, using BS_NOTIFY to get focus notifications.
            Try with and without WM_NEXTDLGCTL and WM_CHANGEUISTATE. MSDN URL are in code.

            Pierre

            Code:
            #COMPILE EXE  '#Win9.07#
            #DIM ALL
            '#RESOURCE ".pbr"
            %UNICODE = 1
            #INCLUDE "Win32Api.inc"
            
            %Button1 = 101
            %Button2 = 102
            %Label1  = 201
            GLOBAL hDlg AS DWORD
            '_____________________________________________________________________________
            
            CALLBACK FUNCTION ShowDIALOG1Proc()
             STATIC hButton1 AS DWORD
             STATIC hButton2 AS DWORD
             STATIC hLabel1  AS DWORD
            
             SELECT CASE AS LONG CBMSG
            
             CASE %WM_INITDIALOG
               hLabel1  = GetDlgItem(CBHNDL, %Label1)
               hButton1 = GetDlgItem(CBHNDL, %Button1)
               hButton2 = GetDlgItem(CBHNDL, %Button2)
               PostMessage(CBHNDL, %WM_APP, 0, 0)
            
             CASE %WM_APP
               CONTROL SET FOCUS CBHNDL, %Button2
            
               'WM_NEXTDLGCTL - https://msdn.microsoft.com/en-us/library/windows/desktop/ms645432(v=vs.85).aspx
               SendMessage(CBHNDL, %WM_NEXTDLGCTL, hButton2, 1) 'Darker border
            
               'WM_CHANGEUISTATE - https://msdn.microsoft.com/en-us/library/windows/desktop/ms646342(v=vs.85).aspx
               SendMessage(CBHNDL, %WM_CHANGEUISTATE, MAKLNG(%UIS_CLEAR, %UISF_HIDEFOCUS), 0) 'Dotted frame
            
             CASE %WM_COMMAND
               SELECT CASE AS LONG CBCTL
            
                 CASE %Button1
                   IF CBCTLMSG = %BN_SETFOCUS THEN
                     SetWindowText(hLabel1, "Focus is on button 1, use space-bar to see ")
                   END IF
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     SetWindowText(hLabel1, "Button 1 was clicked")
                   END IF
            
                 CASE %Button2
                   IF CBCTLMSG = %BN_SETFOCUS THEN
                     SetWindowText(hLabel1, "Focus is on button 2, use space-bar to see ")
                   END IF
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     SetWindowText(hLabel1, "Button 2 was clicked")
                   END IF
            
               END SELECT
             END SELECT
            
            END FUNCTION
            '_____________________________________________________________________________
            
            FUNCTION PBMAIN()
             LOCAL hIcon AS DWORD
            
             DIALOG NEW %HWND_DESKTOP, "Focus", , , 250, 100, _
             %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
             hIcon = ExtractIcon(GetModuleHandle(""), "%SystemRoot%\system32\PowrProf.dll", 1)
             SetClassLong(hDlg, %GCL_HICONSM, hIcon)
             SetClassLong(hDlg, %GCL_HICON, hIcon)
             CONTROL ADD LABEL, hDlg, %Label1, "-",  10, 20, 230, 15, %SS_CENTER
             CONTROL ADD BUTTON, hDlg, %Button1, "Button1",  60, 50, 55, 25, %BS_NOTIFY OR %WS_TABSTOP
             CONTROL ADD BUTTON, hDlg, %Button2, "Button2", 125, 50, 55, 25, %BS_NOTIFY OR %WS_TABSTOP
             DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
             DestroyIcon(hIcon)
            
            END FUNCTION
            '_____________________________________________________________________________
            '

            Comment


            • #7
              Börje's way is easier to implement, you may even use TAB and SHIFT-TAB so the focus won't change...

              CONTROL SET FOCUS CBHNDL, %Button2
              KeyBd_Event(%VK_TAB, 0, 0, 0)
              KeyBd_Event(%VK_TAB, 0, %KEYEVENTF_KEYUP, 0)
              KeyBd_Event(%VK_SHIFT, 0, 0, 0)
              KeyBd_Event(%VK_TAB, 0, 0, 0)
              KeyBd_Event(%VK_TAB, 0, %KEYEVENTF_KEYUP, 0)
              KeyBd_Event(%VK_SHIFT, 0, %KEYEVENTF_KEYUP, 0)


              Pierre

              Comment


              • #8
                Probably an easier method is to make %IDC_Button2 the first button in your source code..

                Alternatively use %WM_NEXTDLGCTL to set focus to the control. Note: The effect of this message differs from that of the SetFocus function because WM_NEXTDLGCTL modifies the border around the target control in addition to moving keyboard focus.

                This message can be sent from the PBMain Code as show commented out below.

                %WM_CHANGEUISTATE is also commented out in the sample code below. It's use will force the display of visual cues which may be hidden by default on the user's PC.

                Code:
                FUNCTION PBMAIN()
                LOCAL lRslt AS LONG
                LOCAL hDlg  AS DWORD
                
                    DIALOG NEW 0, "Dialog1", 70, 70, 250, 134, %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 BUTTON, hDlg, %IDC_BUTTON2, "Button2", 125, 50, 55, 25  ' < First btn normally gets default btn status, shows visual cues if active
                    CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Button1", 60, 50, 55, 25   '   and will respond to Spacebar if focus is not elsewhere.
                 '    CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Button2", 125, 50, 55, 25  '   Move up in source code OR use %WM_NEXTDLGCTL message to make default
                
                 '    DIALOG POST hDlg, %WM_NEXTDLGCTL, GetDlgItem(hDlg, %IDC_Button2), 1 ' set keyboard focus - will respond to Spacebar or EnterKey when focused
                
                 '    DIALOG POST hDlg, %WM_CHANGEUISTATE, MakLng(%UIS_CLEAR, %UISF_HIDEFOCUS Or %UISF_HIDEACCEL), 0   ' Show Visual Cues
                
                    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                END FUNCTION
                Last edited by Dave Biggs; 19 Jun 2017, 08:57 AM.
                Rgds, Dave

                Comment


                • #9
                  You can also set the focus in PBMAIN, instead of %WM_INITDIALOG:

                  Code:
                  CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Button2", 125, 50, 55, 25
                  CONTROL SET FOCUS hDlg, %IDC_BUTTON2
                  But maybe it's too easy.
                  Forum: http://www.jose.it-berater.org/smfforum/index.php

                  Comment


                  • #10
                    Settingf focus is easy, but getting the focus rect that shows which button has focus can be a bit trickier. Tabbing to desired button is simple solution.

                    Comment


                    • #11
                      Additional remarks in post #8 - sample code has commented statement that demos posting %WM_NEXTDLGCTL from PBMAIN.

                      %WM_NEXTDLGCTL does put the focus rect onto the control too.
                      Rgds, Dave

                      Comment


                      • #12
                        Ypu can play with the bittom style (at least using SDK-stule code, might work with DDT, else use 'CONTROL ADD "button" ....' to add the control. The style want..

                        BS_DEFPUSHBUTTON Creates a push button that behaves like a BS_PUSHBUTTON style button, but also has a heavy black border. If the button is in a dialog box, the user can select the button by pressing the ENTER key, even when the button does not have the input focus. This style is useful for enabling the user to quickly select the most likely (default) option.
                        I couls swear there is a window message (CONTROL SEND...) you can use to do something like this.... .. maybe it's DM_SETDEFID... yeah, I think that's it...


                        An application sends a DM_SETDEFID message to change the identifier of the default push button for a dialog box.
                        ....

                        This message is processed by the DefDlgProc function. To set the default push button, the function can send WM_GETDLGCODE and BM_SETSTYLE messages to the specified control and the current default push button.
                        Worth a shot, methinks. Note you really need to read all the fine print provided in the MSDN doc about this message. But I think I've given you a pretty good start.
                        Michael Mattias
                        Tal Systems Inc.
                        Racine WI USA
                        mmattias@talsystems.com
                        http://www.talsystems.com

                        Comment


                        • #13
                          You may also see this post from Mike on SetFocus.
                          In fact, good stuff in the whole thead plus a link to
                          The Old New Thing - How to set focus in a dialog box by Raymond Chen

                          Pierre

                          Comment


                          • #14
                            Strange is that SET FOCUS works, but not with the dialog call.
                            MS has apparently never repaired this. I do not know what is more strange, the problem or the solution.

                            Many Thanks! The following works well:

                            Code:
                            FUNCTION PBMAIN()
                            LOCAL lRslt AS LONG
                            LOCAL hDlg  AS DWORD
                                DIALOG NEW 0, "Dialog1", 70, 70, 250, 134, %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 BUTTON, hDlg, %IDC_BUTTON1, "Button1", 60, 50, 55, 25
                                CONTROL ADD BUTTON, hDlg, %IDC_BUTTON2, "Button2", 125, 50, 55, 25
                                '---------------------------------------------------------------------------------------------
                            DIALOG POST hDlg, %WM_NEXTDLGCTL, GetDlgItem(hDlg, %IDC_BUTTON2), 1
                                DIALOG POST hDlg, %WM_CHANGEUISTATE, MAKLNG(%UIS_CLEAR, %UISF_HIDEFOCUS OR %UISF_HIDEACCEL), 0
                                '---------------------------------------------------------------------------------------------
                                DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                            END FUNCTION

                            Comment

                            Working...
                            X