No announcement yet.

Call toUnicode returning 0.

  • Filter
  • Time
  • Show
Clear All
new posts

  • Call toUnicode returning 0.

    I have the following code:

    #DIM ALL
    %unicode = 1
    #INCLUDE ""
        LOCAL vk AS DWORD, sc AS DWORD, flags AS DWORD
        LOCAL buffer AS WSTRINGZ * 2
        LOCAL result AS INTEGER
        vk = %VK_X
        sc = MapVirtualKey(vk, 2) ' get scan code for the key
        flags = GetKeyboardLayout(0)
        result = ToUnicode(vk, sc, BYVAL 0, buffer, 2, flags)
        IF result > 0 THEN
            MSGBOX "Unicode character: " & buffer
        ELSEIF result < 0 THEN
            MSGBOX "ToUnicode error: " & STR$(GetLastError())
            ' No translation available.
            MSGBOX "Nothing happened."
        END IF
    But toUnicode always returns 0. Any ideas what could be wrong?

  • #2
    Where is that "ToUnicode' function? I don't understand all those params. Looks like that code is a test of that 'ToUnicode' function.

    Regardless, using PB/Win 10, the easiest way to convert "to unicode" is to let the PB compiler handle it...

      LOCAL  aString  AS STRING
      LOCAL wString AS WSTRING
      LET aString = "My Dog Has fleas"
      LET wString =  aString
    No muss, no fuss, no bother.

    No PB10/CC6 ? You may call the WinAPI see
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]


    • #3
      ToUnicode is an API function.

      He is doing scancode to wide character, not string to wstring.


      • #4
        Originally posted by Michael Mattias View Post
        No PB10/CC6 ? You may call the WinAPI see
        Hello Michael, thanks for the input. As Dale said, im trying to convert virtual key + scan codes to wide characters.

        Basically im trying to receive the wparam and lparam from %WM_CHAR and converting them to a wide character. This is required to receive characters from different language keyboards. But the API functions are not working.

        I dont see anything wrong with the declarations, but they are not working (or more likely im just not getting the result that i expect due to an error on my part?).

        In the example above, i tried using mapvirtualkey to get a scan code, but i know lparam contains the scan code. But since that wasnt working either, i tried this manual example.


        • #5
          Originally posted by Brian Alvarez View Post
          Basically im trying to receive the wparam and lparam from %WM_CHAR and converting them to a wide character. This is required to receive characters from different language keyboards. But the API functions are not working..
          I can't get it to work either, but is it really necessary?
          Posted to the window with the keyboard focus when a WM\_KEYDOWN message is translated by the TranslateMessage function. The WM\_CHAR message contains the character code of the key that was pressed.

          "The WM_CHAR message uses UTF-16 (16-bit Unicode Transformation Format) code units in its wParam if the Unicode version of the RegisterClass function was used to register the window class. Otherwise, the system provides characters in the current process code page, which can be set to UTF-8 in Windows Version 1903 (May 2019 Update) and newer. For more information, see Registering Window Classes and Use UTF-8 code pages in Windows apps.

          Starting with Windows Vista, WM_CHAR message can send UTF-16 surrogate pairs to Unicode windows. Use the IS_HIGH_SURROGATE, IS_LOW_SURROGATE, and IS_SURROGATE_PAIR macros to detect such cases, if necessary.


          • #6
            Hello Stuart, thanks for taking a look. I somewhat got toUnicode working, it was returning error 998 (ERROR_NOACCESS) because i was providing the lpKeyState parameter as BYVAL 0. It seems like either the documentation lies when it says it is optional, or it is checking for a null parameter differently. Providing a BYTE array makes it return something, but i am still looking if it provides something useful.

            Is it really necessary? Well, i am using a class that is registered externally, so, the code page is out of reach. As things are right now, the character й is sending character 233 which is ASCII code for й in the Windows-1252 Character set.

            There is plenty of things yet to try.
            Last edited by Brian Alvarez; 9 May 2023, 11:36 PM.


            • #7
              LOCAL ks AS STRING * 256
              result = ToUnicode(vk,sc, VARPTR(ks), buffer, 2, flags)
              Unicode character: x


              • #8
                I got that far... but character й causes error 87 (ERROR_INVALID_PARAMETER).


                • #9
                  Originally posted by Brian Alvarez View Post
                  I got that far... but character й causes error 87 (ERROR_INVALID_PARAMETER).
                  Have you tried MapVirtualKeyEx with an appropriate hkl?
                  Input locale identifier to use for translating the specified code. This parameter can be any input locale identifier previously returned by the LoadKeyboardLayout function.​


                  • #10
                    й becomes й when italicized.

                    I replicated the effect in Notepad set to font Calibri. The character changed back in other fonts.
                    Crylic breve I becomes Latin breve U in Calibri only when italic.
                    Code point stays the same.
                    ??error in Calibi??

                    (slight tangent I found interesting)


                    • #11
                      It's not an error in Calibri; the Cyrillic and other regional alphabets do have glyphs that change shape like that when italicized. IIRC it's a carry-over from a traditional way of writing cursive.
                      "Not my circus, not my monkeys."


                      • #12
                        You're saying the other fonts are wrong?


                        • #13

                          You're right, I have no idea which fonts/glyphs are correct, I'm just saying that's a normal feature of Cyrillic. Glyphs can change letter when italicized.

                          I jumped to the conclusion that if a font changed letters then it was not accidental.

                          Last edited by Eric Pearson; 10 May 2023, 03:35 AM.
                          "Not my circus, not my monkeys."


                          • #14
                            > й becomes й when italicized.​

                            I was curious so I pasted that string into Word and ran through a bunch of fonts. Consolas, Times New Roman, and Arial do the same N-U thing, but Courier New does not. So not even the core Microsoft fonts are consistent.
                            "Not my circus, not my monkeys."


                            • #15
                              Some time since Gutenberg the term italic got misapplied to "looks cursive" because it is slanted:

                              Italic is a whole other alphabet:

                              No wonder it is inconsistant. A very old error that not everybody stuck to. (Some just did slanted.)

                              (I've looking around too. Back to main subject now? (Appologies to Brian.))


                              • #16
                                Curiosity: ToUnicode in a subclassed edit control

                                #COMPILE EXE '#Win 10.04 (D:\Dev\Pow\Bas\Jose Roca\Forum\Jose\Windows API Headers\3.1.07\uz)#
                                #DIM ALL
                                %UNICODE = 1
                                #INCLUDE ""
                                GLOBAL hDlg AS DWORD
                                %Edit01 = 101
                                FUNCTION EditSubClassedProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS LONG, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
                                 STATIC pEditProc AS DWORD
                                 SELECT CASE wMsg
                                   CASE %WM_KEYDOWN
                                     LOCAL wChar AS WSTRINGZ * 4
                                     DIM KeyState(256) AS LOCAL BYTE
                                     GetKeyboardState(BYVAL VARPTR(KeyState(0)))
                                     SHIFT RIGHT lParam, 16 : lParam AND= &HFF 'Isolate Scan code embedded in lParam
                                     SELECT CASE ToUnicode(wParam, lParam, BYVAL VARPTR(KeyState(0)), wChar, 4, 0) 'Next line could also be used
                                     'SELECT CASE ToUnicode(wParam, MapVirtualKey(wParam, %MAPVK_VK_TO_VSC), BYVAL VARPTR(KeyState(0)), wChar, 4, 0)
                                       CASE -1   : SetWindowText(hDlg, "Dead key")
                                       CASE  0   : SetWindowText(hDlg, "No translation key")
                                       CASE ELSE : SetWindowText(hDlg, "ToUnicode wChar " & wChar & " 0x" & HEX$(ASC(wChar)))
                                     END SELECT
                                   CASE %WM_NULL
                                     IF hWnd = 0 AND pEditProc = 0 THEN pEditProc = wParam : EXIT FUNCTION 'Keep original edit procedure pointer without any global variable
                                   CASE %WM_NCDESTROY
                                     SetWindowLong(hWnd, %GWL_WNDPROC, pEditProc) 'Unsubclass edit
                                 END SELECT
                                 FUNCTION = CallWindowProc(pEditProc, hWnd, wMsg, wParam, lParam) 'Call original window proc.
                                END FUNCTION
                                CALLBACK FUNCTION PBMainCallBack
                                 STATIC hEdit AS DWORD
                                 SELECT CASE CBMSG
                                   CASE %WM_INITDIALOG
                                     hEdit     = GetDlgItem(hDlg, %Edit01)
                                     EditSubClassedProc(0, %WM_NULL, SetWindowLong(hEdit, %GWL_WNDPROC, CODEPTR(EditSubClassedProc)), 0)
                                     PostMessage(hEdit, %EM_SETSEL, SendMessage(hEdit, %WM_GETTEXTLENGTH, 0, 0), -1) 'Put caret at the end
                                 END SELECT
                                END FUNCTION
                                FUNCTION PBMAIN
                                 DIALOG FONT "Segoe UI", 9
                                 DIALOG NEW %HWND_DESKTOP, "ToUnicode api", , , 200, 60, %WS_SYSMENU, 0 TO hDlg
                                 SetClassLong(hDlg, %GCL_HICON, LoadIcon(BYVAL %NULL, BYVAL %IDI_INFORMATION)) 'Icon from Windows
                                 CONTROL ADD TEXTBOX, hDlg, %Edit01, "Get ToUnicode key down", 15, 15, 170, 12
                                 DIALOG SHOW MODAL hDlg CALL PBMainCallBack
                                END FUNCTION
                                Last edited by Pierre Bellisle; 10 May 2023, 07:42 PM.


                                • #17
                                  Exactly. Russian in cursive is another thing...

                                  Click image for larger version

Name:	image.png
Views:	112
Size:	140.2 KB
ID:	823512