The Doctor's back to answer more of your questions! This issue will cover:
| How can I install support for Keyboard. . .? | |
| VB is Unicode, isn't it? | |
| Isn't Windows CE Unicode? | |
| Finding out whether an input locale is BiDi? | |
| Everyone who speaks Turkish, say "I" (or perhaps "İ") |
Windows supplies (seemingly) only one layout that corresponds to the Bulgarian standard for a typewriter keyboard layout. Lately is also popular a "phonetic layout" in which the Bulgarian letters are situated "over" the latin letters that sound the same...
So, could you give me a reference where to search for such a layout or there is a way to customize the available layouts?
Best regards,
(From the Internet)
Dr. International has to tell you one thing: this is the single most popular question he has received to date! Simply replace Bulgarian with a different language and the explanation of the Phoentic layout with the appropriate justification, and you will see what many of the messages to the Doctor look like!
The answer is actually quite complicated, so Dr. International will try to present some of the important issues here:
| • | There is no way provided by Windows to create your own custom keyboard layouts. This is a feature that many people have asked for, and people at Microsoft are very aware of the interest in this area. |
| • | In many cases, there is a perfectly acceptable keyboard layout that actually contains all of the characters that one needs for a specific language. In this case, you can use one of those keyboards. The Doctor would suggest that you don't worry about the name as much as making sure the functionality is there. All of these keyboards are here at /globaldev/reference/keyboards.mspx |
| • | The actual decision to include a keyboard is a complicated one, that involves extensive research with governments, educational institutions, local software providers, and other interested parties. In many cases, it is difficult to find the expertise for a particular locale; in other cases, there is sometimes too much (conflicting) information. The end result is usually based on an established standard, although occasionally specific keys that other keyboards provide are added in order to allow the keyboard to have the best support possible. |
| • | The method described above is obviously not perfect, and sometimes important information is missed. In these cases, feedback from users is the crucial step to making sure that future versions will have the support that people need. Examples include the multiple keyboards that exist for Devanagari languages such as Hindi, or the support for the Euro that was added to many of the European keyboards. |
If you ever feel that you have such information, then Dr. International would encourage you to send this information to him via the Ask Dr. International form. You should include as much information as you can. Things like, where the keyboard is used, why it might be superior to what is available, whether any Standards bodies have recognized it, and even a legitimate business case that will show how wide the usage is now and would be if it were added, etc. are most helpful. Dr. International cannot promise what will happen, but he can promise that the information will get to the right people to be reviewed!
I am trying to display Unicode strings in a FlexGrid control in Visual Basic, but most of the characters are replaced by question marks, and a few of them are replaced by different characters. For example, here is the lowercase Greek alphabet:
αβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ
The grid control converts this to:
aß?de??????µ???p??st?f????????
I am running this application on Windows 2000. How can I display the data correctly?
(From the Internet)
Unfortunately, you are running across a limitation in many Visual Basic controls, since the majority of them are not Unicode-enabled. Any time you try to use them with Unicode strings, those strings are converted to the default system code page via the WideCharToMultiByte function. This function does have a "best guess" mechanism that will replace characters when they do not exist on the target code page. This is what will cause a letter such as the Greek alpha (α) to be replaced with the lowercase a, when your default system code page is 1252 (Western European and United States).
However, in your case, there is a workaround!
Instead of using the MS FlexGrid control, you can use the MS Hierarchical FlexGrid Control. When this control is being used on a Unicode operating system such as Windows NT 4.0 or Windows 2000, it is Unicode-enabled and will properly handle these strings. In many other types of controls, Microsoft does not provide a Unicode-enabled control, and you would have to try to turn to 3rd parties for solutions.
This is an issue that is being addressed in the next version of Visual Basic, also known as VB.Net.
I am sure that I read that Windows CE is a completely Unicode platform. Yet any time I try to create applications using the "Microsoft eMbedded Visual Tools", the IDE cannot handle Unicode strings at all. This happens whether I use eMbedded Visual C++ 3.0 or eMbedded Visual Basic 3.0. Is there some setting I am missing?
(From 'Searching for Unicode')
Hello Searching,
There is a lot of interest in Unicode support, isn't there? :-)
No, there is no special setting, and the things you have read are correct: Windows CE is an entirely Unicode-based operating system. The problem is that the two IDEs for the eMbedded Visual Tools are based on the Visual Studio 6.0 IDEs, which are not Unicode enabled. This situation is similar to what happens in Visual C++ 6.0, where even though you can compile a Unicode application, you cannot actually see Unicode strings in the IDE. This is similar to the VS 6.0 situation, so it should not be that large of an djustment.
Dr. International can assure you that once your code is compiled, it will properly support Unicode, and while debugging either with a device or with one of the emulators, you will see your Unicode application working properly. If you are using eMbedded VB, you are even provided with a special version of the Win32 API Viewer that will properly handle the strings you pass to the API's "W" functions as Unicode.
I am expected to show a tail on the caret when the keyboard language is bidi/RTL.
Right now we hard-code the list of languages that are RTL. I couldn't find an API or NLS setting that would tell me a keyboard/language is bidi.
But even if I have the full list of RTL languages, support could be added for more of them in future versions of Windows. So how would I know to turn on the tailed caret? I can't wait until text is typed -- I must show it when the keyboard language changes.
(From the Internet)
Amazingly enough, there is indeed a way to retrieve this information!
Bit 123 of the LOCALE_FONTSIGNATURE returned from the GetLocaleInfo function indicates whether or not a given locale is a BiDi locale. You can use code such as the following to employ this method:
#define MAXWCBUF 80 WCHAR wcBuf[MAXWCBUF]; int cBuf; cBuf = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, wcBuf, MAXWCBUF); g_UserBidiLocale = (cBuf && wcBuf[7] & 0x0800) ? TRUE : FALSE;
Obviously you can replace LOCALE_USER_DEFAULT with the Locale ID that you need to check; you can even use the HIWORD of the handle to the input locale (hKL). You should note, however, that this solution will not work on versions of Windows prior to Windows 2000. However, for those versions a simple hard-coded list is all you would need, since new input locales are not added to old versions. You can simply get the primary language ID with code such as the following:
PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID()))
If this expression returns LANG_ARABIC, LANG_HEBREW, or LANG_FARSI, then it is a BiDi language (these three are the only ones that could be around prior to Windows 2000.
I am from Turkey, and I am having problems with my Access 2000 application. My database is in Turkish sort order, but when I try to use the LCase() or UCase() functions inside of a query or in a form/report expression, it is not using the Turkish casing rules (where İ is the uppercase form of i, and I is the uppercase form of ı). Instead it seems to be using the English casing rules (where I is the uppercase form of i). Data in the database itself seems to work properly though. I even tested this with an ADP [Access Data Project) connected to SQL Server and my form and report expressions did not work there, either!
What I am doing wrong?
(Confused in Turkey)
Hello Confused,
Let the Doctor reassure you here: you are not doing anything wrong. The limitation is in Windows itself, unfortunately.
You see, ideally the setting of Turkish regional settings would cause the collation in Windows (which would affect the functioning of the APIs such as CompareString) to use the Turkish casing rules. However, when this was attempted, there were problems. Since in the file system, all files need to have an 8.3 representation that is in upper case, even if the long file name version may be in mixed case, there were basic problems with .INI and .INF files needed by Windows to run. This is because an attempt to open win.ini on a Turkish system would fail, since the filename is really WIN.INI! There were problems even booting up Windows in this situation! Therefore, the non-Turkish I/i mapping had to be used.
Obviously this is not ideal, but a system that works did have to take priority here. However, neither Jet nor SQL Server needed to have such limitations, so both products, as you noticed, will properly handle the Turkish casing rules. The problem here is that the UCase and LCase functions that you would use with an Access query, form, or report actually come from VBA. And VBA functions rely on the operating system to handle casing.
However, there is no need to panic. The doctor can prescribe two workarounds:
1) If you are using a SQL Server database, you can use SQL Server's UPPER() and LOWER() functions in queries instead of UCase() and LCase(). For example, a query such as the following can be used to convert data to upper and lower case as needed:
select UPPER([Field1]) as [UpperCase], LOWER([Field2]) as [LowerCase] from Table1
This query will properly handle any locale, Turkish or not, because the server's own casing rules will be used; if you are using SQL Server 2000, collation can be specified even at the column level, and this query will use the column's collation.
2) If you are using a Jet database, or if you need to use a form or report expression, then you can write a user defined function to do the work for you:
Function UCase(vIn As Variant) As Variant
If IsNull(vIn) Then
UCase = Null
Else
Select Case AscW(vIn)
Case &H131 ' Dotless lowercase I
UCase = ChrW$(&H49)
Case &H69 ' Dotted lowercase I
UCase = ChrW$(&H130)
Case Else
UCase = VBA.UCase$(vIn)
End Select
End If
End Function
Function LCase(vIn As Variant) As Variant
If IsNull(vIn) Then
LCase = Null
Else
Select Case AscW(vIn)
Case &H49 ' Dotless uppercase I
LCase = ChrW$(&H131)
Case &H130 ' Dotted uppercase I
LCase = ChrW$(&H69)
Case Else
LCase = VBA.LCase$(vIn)
End Select
End If
End Function
These functions will override the built in UCase() and LCase() functions provided by VBA, and will allow you to use the Turkish casing rules when you need to. Note how they actually use the VBA functions when they need to by specifically calling VBA.UCase() and VBA.LCase(). You can also use these functions elsewhere in your VBA or VB code.
Either of these two methods will give you the behavior you are looking for: proper linguistic Turkish casing.
The issue with the OS and the file system is obviously not ideal, but it would require a major architectural change in Windows to address it; in the meantime, the efforts of applications to support linguistic casing for Turkish will need to be sufficient. After all, Dr. International thinks that if your computer cannot even boot, than it is a pretty expensive plant stand, isn't it? :-)
See you next time!
Dr. International
Windows International Division