Announcement

Collapse
No announcement yet.

Edit Subclass Question

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

  • Edit Subclass Question

    Hello to all,

    The following post is from my ever ending battle to learn the text handling side of windows:

    Code:
    ' -----------------------------------------------------------------------------
    
    FUNCTION editSubclassProc(BYVAL hEdit AS LONG, _
                              BYVAL wMsg AS LONG, _
                              BYVAL wParam AS LONG, _
                              BYVAL lParam AS LONG) AS LONG
    
      LOCAL  fPassThru   AS LONG
    
      FUNCTION = %FALSE      'Initialize function to False
    
      SELECT CASE wMsg
        CASE %WM_LBUTTONUP, %WM_KEYUP
          updCaretPos2Sbar hEdit, ghStatus, 0, 0
    
        CASE %WM_CHAR
          '/* Pass the character message to default edit control procedure */
          CallWindowProc glpfnDefEditProc, hEdit, wMsg, wParam, lParam
          
          SELECT CASE wParam
            CASE 34                     'User typed a ", send matching "
              IF ISFALSE fPassThru THEN
                fPassThru = %TRUE                              'Prevent closed loop
                CallWindowProc glpfnDefEditProc, hEdit, wMsg, wParam, lParam
                '/* Move the caret back one space */
                'CallWindowProc glpfnDefEditProc, hEdit, %WM_KEYDOWN, %VK_LEFT, 0
              END IF
    
            CASE 40                     'User typed a (, send matching )
              CallWindowProc glpfnDefEditProc, hEdit, wMsg, 41, lParam
              'CallWindowProc glpfnDefEditProc, hEdit, %WM_KEYDOWN, %VK_LEFT, 0
              'PostMessage hEdit, %WM_KEYDOWN, %VK_LEFT, 0
              'SendMessage GetParent(hEdit), %WM_KEYDOWN, 0, 0
          END SELECT
          EXIT FUNCTION
    
        CASE %WM_CONTEXTMENU
          'EXIT FUNCTION
    
        CASE %WM_DESTROY
          SetWindowLong hEdit, %GWL_WNDPROC, glpfnDefEditProc   'Restore procedure
    
      END SELECT
    
      FUNCTION = CallWindowProc(glpfnDefEditProc, hEdit, wMsg, wParam, lParam)
    END FUNCTION  'editSubclassProc
    
    ' -----------------------------------------------------------------------------
    My question is, how do I simulate the VK_LEFT key from the soft end to get the same result from the keyboard. I've tried everything I could think of to get the caret to backup one space after the subclass function adds another character (ie "" and ()).

    Passing the WM_KEYDOWN message does cause the caret to backup but the trailing character is highlighted.

    Using the get/set caret functions also move the caret back but on the next char key down, the caret jumps over the inserted character inserted by the subclass function. Like it moved but the edit control didn't know about it????????

    I've read till I'm blue in the face. HELP!!!

    Cheers,
    Cecil

  • #2
    Well I finally found what the problem was. One last search of MSDN revealed how to force an edit control to set the caret position. EM_SETSEL was the key.

    Code:
    ' -----------------------------------------------------------------------------
    
    FUNCTION editSubclassProc(BYVAL hEdit AS LONG, _
                              BYVAL wMsg AS LONG, _
                              BYVAL wParam AS LONG, _
                              BYVAL lParam AS LONG) AS LONG
    
      LOCAL  fPassThru   AS LONG, _
             iOffset     AS LONG
             
      FUNCTION = %FALSE      'Initialize function to False
    
      SELECT CASE wMsg
        CASE %WM_LBUTTONUP, %WM_KEYUP
          updCaretPos2Sbar hEdit, ghStatus, 0, 0
    
        CASE %WM_CHAR
          '/* Pass the character message to default edit control procedure */
          CallWindowProc glpfnDefEditProc, hEdit, wMsg, wParam, lParam
          '/* Get the caret location relative to last character entered */
          iOffset = HIWRD(Edit_GetSel(hEdit))
          
          SELECT CASE wParam
            CASE 34                     'User typed a ", send matching "
              IF ISFALSE fPassThru THEN
                fPassThru = %TRUE                              'Prevent closed loop
                CallWindowProc glpfnDefEditProc, hEdit, wMsg, wParam, lParam
                '/* Move the caret back one character */
                SendMessage hEdit, %EM_SETSEL, iOffset, iOffset
              END IF
    
            CASE 40                     'User typed a (, send matching )
              CallWindowProc glpfnDefEditProc, hEdit, wMsg, 41, lParam
              SendMessage hEdit, %EM_SETSEL, iOffset, iOffset
          END SELECT
          EXIT FUNCTION
    
        CASE %WM_CONTEXTMENU
          'EXIT FUNCTION
    
        CASE %WM_DESTROY
          SetWindowLong hEdit, %GWL_WNDPROC, glpfnDefEditProc   'Restore procedure
    
      END SELECT
    
      FUNCTION = CallWindowProc(glpfnDefEditProc, hEdit, wMsg, wParam, lParam)
    END FUNCTION  'editSubclassProc
    
    ' -----------------------------------------------------------------------------
    Cecil

    ------------------


    [This message has been edited by Cecil Williams (edited March 16, 2000).]

    Comment


    • #3
      Cecil --
      You can also imitate by KeyBd_Event
      Small sample (based on Lance' code)
      If to type the word "LEFT", cursor automatic moves to previous position (at first time only)
      Code:
      #Compile Exe
      #Register None
      #Include "WIN32API.INC"
      Global hDlg&
      Global gOldSubClassProc As Dword
      Function SubClassProc(ByVal hWnd&, ByVal wMsg&, ByVal wParam&, ByVal lParam&) As Long
          Static Ex&
          Function = CallWindowProc(gOldSubClassProc, hWnd&, wMsg&, wParam&, lParam&)
          Control Get Text hDlg&, 102 To a$
          If UCase$(Right$(a$, 4)) = "LEFT" And Ex& = 0 Then
             KeyBd_Event %VK_LEFT, MapVirtualKey(%VK_LEFT, 0), 0, 0: Sleep 0
             KeyBd_Event %VK_LEFT, MapVirtualKey(%VK_LEFT, 0), %KEYEVENTF_KEYUP, 0: Sleep 0
             Ex& = 1
          End If
      End Function
      CallBack Function DlgCallBack
          Static hEdit&
          Select Case CbMsg
              Case %WM_INITDIALOG
                  Control Handle CbHndl, 102 To hEdit&
                  gOldSubClassProc = SetWindowLong(hEdit&, %GWL_WNDPROC, CodePtr(SubClassProc))
              Case %WM_DESTROY
                  SetWindowLong hEdit&, %GWL_WNDPROC, gOldSubClassProc
          End Select
      End Function
      Function PbMain
          Dialog New 0, "Type left",,, 170, 100, %DS_CENTER Or %WS_SYSMENU To hDlg
          Control Add TextBox,  hDlg, 102, "", 10, 10, 150, 50, %ES_MULTILINE _
              Or %ES_WANTRETURN, %WS_EX_CLIENTEDGE
          Dialog Show Modal hDlg Call DlgCallBack
      End Function
      [This message has been edited by Semen Matusovski (edited March 16, 2000).]

      Comment

      Working...
      X