Announcement

Collapse
No announcement yet.

ALT KEY handling in a SubClassed Button

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

  • BOB MECHLER
    replied
    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

    Leave a comment:


  • Dominic Mitchell
    replied
    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.

    Leave a comment:


  • BOB MECHLER
    replied
    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

    Leave a comment:


  • Michael Mattias
    replied
    As Mr. Mitchell notes.....
    >duplicate the work.......
    Code:
    CONTROL ADD  BUTTON .... "[B][COLOR="Red"]&[/COLOR][/B]help"
    Alt+H clicks this button.

    Leave a comment:


  • Dominic Mitchell
    replied
    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.

    Leave a comment:


  • Chris Holbrook
    replied
    Bob, would VkKeyScanEx help?

    Leave a comment:


  • BOB MECHLER
    started a topic ALT KEY handling in a SubClassed Button

    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
Working...
X