Results 1 to 6 of 6

Thread: Alt+NumPad input for Unicode TextBox with surrogate pair support

  1. #1

    Thread Starter
    Member dseaman's Avatar
    Join Date
    Oct 2004
    Location
    Natal, Brazil
    Posts
    38

    Alt+NumPad input for Unicode TextBox with surrogate pair support

    When using Alt+NumPad for Unicode input I get a bogus character in Notepad/Notepad++ and all other Unicode TextBox implementations that I tried. WordPad and InkEdit, on the other hand. works OK, including surrogate pairs.

    Test summary:
    Alt+128512 (&H1F600) WordPad/InkEdit ��, Notepad/Notepad++/TextBoxW/ucText Nothing
    Alt+173569 (&H2A601) WordPad/InkEdit ��, Notepad/Notepad++TextBoxW/ucText ☺ (&H263A, 9786)
    Alt+931 (&H03A3) WordPad/InkEdit Σ , Notepad/Notepad++/TextBoxW/ucText ú (&HFA, 250)

    Here is sample code that overrides the internal Alt+NumPad behavior:
    1. Assumes you have a subclassed Unicode TextBox with source code that exposes Translate Accelerator.
    2, Make sure NumLock is On before testing.
    3. Tested with Segoe UI Regular.

    Code:
    Option Explicit
    
    Private mbDeleteChar As Boolean
    
    Private Function KeyPressed(ByVal KeyCode As KeyCodeConstants) As Boolean
      KeyPressed = CBool((GetAsyncKeyState(KeyCode) And &H8000&) = &H8000&)
    End Function
    
    Private Function ToSurrogatePair(ByVal i As Long) As String
      Dim Hi               As Integer, Lo As Integer
      On Error GoTo ErrHandler
      i = i - &H10000
      Hi = i \ &H400 + &HD800
      Select Case Hi
        Case &HD800 To &HDBFF
          Lo = i Mod &H400 + &HDC00
          Select Case Lo
            Case &HDC00 To &HDFFF
              'Debug.Print Hex(Hi), Hex(Lo)
              ToSurrogatePair = ChrW$(Hi) & ChrW$(Lo)
          End Select
      End Select
    ErrHandler:
    End Function
    
    'Build string in Translate Accelerator WM_SYSKEYDOWN.
    Friend Function TranslateAccel(pMsg As Msg) As Boolean
      Static mSysWord   As String
      
        Case WM_SYSKEYDOWN
          If KeyPressed(vbKeyMenu) Then 'Alt Pressed
            Select Case pMsg.wParam
              Case vbKeyNumpad0 To vbKeyNumpad9
                mSysWord = mSysWord & ChrW$(pMsg.wParam - 48)
            End Select
          End If
        Case WM_CHAR
          If Len(mSysWord) Then
            Dim i                As Long
            Dim s                As String
            On Error Resume Next
            i = CLng(mSysWord)
            Select Case i
              Case &HD800& To &HDBFF& 'Skip Reserved
              Case Is <= &HFFFF& '0 - 65535
                s = ChrW$(i)
              Case Is <= &H10FFFF 'Unicode max value
                s = ToSurrogatePair(i)
            End Select
            If Len(s) Then
              SelText = s 'Insert as SelText
              mSysWord = vbNullString 'Reset
              mbDeleteChar = True 'To delete bogus WM_CHAR that Alt+ generated internally.
            End If
            On Error GoTo 0
          End If
    
    'Finally delete the bogus character that appears in WM_CHAR when Alt is released.
    myWndProc:
        Case WM_CHAR
          If mbDeleteChar Then
            mbDeleteChar = False
            wParam = 0
          End If
    Similar code was tested in Krools TextBoxW (use wParam in lieu pf pMsg.wParam and KeyChar = 0 in WindowProcControl) and it appears to be working OK here. TextBoxW.Zip atttached.

    TextBoxW.zip
    Last edited by dseaman; May 26th, 2020 at 07:31 PM. Reason: Typo

  2. #2
    PowerPoster
    Join Date
    Sep 2012
    Posts
    2,083

    Re: Alt+NumPad input for Unicode TextBox with surrogate pair support

    It seems that the file is missing: CCRightToLeftModeConstants ???

  3. #3

    Thread Starter
    Member dseaman's Avatar
    Join Date
    Oct 2004
    Location
    Natal, Brazil
    Posts
    38

    Re: Alt+NumPad input for Unicode TextBox with surrogate pair support

    TextBoxW.zip contains only the control TextBoxW.ctl.
    You need to download the entire project from http://www.vbforums.com/showthread.p...mmon-controls) and just replace TextBoxW.ctl with the file attached here.

  4. #4
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,375

    Re: Alt+NumPad input for Unicode TextBox with surrogate pair support

    Thanks. I tested a little bit and found two bugs.

    1. mSysWord should be reset in case a key is not between Numpad0 and Numpad9.
    Code:
    Select Case pMsg.wParam
      Case vbKeyNumpad0 To vbKeyNumpad9
        mSysWord = mSysWord & ChrW$(pMsg.wParam - 48)
      Case Else
        mSysWord = vbNullString
    End Select
    2. ignore <= 255 as this is special range. (ASCII key combos ?)
    Code:
    Select Case i
      Case Is <= &HFF& 'Skip ASCII key combos
      Case &HD800& To &HDBFF& 'Skip Reserved
      Case Is <= &HFFFF& '0 - 65535
        s = ChrW$(i)
      Case Is <= &H10FFFF 'Unicode max value
        s = ToSurrogatePair(i)
    End Select
    It's a solution but for me it doesn't look that straight forward. So, I'm hesitating to fix this at all.. Thanks anyhow

  5. #5

    Thread Starter
    Member dseaman's Avatar
    Join Date
    Oct 2004
    Location
    Natal, Brazil
    Posts
    38

    Re: Alt+NumPad input for Unicode TextBox with surrogate pair support

    Duplicate Post
    Last edited by dseaman; May 28th, 2020 at 11:41 AM. Reason: Excluding <&H20

  6. #6

    Thread Starter
    Member dseaman's Avatar
    Join Date
    Oct 2004
    Location
    Natal, Brazil
    Posts
    38

    Re: Alt+NumPad input for Unicode TextBox with surrogate pair support

    In Microsoft Word and other RichEdit controls like InkEdit you can insert Unicode characters by typing the hex value of the character as 4 Hex characters and then typing Alt-x.

    This method does not support surrogate pairs since it is limited to 4 Hex characters.

    After testing in WordPad, 4Hex+ALt-X accepts >= &H20
    Here is the code we are using in Unicode TextBox.

    Code:
        Case WM_SYSCHAR  '&H106
          If pMsg.wParam = 88 Or pMsg.wParam = 120 Then ' X or x
            On Error GoTo ErrHandler
            Dim H                As String
            Dim c                As Long
            c = CurrentColumn
            If c > 3 Then
              H = ChrW$("&H" & Mid$(Text, c - 3, 4))
              If Len(H) Then
                SelStart = c - 4
                SelLength = 4
                If AscW(H) >= &H20 Then
                  SelText = H
                Else
                  SelText = vbNullString
                End If
              End If
            End If
            Exit Function
          End If

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width