Prev: Unicode Labels
Next: EM_CHARFROMPOS in RichEdit
From: expvb on 2 Feb 2009 20:53 "Karl E. Peterson" <karl(a)mvps.org> wrote in message news:uqLdnyZhJHA.4408(a)TK2MSFTNGP06.phx.gbl... > expvb wrote: >> I was saying that it's not always possible to get scan codes for every >> character. After checking the documentation, when you use >> KEYEVENTF_UNICODE, >> Windows sends VK_PACKET, which later translates to WM_CHAR and converted >> to >> ANSI if the window is ANSI, so there is nothing special you need to do. >> However, it seems that in certain situations the Unicode character is >> discarded. Use the Search tab in MSDN and type "VK_PACKET" (5 results), >> or >> "IME_PROP_ACCEPT_WIDE_VKEY" flag, which affect how VK_PACKET is >> processed. > > Okay, will take a look. After some more reading, it seems that MS introduced a way to insert characters without having to have a keyboard scan code by adding KEYEVENTF_UNICODE. This was probably done to support writing pads(handwriting recognition pads). In these pads there are no keys, so there are no scan codes. KEYEVENTF_UNICODE/VK_PACKET was introduced for this purpose, but since "IME_PROP_ACCEPT_WIDE_VKEY" flag can affect how VK_PACKET is processed, you can avoid VK_PACKET and send the Unicode character by using SendUnicodeChar() function below. Windows would automatically convert the Unicode character to ANSI if the target window is ANSI(See WM_CHAR in MSDN for details). Note that I am using the W version of SendMessage. Option Explicit Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _ ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Any) As Long Private Declare Function SendMessageW Lib "user32" (ByVal hWnd As Long, _ ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Const WM_CHAR = &H102 Private Const WM_UNICHAR = &H109 ' Windows 2000+ Only Public Function SendUnicodeChar(ByVal hWnd As Long, _ ByVal lKey As Long) As Long SendUnicodeChar = SendMessageW(hWnd, WM_CHAR, lKey, ByVal 1&) End Function
From: Karl E. Peterson on 2 Feb 2009 21:22 expvb wrote: > After some more reading, it seems that MS introduced a way to insert > characters without having to have a keyboard scan code by adding > KEYEVENTF_UNICODE. That's what I'm doing! > This was probably done to support writing > pads(handwriting recognition pads). In these pads there are no keys, so > there are no scan codes. KEYEVENTF_UNICODE/VK_PACKET was introduced for this > purpose, but since "IME_PROP_ACCEPT_WIDE_VKEY" flag can affect how VK_PACKET > is processed, you can avoid VK_PACKET and send the Unicode character by > using SendUnicodeChar() function below. Windows would automatically convert > the Unicode character to ANSI if the target window is ANSI(See WM_CHAR in > MSDN for details). Note that I am using the W version of SendMessage. > > > Option Explicit > > Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _ > ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ > lParam As Any) As Long > Private Declare Function SendMessageW Lib "user32" (ByVal hWnd As Long, _ > ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long > Private Const WM_CHAR = &H102 > Private Const WM_UNICHAR = &H109 > > ' Windows 2000+ Only > Public Function SendUnicodeChar(ByVal hWnd As Long, _ > ByVal lKey As Long) As Long > SendUnicodeChar = SendMessageW(hWnd, WM_CHAR, lKey, ByVal 1&) > End Function That would prevent the mixing of character sets (to allow for stuff like navigation keys, etc), that I was trying to support. So the question is, what advantage does that confer over stuffing the SendInput buffer with the Unicode character? ' http://vb.mvps.org/samples/raw/MSendInput.bas.txt Private Sub StuffBufferW(ByVal CharCode As Integer) ' Unicode is relatively simple, in this context?! ' Press and release this key. With m_Events(m_EvtPtr) .wVK = 0 .wScan = CharCode .dwFlags = KEYEVENTF_UNICODE End With m_EvtPtr = m_EvtPtr + 1 With m_Events(m_EvtPtr) .wVK = 0 .wScan = CharCode .dwFlags = KEYEVENTF_UNICODE Or KEYEVENTF_KEYUP End With m_EvtPtr = m_EvtPtr + 1 End Sub -- ..NET: It's About Trust! http://vfred.mvps.org
From: Thorsten Albers on 3 Feb 2009 07:42 Karl E. Peterson <karl(a)mvps.org> schrieb im Beitrag <#jb79zZhJHA.760(a)TK2MSFTNGP03.phx.gbl>... > Hmmmm, that's not what that code was doing, though. Rather, it was just processing > the passed string, one character at a time, and then stuffing a SendInput buffer > based on what was found. If the character was >=256, it would stuff it with a > Unicode character. If it was 0-255, it'd use the normal ANSI procedures, taking > into account things like Shift states and such. IMHO a procedure supporting Unicode should be a Unicode-only procedure. Otherwise the result may differ from what was expected. E.g. A) Sending character code 00C4h as Unicode 1. Receiving application does support Unicode Application works with character code 00C4h and shows up the glyph 'A with diaeresis above'. That's o.k. 2. Receiving application does not support Unicode Application works with character code C4h and shows up the glyph which in the application's/user's/system's current ANSI codepage is encoded with character code C4h (Western: 'A with diaresis above'; Greek: 'Delta'; Cyrillic: 'De', etc.) That's o.k. B) Sending character code C4h as ANSI 1. Receiving application does support Unicode Application converts the character code from ANSI to Unicode according to the application's/user's/system's current ANSI codepage which may be 00C4h (Latin 'A with diaeresis above'), 0394h (Greek 'Delta'), 0414h (Cyrillic 'De'), etc. This doesn't make much sense and presumably is not what the user of the procedure expects!! 2. Receiving application does not support Unicode S. A.2. If at all, using ANSI instead of Unicode in your procedure would make sense only if restricted to >>ASCII<< character codes (000-127) because they are the same in any ASCII and ANSI codepage as well as in Unicode. Therefore: If (code And &HFF80) Then ' Unicode Else ' ANSI End If -- Thorsten Albers albers (a) uni-freiburg.de
From: Thorsten Albers on 3 Feb 2009 07:51 Karl E. Peterson <karl(a)mvps.org> schrieb im Beitrag <OD64C3ZhJHA.5244(a)TK2MSFTNGP06.phx.gbl>... > First I've ever heard of them! Remember, I'm USian, and therefore *highly* > unicode-impaired. :-/ We all hope that this will change under a coloured president with a semitic name who came from Indonesia... (feel free to replace 'coloured' by whatever currently is the political correct word in the USA) -- Thorsten Albers albers (a) uni-freiburg.de
From: Karl E. Peterson on 3 Feb 2009 13:48
Hi Thorsten -- >> Hmmmm, that's not what that code was doing, though. Rather, it was just >> processing the passed string, one character at a time, and then stuffing a >> SendInput buffer based on what was found. If the character was >=256, it would >> stuff it with a Unicode character. If it was 0-255, it'd use the normal ANSI >> procedures, taking into account things like Shift states and such. > > IMHO a procedure supporting Unicode should be a Unicode-only procedure. > Otherwise the result may differ from what was expected. E.g. This is why I asked here. I'd hoped to find folks far more familiar with these sorts of issues than I am. My first inclination was indeed to simply offer a distinct 'W' version of the call, and leave it at that. Then, it looked "so easy!" to get tricky and fold it all into one, that I wondered what I must be missing. Too good to be true? Yeah, sounds like it, given what you're telling me. So, assuming I were to create another parallel routine that's specifically intended for Unicode... Would it also matter to the users of this routine that it support the navigation keys as well? Or would it be sufficient to let them do navkeys with the standard routine, then send Unicode chars with the dedicated routine? Thanks... Karl -- ..NET: It's About Trust! http://vfred.mvps.org |