Announcement

Collapse
No announcement yet.

ALT KEY handling in a SubClassed Button

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

  • ALT KEY handling in a SubClassed Button

    I've searched my poffs, maybe I'm not giving the right search key, but I can't find an example of trapping say 'Alt Y' or 'Alt N' so I can simulate the button click. I've got enter clicking the currently focused button and button clicking all working in the sub class.

    Bob Mechler

  • #2
    Bob, would VkKeyScanEx help?

    Comment


    • #3
      Why are you trying to duplicate the work of the Dialog Box Manager/IsDialogMessage function?

      What you are attempting is possible, but before I provide an answer I would like to know why you need to do this for a button.
      Dominic Mitchell
      Phoenix Visual Designer
      http://www.phnxthunder.com

      Comment


      • #4
        As Mr. Mitchell notes.....
        >duplicate the work.......
        Code:
        CONTROL ADD  BUTTON .... "&help"
        Alt+H clicks this button.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          This is my subclassed Dialog Confirmation y/n that is generic and self sizing based on the message passed. This code sets focus on the default button whether Yes or No and makes sure the broken line box is there (sometimes it's not). It handles the return key and throws it away.

          Why do this?

          In my main dialog I heavily trap many different keys for branching to lookup routines and/or dup functions. As each textbox gets focus it uses a message pump that will allow responding to any key as a field exit key if that key is setup to be a field exit key. Once the field is exited the key that was pressed is used by the program to call a dialog that presents a listbox of choices for the field or the exit key might fill in the field with default information and go on to the next field.

          Other times when return is pressed I normally just go to the next field and re-enter the message pump afresh. Many times the information in the field is not valid or some other combination of fields causes a warning box to be needed.

          At that point I pop up a dialog that informs the user of the problem and requires a yes/no answer and is supposed to stay in the field that caused the problem. If I don't throw away the return key it gets processed by the underlying field and it moves to the next field. Anyway, the code below successfully throws away the return and handles the button clicks.



          But now the ALT Y and ALT N need to respond.

          Code:
                GLOBAL V_YNMSG$,CUST_ERMSG_DEPTH AS INTEGER
                MACRO mSC_Set(phDlg, phCtl, pProc)
                		SetWindowLong GetDlgItem(phDlg, phCtl), %GWL_USERDATA, _
                				SetWindowLong(GetDlgItem(phDlg, phCtl), %GWL_WNDPROC, CODEPTR(pProc))
                END MACRO
                MACRO mSC_Kill(phCtl)
                		SetWindowLong(GetDlgItem(CBHNDL, phCtl), %GWL_WNDPROC, _
                				GetWindowLong(CBHNDL, %GWL_USERDATA))
                END MACRO
                MACRO mSC_OrgProc
                		FUNCTION = CallWindowProc(GetWindowLong(phWnd, %GWL_USERDATA), phWnd, pdMsg, pWParam, pLParam)
                END MACRO    
                FUNCTION YNSubClassProc(BYVAL phWnd AS DWORD, BYVAL pdMsg AS DWORD, BYVAL pWParam AS DWORD, BYVAL pLParam AS LONG) AS LONG
                  SELECT CASE pdMsg
                    CASE %WM_KEYUP
                      IF pWParam = 13 THEN               
                        SELECT CASE GetDlgCtrlID(phWnd)
                          CASE 2 
                            V_YESNO$ = "Y"
                          CASE 3
                            V_YESNO$ = "N"
                        END SELECT                
                        V_YNDEF = 0
                        DIALOG END GetParent(phWnd),0
                      END IF
                    CASE %WM_LBUTTONDOWN
                      SELECT CASE GetDlgCtrlID(phWnd)
                        CASE 2 
                          V_YESNO$ = "Y"
                        CASE 3
                          V_YESNO$ = "N"
                      END SELECT 
                      V_YNDEF = 0
                      DIALOG END GetParent(phWnd),0
                  END SELECT
                  mSC_OrgProc
                END FUNCTION
                CALLBACK FUNCTION YesNoMsgbxproc 
                  DIM sCBCTL AS LONG
                  SELECT CASE AS LONG CBMSG
                      CASE %WM_INITDIALOG 
          
                        IF V_YNDEF = 2 THEN
                          KeyBd_Event %VK_RIGHT, MapVirtualKey(%VK_RIGHT, 0), 0, 0: SLEEP 0
                        ELSEIF V_YNDEF = 1 THEN
                          KeyBd_Event %VK_RIGHT, MapVirtualKey(%VK_RIGHT, 0), 0, 0: SLEEP 0
                          KeyBd_Event %VK_LEFT, MapVirtualKey(%VK_LEFT, 0), 0, 0: SLEEP 0
                        END IF
                        ' Initialization handler
                        '
                        SetWindowPos CBHNDL,%HWND_TOPMOST,0,0,0,0,%SWP_NOMOVE OR %SWP_NOSIZE
                      CASE %WM_DESTROY  
                        mSC_Kill(2)
                        mSC_Kill(3)
                      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_SIZE
                        IF IsIconic(CBHNDL) THEN
                          DIALOG SHOW STATE hdlg,%SW_HIDE
                        ELSE
                          DIALOG SHOW STATE hdlg,%SW_SHOW
                        END IF
                      CASE %WM_COMMAND 
                  END SELECT
                END FUNCTION
                SUB YesNoMsgbx                   
                  DIM msg as tagmsg,loopcnt AS LONG,hCtrl2 AS STATIC LONG,hCtrl3 AS STATIC LONG
                  ALT_ERMSG_DEPTH = 0
                  ERMSG_DEPTH = (LEN(V_YNMSG$) / 35) * 10 + 10
                  IF ERMSG_DEPTH < 10 THEN ERMSG_DEPTH = 10
                  IF INSTR(V_YNMSG$,CHR$(10)) > 0 THEN
                    ALT_ERMSG_DEPTH = PARSECOUNT(V_YNMSG$,$LF) * 8
                  END IF
                  IF ALT_ERMSG_DEPTH > ERMSG_DEPTH THEN
                    ERMSG_DEPTH = ALT_ERMSG_DEPTH
                  END IF
                  IF CUST_ERMSG_DEPTH > 0 THEN
                    ERMSG_DEPTH = CUST_ERMSG_DEPTH
                    CUST_ERMSG_DEPTH = 0 'reset
                  END IF
                  IF V_YNSIZ < 150 THEN V_YNSIZ = 150
                  DIALOG DISABLE hdlg
                  DIALOG NEW 0,"User option",,,V_YNSIZ ,ERMSG_DEPTH + 50, %WS_SYSMENU,0 TO YesNoMsgBox&
                  CONTROL ADD LABEL,YesNoMsgBox&,10,V_YNMSG$,10,10,V_YNSIZ - 20,ERMSG_DEPTH,%SS_CENTER,%WS_EX_LEFT OR %WS_EX_STATICEDGE
                  CONTROL SEND YesNoMsgBox&, 10, %WM_SETFONT, hFontText, %True
                  IF V_YNDEF = 1 THEN
                    CONTROL ADD BUTTON,YesNoMsgBox&,2,"&Yes",V_YNSIZ/2 - 50,ERMSG_DEPTH + 13,40,14,%BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT
                    CONTROL ADD BUTTON,YesNoMsgBox&,3,"&No",V_YNSIZ/2 + 10,ERMSG_DEPTH + 13,40,14,%BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT
                    CONTROL SEND YesNoMsgBox&, 2, %WM_SETFONT, hFontText, %True
                    CONTROL SEND YesNoMsgBox&, 3, %WM_SETFONT, hFontText, %True
                    CONTROL SET FOCUS YesNoMsgBox&, 2
                    CONTROL REDRAW YesNoMsgBox&,2
                  ELSEIF V_YNDEF = 2 THEN
                    CONTROL ADD BUTTON,YesNoMsgBox&,2,"&Yes",V_YNSIZ/2 - 50,ERMSG_DEPTH + 13,40,14,%BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT
                    CONTROL ADD BUTTON,YesNoMsgBox&,3,"&No",V_YNSIZ/2 + 10,ERMSG_DEPTH + 13,40,14,%BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT
                    CONTROL SEND YesNoMsgBox&, 2, %WM_SETFONT, hFontText, %True
                    CONTROL SEND YesNoMsgBox&, 3, %WM_SETFONT, hFontText, %True
                    CONTROL SET FOCUS YesNoMsgBox&, 3
                    CONTROL REDRAW YesNoMsgBox&,3
                  END IF 
                  mSC_Set(YesNoMsgBox&,2,YNSubClassProc)        
          
                  mSC_Set(YesNoMsgBox&,3,YNSubClassProc)        
                  DIALOG SHOW MODAL YesNoMsgBox&  CALL YesNoMsgbxproc 
                  SetForeGroundWindow hdlg
                  V_YNSIZ = 150            
                  DIALOG ENABLE hdlg
          
                END SUB

          Comment


          • #6
            I will have to do a long post for the benefit of lurkers because I still don't think you need to do the work of the OS.
            By the way, the code in your post will never work even if you were to replace WM_KEYUP with WM_SYSKEYUP or WM_SYSCHAR.

            You can do one of the following:

            1) SetWindowsHookEx(WH_GETMESSAGE)
            2) Process keys in message loop
            3) Process WM_GETDLGCODE
            4) Turn off default dialog box keyboard handling(don't call IsDialogMessage)

            I will post explanations and code at a later date.
            Dominic Mitchell
            Phoenix Visual Designer
            http://www.phnxthunder.com

            Comment


            • #7
              Thanks,

              Admittedly, I'm trying to usurp the work of the OS with my own message loop. It's clear I don't have complete command of what it takes to handle more than one dialog using custom message pumps.


              Bob Mechler

              Comment

              Working...
              X