Postings are provided as is with no warranties, and confer no rights. Opinions expressed here are my own delusions; my employers at best shake their heads and sigh, at worst repudiate the content with extreme prejudice, whenever it manages to appear on their radar.
This blog is unsuitable for overly sensitive persons with low self-esteem and/or no sense of humour. Proceed at your own risk. Use as directed. Do not spray directly into eyes. Caution: filling may be hot. Do not give to children under 60 years of age. Not labeled for individual sale. Do not read 'natas teews ym' backwards. Objects in mirror are closer than they appear. Chew before swallowing. Do not bend, fold, spindle or mutilate. Do not take orally unless directed by a physician. Remove baby before folding stroller. Not for use on unexplained calf pain.
A nice FLAIR (FLuid Attenuated Inversion Recovery) view from the not-too-distant past. Every abnormality you can see on this scan (and there is more than one!) is asymptomatic at present. Alongside is a picture of me walking the walls at Fremont Studios, a sign of a damaged brain.
Yes, C (not Claire, or Chrsitine; the other C, I mean) is probably grimacing after just seeing the title of this blog.
I can almost hear the two us acting out a bit from a Louis XIV song:
She said oh come on boy aren't you tired of talking Persia yet?I said little girl what do you really expect?
I guess you have to be there. In my head, I mean....
So anyway, Afshar's question via the Contact Link was:
Hi Michael, There is a good standard for Persian (Farsi) keyboard layout called ISIRI 9147 (former version was ISIRI 2901) but none versions of windows comply with it including Vista, XP, 98, 95. I always wonder why Microsoft doesn't like to use this standard and even more each version's keyboard layout is changing by new versions? ISIR stands for Institute Of Standards & Industrial Research Of Iran (http://www.isiri.org/). ISIRI in Iran is something like ANSI in U.S. I am a Persian (Farsi) user of MS Windows and an i18n interested C# developer. I'm very pleased to help on this issue if I can. Please let me know if I can do anything. afshar
Hi Michael,
There is a good standard for Persian (Farsi) keyboard layout called ISIRI 9147 (former version was ISIRI 2901) but none versions of windows comply with it including Vista, XP, 98, 95. I always wonder why Microsoft doesn't like to use this standard and even more each version's keyboard layout is changing by new versions? ISIR stands for Institute Of Standards & Industrial Research Of Iran (http://www.isiri.org/). ISIRI in Iran is something like ANSI in U.S.
I am a Persian (Farsi) user of MS Windows and an i18n interested C# developer. I'm very pleased to help on this issue if I can. Please let me know if I can do anything.
afshar
And there was another, similar note from Nasser as well:
Dear Kaplan, MichaelAs I Know you are a real good connector between microsoft and developers, I want to ask you to do something for me.I Live in Iran and I always like to work with standard application. Microsoft is going to finalize Windows 7 and we want microsoft to implement a standard Keyboard Layout for Iran. Now in all windows versions (2008,vista,xp,etc) microsoft provides a keyboard layout for Farsi that is not a standard one.The Institute of Standards & Industrial Research of Iran had announced two keyboard layouts: one ISIRI 2901 that realeased on about 13 years ago and the other one ISIRI 9147 that was the Persian Keyboard Layout version2 and released about 2 years ago.We want to ask from microsoft to implement this keyboard Layout (ISIRI 9147) into windows seven and other following Operating System like Midori or viseversa Please show us the best way to connect to microsoft to ask this from them, or connect us to them, or better than everything ask them to implement this keyboard layout into windows. FarsiWeb had implemented this layout and this layout is publicly available from here you can download it and use it but please do something for us, we use from a wide variety of unstandard application becouse of this bad kayboard layout that microsoft provided on windows. there is a good group on google formerly named Persian Computing there are some good guys that can be helpfull for you like Behdad Esfahbod and Rouzbeh PourNader that were in ISIRI 9147 implementation team.I am wonder if you help me, thank you so much , Nasser
Dear Kaplan, MichaelAs I Know you are a real good connector between microsoft and developers, I want to ask you to do something for me.I Live in Iran and I always like to work with standard application. Microsoft is going to finalize Windows 7 and we want microsoft to implement a standard Keyboard Layout for Iran. Now in all windows versions (2008,vista,xp,etc) microsoft provides a keyboard layout for Farsi that is not a standard one.The Institute of Standards & Industrial Research of Iran had announced two keyboard layouts: one ISIRI 2901 that realeased on about 13 years ago and the other one ISIRI 9147 that was the Persian Keyboard Layout version2 and released about 2 years ago.We want to ask from microsoft to implement this keyboard Layout (ISIRI 9147) into windows seven and other following Operating System like Midori or viseversa Please show us the best way to connect to microsoft to ask this from them, or connect us to them, or better than everything ask them to implement this keyboard layout into windows.
FarsiWeb had implemented this layout and this layout is publicly available from here you can download it and use it but please do something for us, we use from a wide variety of unstandard application becouse of this bad kayboard layout that microsoft provided on windows.
there is a good group on google formerly named Persian Computing there are some good guys that can be helpfull for you like Behdad Esfahbod and Rouzbeh PourNader that were in ISIRI 9147 implementation team.I am wonder if you help me, thank you so much , Nasser
Well, let me explain.
Microsoft does not have a subsidiary in Iran, and we don't sell software there.
We aren't allowed to, actually.
And while recent developments like US Lifts Iran, Sudan, Cuba Internet Services Export Ban are interesting (note that this had not yet happened when those two messages were sent to me), the meaning of these initial steps in terms of how companies would engage in reviewing or implementing standards in these countries is not entirely clear.
Note from the announcement that article links to:
U.S. companies can now export instant messaging, e-mail and social-networking tools, blogging software, Web browsers and photo and movie sharing software, as long as the software is publicly available at no cost to the user, the Department of Treasury said in a press release.
It is unclear whether keyboards and such that only go into products that the new guidelines wouldn't cover (i.e. Windows) would in fact be included - I am not a lawyer, but it seems unlikely.
I know I wouldn't just randomly start doing the work before people a whole bunch of levels over me told me it was okay.
So I guess the direct answer to afshar and Nasser as to why Microsoft isn't looking at these standards would be that Microsoft (or at least the small part of it in which I sit!) hasn't been given the okay to be looking into supporting those things.
If and when that changes and Microsoft can more directly engage in-country, some aspects of our support (like LIPs and keyboards and locales and so on) can be targeted more to the new customers in threse markets made available, as opposed to the expatriate market that is the current primary focus....
I remember growing up in Ohio, with several friends heading to Miami University (for college), who would have the shirt that said "Miami of Ohio, Dammit" on the back for those who assumed a Florida connection.
I had a similar one for the University of Pennsylvania that said Penn on the front and "Not Penn State, dammit!" on the back.
You can think of the alternate title of today's blog you are reading (It's Malayalam, which is not the language in Malaysia, darn it!) as a softer version of that same sentiment for the language of the day today!
That particular "mistake" is common enough to be mentioned in the language's Wikipedia page, for what it is worth.
Anyway, here we go....the Malayalam Language Interface Pack for Windows 7 is now available!
It can be installed on any 32-bit Windows 7 system with English resources....
You can download it right here. :-)
And now some background info on Malayalam:
NUMBER OF SPEAKERS: 35 million. Not to be confused with Malay (which is spoken in Malaysia), Malayalam is spoken by approximately 35 million people in the state of Kerala in southern India. It is that state's official language and one of India's official languages. NAME IN THE LANGUAGE ITSELF: മലയാളം FUN FACTS: Malayalam is the longest language name in English that is a palindrome (i.e., it can be read both forward and backward). However, it is not a palindrome in its own script, for three reasons: the third a is long and should properly be transliterated aa or ā (an a with a macron) while the other a’s are short; the two l consonants represent different sounds, the first l being dental ([l̪], Malayalam ല, Roman l) (although the consonant chart below lists that sound as [alveolar]) and the second retroflex ([ɭ], Malayalam ള, Roman ḷ); and the final m is written as an anusvara, which denotes the same phoneme /m/ as in the initial m in this case, but the two m’s are spelled differently (the first m is a normal ma മ with an inherent vowel a, while the last m ം is a pure consonant). The first Malayalam dictionary was created by the German missionary Hermann Gundert, who happens to be the grandfather of Nobel prize-winning German-Swiss author Hermann Hesse. English words of Malayalam origin are teak (taekku) and mango (maanga). Malayalam is one of the language names that was eing mispronounced by people like me when the work to support it was first happening (in Windows XP). We were incorrectly pronouncing it as Mah-lie-ah-lam, and I was explaining that due to the honest efforts on the part of our tam to be respectful that we should rename it to Ma-truth-alam. Luckily our mispronunciation was pointed out before it went too far. :-) Although occasionally cited as an example where cross-script use of letters can lead to confusion in International Domain Names due to the similarity of letter appearance between Tamil and Malayalam, the cited examples often used are for letters that do not in fact look all that similar in any font I have been looking at. But don't take my word for it; you can be the judge yourself: CLASSIFICATION: Malayalam belongs to the Southern branch of the Dravidian languages and is most closely related to Tamil. The Dravidian languages are not related to the Indo-European languages spoken in the north of India (so that the term "Indic languages" is referring to a geographical, not a linguistic group). SCRIPT: Malayalam has a script of its own, an abugida of the Brahmic family. Like in all abugidas, or alphasyllabaries, characters for consonants have embedded vowels (or an extra diacritic showing that there is no vowel).
NUMBER OF SPEAKERS: 35 million. Not to be confused with Malay (which is spoken in Malaysia), Malayalam is spoken by approximately 35 million people in the state of Kerala in southern India. It is that state's official language and one of India's official languages.
NAME IN THE LANGUAGE ITSELF: മലയാളം
FUN FACTS:
CLASSIFICATION:
Malayalam belongs to the Southern branch of the Dravidian languages and is most closely related to Tamil. The Dravidian languages are not related to the Indo-European languages spoken in the north of India (so that the term "Indic languages" is referring to a geographical, not a linguistic group).
SCRIPT:
Malayalam has a script of its own, an abugida of the Brahmic family. Like in all abugidas, or alphasyllabaries, characters for consonants have embedded vowels (or an extra diacritic showing that there is no vowel).
You can find out more about the Malayalam language here.
Enjoy!
If you are someone who is generally annoyed by my blather then you may skip to the code, otherwise I find it all interesting so I don't mind if you do, as well.....
Ok, so I wrote the blog The real problem(s) with all of these console "fallback" discussions to point how backasswards most of the console code out there really is in relation to available Unicode support.
And I wrote the blog Conventional wisdom is retarded, aka What the @#%&* is _O_U16TEXT? to point out how Unicode support was in there, even though no one thought it was.
Then last month I wrote the blog Anyone who says the console can't do Unicode isn't as smart as they think they are where I pointed out that this stuff can work even in places like .Net where people assume it won't.
Now between these three blogs, I am telling a lot of people they are wrong. Including three prior versions of me, each of whom did not know the knowledge in some or all of these blogs.
Now let's pretend that I hadn't written any of these for a moment.
In fact, let's pretend I hadn't even read any of them.
And that I had never heard of Michael S. Kaplan or Sorting it all Out at all.
Just for a moment.
Now further, pretend that I am just as ornery and non-authoritarian as I actually am usually.
My response to these three blogs would be who the hell is Michael Kaplan?!?
I would look especially at that last blog and point out the flaws in the arguments made here, i.e.
There are so many caveats listed there that they could fill a whole 'nuther blog!
and
Sometimes you will still get question marks, other times you will get square boxes, and only occasionally will you get full support of text.
There is not a lot to help you detect which is which!
Those three points alone are all I would need to write all of this off as interesting but not useful for my console applications.
I would demand those blanks be filled in, that the job get finished, or this Michael Kaplan fellow should just quit talking so much. Or writing so much. Or whatever so much.
Today, I am going to try to satisfy that fictional version of me, with a bit of code:
using System; using System.Text; using System.Runtime.InteropServices; public class Test { public static void Main() { if(IsConsoleRedirected()) { Console.WriteLine("You are running in a redirected console.\r\nWrite Unicode via WriteFile and be happy!"); } else { if(IsPowerShellIse()) { Console.WriteLine("You are running in Powershell ISE and can support complex scripts."); } else { if(IsConsoleFontTrueType()) { Console.WriteLine("No PowerShell ISE, but a TrueType font is selected;\r\nyou can at least display some Unicode in CMD."); } else { Console.WriteLine("No PowerShell ISE, no TrueType font; you are limited to one code page."); } } } } internal static bool IsConsoleFontTrueType() { IntPtr stdout = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_FONT_INFO_EX cfie = new CONSOLE_FONT_INFO_EX(); cfie.cbSize = (uint)Marshal.SizeOf(cfie); if(GetCurrentConsoleFontEx(stdout, false, ref cfie)) { return((cfie.FontFamily & TMPF_TRUETYPE) == TMPF_TRUETYPE); } return false; } internal static bool IsPowerShellIse() { uint[] rgpl = new uint[1]; uint siz = GetConsoleProcessList(rgpl, 1); if(siz > 0) { rgpl = new uint[siz]; siz = GetConsoleProcessList(rgpl, (uint)rgpl.Length); for(int pid=0; pid < siz; pid++) { StringBuilder sb = new StringBuilder(260); uint dwSize = (uint)sb.Capacity; IntPtr process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, (int)rgpl[(int)pid]); QueryFullProcessImageName(process, 0, sb, ref dwSize); // Name of EXE is PowerShell_ISE.exe if(sb.ToString(0, (int)dwSize).IndexOf("_ise") != -1) { return(true); } } } return(false); } public static bool IsConsoleRedirected() { IntPtr stdout = GetStdHandle(STD_OUTPUT_HANDLE); if(stdout != INVALID_HANDLE_VALUE) { uint filetype = GetFileType(stdout); if(! ((filetype == FILE_TYPE_UNKNOWN) && (Marshal.GetLastWin32Error() != ERROR_SUCCESS))) { uint mode; filetype &= ~(FILE_TYPE_REMOTE); if (filetype == FILE_TYPE_CHAR) { bool retval = GetConsoleMode(stdout, out mode); if ((retval == false) && (Marshal.GetLastWin32Error() == ERROR_INVALID_HANDLE)) { return true; } else { return false; } } else { return true; } } } // TODO: Not even a stdout so this is not even a console? return false; } [DllImport("kernel32.dll", ExactSpelling=true, EntryPoint="QueryFullProcessImageNameW", CharSet = CharSet.Unicode)] internal static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize); [DllImport("kernel32.dll", ExactSpelling=true)] internal static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll", ExactSpelling=true, SetLastError=true)] internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); [DllImport("kernel32.dll", ExactSpelling=true)] internal static extern bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool bMaximumWindow, ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx); [DllImport("Kernel32.DLL", ExactSpelling=true, SetLastError=true)] internal static extern uint GetFileType(IntPtr hFile); [DllImport("Kernel32.DLL", ExactSpelling=true)] internal static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] static extern uint GetConsoleProcessList(uint[] ProcessList, uint ProcessCount); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct CONSOLE_FONT_INFO_EX { internal uint cbSize; internal uint nFont; internal ushort dwFontSizeX; internal ushort dwFontSizeY; internal int FontFamily; internal int FontWeight; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] internal string FaceName; } internal const uint PROCESS_QUERY_LIMITED_INFORMATION = 0x1000; internal const int TMPF_TRUETYPE = 0x4; internal const int LF_FACESIZE = 32; internal const int STD_OUTPUT_HANDLE = -11; // Handle to the standard output device. internal const int ERROR_INVALID_HANDLE = 6; internal const int ERROR_SUCCESS = 0; internal const uint FILE_TYPE_UNKNOWN = 0x0000; internal const uint FILE_TYPE_DISK = 0x0001; internal const uint FILE_TYPE_CHAR = 0x0002; internal const uint FILE_TYPE_PIPE = 0x0003; internal const uint FILE_TYPE_REMOTE = 0x8000; internal static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); }
First, note that as with the previous blog I am writing Win32 code in C#, to not only let any C/C++ Win32 developer know what to do, but to allow managed developers to be able to support it right away with no delay.
Now there are three important routines here:
IsConsoleRedirected() returns true when your console has been redirected to a file, which means that you can just write everything out as Unicode and call it good.
And when that function returns false, you can move on to the next function.
Because that next function, IsPowerShellIse(), returns true if you are running in PowerShell ISE, a.k.a. The Graphical PowerShell. If you are, then you have full support for Unicode and complex scripts, and anything your application can produce or try to take in. You do not have to be writing in PowerShell ISE to get that support; a Unicode console application can do all the work here, taking advantage of running in this cool modern host, where IMEs and other input methods work irregardless of systm locale and so on.
And when that function returns false, you can move on to the last function.
Because that last function, IsConsoleFontTrueType(), returns true, it means that you are in CMD.EXE but with a TrueType font set. And that means you can display any character the font supports and that the square box that is displayed for the rest of the characters can be copied and pasted somewhere.
And if all three functions return false and you are truly limited to code pages, then you can do what you would have done if none of this support existed.
With all of this support, you can write some kickass and cool console applications that will in every case do the best that the platform can offer the user of the application. Every time....
Now there are other fancy things you (or I!) might want to do like try to change some of those answers, but for now we're going to pretend you are trying to live within the environment you are given. Perhaps some other time all of you non-J. Alfred Prufrock types like myself who would dare to disturb the universe can exercise that bit of psyche and try to change some of the answers that can be changed....
:-)
The title is accurate, I cannot see any part of Tamil Nadu from where I live. But then I'm not running for vice-president of the United States so the "informal" nature of such a bizarre metric on domestic and foreign policy experience leading to me being a poor choice for such a role is unlikely to hamper me too much. Instead I've just gone to the places, which ios clearly less impressive....
Which is good -- because I can forget about all that, and focus on some actual exciting news!
You know, forget about the above, it sounded much cleverer in my head. A place you wouldn't want to live....
So now presenting the thing that everyone (including me) had been waiting for (on, by providence or design, this 150th anniversary of Tagore's birthday) -- the Tamil Language Interface Pack for Windows 7!
It is only being released for 32-bit1, and you must have English resources installed.
And yes, I wish they were releasing a 64-bit version too. As I have mentioned.
You can download that 32-bit version from right here....
This LIP is produced as a part of the Local Language Program! w00t w00t!
And now, a little background information about Tamil:
NUMBER OF SPEAKERS: ~70 million, worldwide NAME IN THE LANGUAGE ITSELF: தமிழ் Tamil is the official language in the southeastern Indian state of Tamil Nadu and also in Sri Lanka and Singapore. It is constitutionally recognized in India and South Africa. Most of its 70 million speakers live in Tamil Nadu (around 50 million) and the neighboring states and in northern and northeastern Sri Lanka (4 million), but there are also significant communities of speakers in Singapore, Malaysia, Mauritius, and South Africa. A purist movement in the 19th and 20th centuries cleaned the Tamil vocabulary from many Sanskrit loan words which can still be found in many other related languages. Tamil, like other Dravidian languages, is an agglutinative language. FUN FACTS: Tamil loanwords in the English language include catamaran (from கட்டுமரம், bundled logs), curry (from கறி, sauce) and pariah (from பறையர், plural of பறையன், outcast). Tamil was classified as the first "classical language" after the creation of this category by the government of India in 2004. One of the criteria for a language for gaining that status is its existence for more than 1,000 years. Tamil can look back at a literary history of at least 2,000 years. CLASSIFICATION: Tamil is member of the group of Dravidian languages which are not related to the Indo-Aryan languages spoken in northern and central India (those belong to the family of Indo-European languages). Its closest relative is Malayalam5. SCRIPT: Tamil has its own abugida script (meaning that it is a syllabic, not an alphabetic script). It has less characters than most other Indic scripts due to the lower number of consonants in the Tamil language (There are neither aspirated nor voiced stops like the English g or f4). It is said that the script developed from the Brahmi script to its own form due to the fact that Tamil was mostly written on palm leaves. This required rounder characters and less dots (which would have pierced the leaves). [note from me - some have suggested that the plam leaves point is an apocryphal bit added to Daniels & Bright years ago, but I have not had a chance to get the true story from anyone yet] You can read more about Tamil here. The sections about old/middle/modern Tamil are paricularly interesting, in my opinion....
NUMBER OF SPEAKERS:
~70 million, worldwide
NAME IN THE LANGUAGE ITSELF:
தமிழ்
Tamil is the official language in the southeastern Indian state of Tamil Nadu and also in Sri Lanka and Singapore. It is constitutionally recognized in India and South Africa. Most of its 70 million speakers live in Tamil Nadu (around 50 million) and the neighboring states and in northern and northeastern Sri Lanka (4 million), but there are also significant communities of speakers in Singapore, Malaysia, Mauritius, and South Africa.
A purist movement in the 19th and 20th centuries cleaned the Tamil vocabulary from many Sanskrit loan words which can still be found in many other related languages. Tamil, like other Dravidian languages, is an agglutinative language.
Tamil is member of the group of Dravidian languages which are not related to the Indo-Aryan languages spoken in northern and central India (those belong to the family of Indo-European languages). Its closest relative is Malayalam5.
Tamil has its own abugida script (meaning that it is a syllabic, not an alphabetic script). It has less characters than most other Indic scripts due to the lower number of consonants in the Tamil language (There are neither aspirated nor voiced stops like the English g or f4). It is said that the script developed from the Brahmi script to its own form due to the fact that Tamil was mostly written on palm leaves. This required rounder characters and less dots (which would have pierced the leaves). [note from me - some have suggested that the plam leaves point is an apocryphal bit added to Daniels & Bright years ago, but I have not had a chance to get the true story from anyone yet]
You can read more about Tamil here. The sections about old/middle/modern Tamil are paricularly interesting, in my opinion....
As I have mentioned in From Seattle (USA) to Coimbatore (India) in June? You betcha! , I will be at Tamil Internet 2010 in Kovai next month, and various other places throughout India. I now have my letters and my visa plus everything else I need. And I am very excited about that. I remembered the Next time, just bring one laptop, Mr. Michael! lesson and am somehow bringing just one laptop this time. Oh, and one iBot, which is neither PC nor Mac5.
Also, for the record, speaking specifically to the points raised in Tamil language support in Windows? You can't SHRII-k yet, but it's getting better, they still did not add SHA to the keyboard, either to fix the SHRII or to just add the letter. Thank goodness for the typography team adding the support, though I occasionally hear rumors of opinions some native speakers have on Latha itself that I'd love to get someone to describe on the record. :-)
1 - Though I am going to convert one of my self-hosting machines into a build machine so I can make a 64-bit version for me at least2. 2 - No I cannot send it to anyone, sorry. Being a full-time employee in the Windows org does have some advantages33 - I also have my own version of Notepad that makes writing a UTF-8 BOM optional!4 - Though as I have discussed previously, Tamil does have a more or less world-wide convention of using the Aaytham as an "F" in loasn words that require the sound,5 - whose LIP was also recently released, as I mentioned in Are MALAYALAM KA & TAMIL KA confusable? Only if you think "all those Dravidians look alike" !6 - Actually it is more of a custom Linux distro on custom hardware, so probably closer in lineage to a PC.
Over in the Suggestion Box, Ben asked:
Like many, I am really enjoying Windows 7. However, there is one little issue that I notice almost daily. As I am constantly switching between English, Japanese, Korean, and Chinese, I usually always "Restore the [IME] language bar" on the desktop. Hence, it is not minimized to the tray. This is my preferred setting. Whenever I watch a movie in Media Player, I set the screen to full size. This works well; however, the IME bar never disappears instead overlays the video. As there is not much opportunity to type anything while watching a movie in full screen, I think it would be best if the IME would become invisible. I do not remember anymore, but I do not recall having this type of problem in XP. Other than manually minimizing it, is there anything that can be done to solve this tiny but constant issue? Not sure if this would be an IME or a Media Player issue.
Like many, I am really enjoying Windows 7.
However, there is one little issue that I notice almost daily.
As I am constantly switching between English, Japanese, Korean, and Chinese, I usually always "Restore the [IME] language bar" on the desktop. Hence, it is not minimized to the tray. This is my preferred setting.
Whenever I watch a movie in Media Player, I set the screen to full size. This works well; however, the IME bar never disappears instead overlays the video. As there is not much opportunity to type anything while watching a movie in full screen, I think it would be best if the IME would become invisible.
I do not remember anymore, but I do not recall having this type of problem in XP. Other than manually minimizing it, is there anything that can be done to solve this tiny but constant issue? Not sure if this would be an IME or a Media Player issue.
One has to love the "one little issue" questions, you know? :-)
First we'll take a step back.
And say that yes, this is a Media Player issue.
Because Media Player can implement UILess Mode for when it is completely maximized if it wants to.
But it isn't doing that, so we have to move on now and see what we can do in spite of that fact.
So we will keep looking, now.
Of course the easiest thing one can do is the minimize/restore dance....
but Ben is already saying that is the thing he's like to avoid.
Now there ianother option, on that same menu.
That Transparency item:
If you select it, then the language bar will be a lot less substantial when you aren't interacting with it.
Like this:
This may or may not be distracting, kind of depends.
That "Vertical" option can also be worth considering, though most people don't like to go that route.
Now if you use your IMEs so often that you do all of the interaction via the various keyboard shortcuts, then you have yet another option.
Hot keys!
Just assign a different hot key to each IME you want to
and then hide the Language Bar completely!
But a lot of people (and I am assuming Ben is one of them) want the Language Bar to be there when they might be using the IME.
And this limits the options a lot more.
Now at an obvious level there is a user interface that lets one pick the "status" of the Language Bar's interface:
This suggests there must be a way for anyone to make that change.
Now spulenking around in the exports of various relevant DLLs finds the following:
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01Copyright (C) Microsoft Corporation. All rights reserved. Dump of file c:\Windows\System32\msctf.dll File Type: DLL Section contains the following exports for MSCTF.dll 00000000 characteristics 4A5BC5DC time date stamp Mon Jul 13 16:40:12 2009 0.00 version 1 ordinal base 71 number of functions 71 number of names ordinal hint RVA name 2 0 0000382C CtfImeAssociateFocus...{skip some exports} 55 35 0001A05C TF_GetShowFloatingStatus...{skip some exports} 68 43 00072ED0 TF_SetShowFloatingStatus...{skip some exports} 71 46 00041470 TF_WaitForInitialized Summary 3000 .data A000 .pdata 18000 .rdata 2000 .reloc 41000 .rsrc A0000 .text
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file c:\Windows\System32\msctf.dll
File Type: DLL
Section contains the following exports for MSCTF.dll
00000000 characteristics 4A5BC5DC time date stamp Mon Jul 13 16:40:12 2009 0.00 version 1 ordinal base 71 number of functions 71 number of names
ordinal hint RVA name
2 0 0000382C CtfImeAssociateFocus...{skip some exports} 55 35 0001A05C TF_GetShowFloatingStatus...{skip some exports} 68 43 00072ED0 TF_SetShowFloatingStatus...{skip some exports} 71 46 00041470 TF_WaitForInitialized
Summary
3000 .data A000 .pdata 18000 .rdata 2000 .reloc 41000 .rsrc A0000 .text
But it hardly seems worth it to try to reverse engineer those functions, which are in all likelihood little more than thin wrappers around the ITfLangBarMgr::ShowFloating and ITfLangBarMgr::GetShowFloatingStatus methods on the ITfLangBarMgr interface.
If the code were any more complicated than something along the lines of:
HRESULT hr; ITfLangBarMgr *pLangBarMgr = NULL; hr = CoCreateInstance(CLSID_TF_LangBarMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfLangBarMgr, (LPVOID*)&pLangBarMgr); if (SUCCEEDED(hr) && pLangBarMgr) { pLangBarMgr->ShowFloating(TF_SFT_MINIMIZED); pLangBarMgr->Release(); }
HRESULT hr; ITfLangBarMgr *pLangBarMgr = NULL;
hr = CoCreateInstance(CLSID_TF_LangBarMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfLangBarMgr, (LPVOID*)&pLangBarMgr); if (SUCCEEDED(hr) && pLangBarMgr) { pLangBarMgr->ShowFloating(TF_SFT_MINIMIZED); pLangBarMgr->Release(); }
(mostly snagged from the interface help topic!) then I would frankly be shocked.
Is it worth creating some little EXE that when run will detect what the state is and toggle it between TF_SFT_MINIMIZED and TF_SFT_SHOWNORMAL?
Well, I would leave that up to Ben or whoever is interested here.
Given an application that doesn't do the work to move the IME out of the way, that would really be the most one can do here....
It is interesting how often there will be two groups of people, each of whom thinks a particular behavior is expected, while another is buggy.
One of those group's bugs are the other's expected behavior. And vice versa.
The funniest part happens when one group is more right than the other, by some objective criteria like overall behavioral impact.
As a final plot twist, a few inconsistencies and confusing KB articles can fan the flames, as well.
Sound like anything you've seen before?
It is a common pattern.... :-)
I'll start with regular reader Jan Kučera from a note in the Suggestion Box:
I don't know why it came so late to me, but I live in a country that is preparing for the euro. So Microsoft eventually releases an update for our culture when ..it happens. You mean that all existing e.g. Excel spreadsheets with currency/accounting data will show up in^H^Hwith euros instead of krowns? I can't believe there were no support calls regarding this. Unless nobody is actually using these formats. :) So any note on how similar transitions works, or if/how multiple currencies per region are handled, would be helpful. Thanks! Jan
I don't know why it came so late to me, but I live in a country that is preparing for the euro. So Microsoft eventually releases an update for our culture when ..it happens.
You mean that all existing e.g. Excel spreadsheets with currency/accounting data will show up in^H^Hwith euros instead of krowns? I can't believe there were no support calls regarding this. Unless nobody is actually using these formats. :)
So any note on how similar transitions works, or if/how multiple currencies per region are handled, would be helpful. Thanks!
Jan
Jan is 100% correct in his concern -- Excel's behavior here that would simply format using the Regional and Language Options formatting without regard for the fact that the intrinsic meaning of the data is changing boggles the mind as something that would quite simply corrupt currency information completely if someone doesn't know to ignore the currency sign completely.
The only time the behavior is not a complete brain-dead bug is when an Excel application is empty of data and shipped to a customer with different settings -- that would the one time that the change shouldn't retain any sense of memory of the fact that you typed in krowns for those monetary values when perhaps you wanted euros. But if you have any data in the spreadsheet, it should retain that memory of what the values were when you typed them in. Any other behavior is potentially very very bad unless you ignore the formatting -- in which case you are better off if it isn't there at all.
There was a scene in TV show Angel where Angel, after having won a certain ring, had earned the right to go to the home office of Hell. He went down a long elevator ride and came out where he started -- because he was already in Hell but had not noticed.
Imagine for a moment that the majority of the business world is run on various Excel spreadsheets.
Then once you snap out of it you will realize you were already in that world.
Because for every application a company pays some consultant to write, there are four dozen Excel spreadsheets that contain all kinds of bsuiness logic in them.
Imagine that just 0.1% of them hold currency values where a reported printed with a changed currency symbol but unchanged values could cause companies to think that THEY were now in Hell.
Scary thought, huh?
Luckily, this really is just a display issue; the symbol imparts no knowledge that would cause programs to behave differently. So beyond a few reports that print values that look to insanely large or too laughably small, the "bug" is more or less contained.
Unfortunately Jan, Excel has no solution here; this is their long-standing behavior.
You basically need to treat it as a number and ignore the currency sign, storing that knowledge elsewhere of whether you are dealing with dollars or euros or yen or whatever. Which is what people mostly do.
So if you look at the nature of the bug here, to fix it on the Excel side you would have had to have each field formatted as a currency value store not only that it is a currency value but also what the Regional and Language Options locale was at the time the value was added.
So it could always remember what it was.
Now as a by the way, no product does this right.
But a related bug (when you change the default user locale, say from en-US to ja-JP) that Excel also has -- and is very serious if you think about the way currency rates fluctuate and are sometimes so very different that you are massively changing the meaning of the numbers -- that bug does not exist in all programs.
If you look at Microsoft Access, it turns out that at least since Access 2.0 and probably before that it has been doing the very "fix" I suggested above: when you set a column's formatting to be Currency it remembers the default user locale when you put in the data. So that if you change your default user locale it does not massively change the meaning of your data.
If there are any Access old-timers around they could verify my recollection on this one, but it was largely through the efforts of Emma, the International Program Manager for Access from Access <= 97 that kept this subtle data corruption bug from being added to the product.
It was intentional, it was by design, and has been for at least since Access 2.0 and maybe earlier.
But you may notice if you look at Microsoft Access and the Ten-Year-Old Currency Bug from a bit over a year ago that Donn Edwards (the author) not only believes the behavior of "silently" making this change to be a bug, but he blames me personally for the behavior.
Even though it was done before I was even doing things with Access as a user in any serious way, let alone on the Access team (and that when I was on the team years later I was not working in that area of the product).
Okay, I'll take one for the team here despite all that, since I have defended the behavior in the past, am defending it right now, and will continue to defend it in the future -- it is the right behavior. Though may still be some nuances for the empty database scenario -- and if there still are I'd be willing to call those bugs since the empty table case reasonably could be expected to behave differently from the case where a table contains rows of currency data -- which I assume is the one I am being vilified for (though the rant goes on for quite a while so I tuned out; perhaps someone else can glean whether there is another complaint there).
To be honest it would make sense to extend the Access behavior to handle Jan's case where the currency within a locale is changed (e.g. from krowns to euros) and store it the same way that the locale is stored now. Because that would help with the migration of existing monetary data. I suspect that making such a change would be controversial, though if I am right everyone could be made happy with some simple changes in the next version of Access (after the one that just came out) to clean up any remaining issues in the empty table case (if there are any; I have not checked).
Then someone could also fix the crazy behavior in Excel, the one that does corrupt data unless one knows to ignore the formatting....
I agree that the documentation here is absent/confusing, and with some of these vicious threads the web isn't much better. Also, this retired KB article is wrong about the old products to which if refers. Not sure what gets done in that case. This other article is a more accurate description of the behavior.
And I have a lot more respect for MVP Allen Browne's take on the issue; he and I disagree, but a lot more respectfully. He at least takes the time to understand the intent and feels that the documented descriptions of the application lead one to make bad decisions since the behavior is not clear. It if for that sake that I hope Access would consider looking into fixing the empty table case (perhaps on Compact, Access could reset the format when there are no rows in the table, or something like that? It is more complicated than that since it would be a behavior change, but an "application deliver" process would be a new feature that could perhaps do this kind of cleanup).
It is interesting to find out that the Internet contained a page with such venomous indictments of me and I never knew about it at all. But I suppose that is the nature of the angry dark side of the web....
Back in the end of February, A2 asked via the Contact link:
Hi Michael. (I already posted this message one or two months ago and can't find if you published it or if you even received it! I wanted to answer to this thread : http://blogs.msdn.com/michkap/archive/2007/01/30/1557184.aspx at the beginning. I prefer now using the contact form system. Sorry if my message bother you, I won't send it again.) So I'm wondering how to have a WOW64 keyboard layout dll using WDK7 (if it's really needed…) I'm on Win7 (x64 machine) with MSKLC 1.4 and WDK 7.0. I'm building Windows drivers for french keyboard layout bepo (http://bepo.fr). Here is where I am with all this. Please correct me if I'm wrong. MSKLC 1.4 generate a .exe, three .msi and four .dll. The .exe only choose the good .msi depending of the computer architecture. Installation or uninstallation only need the good .msi (and one or two .dll for installation). For example, on x86 machines, i386.msi copy \i386\ .dll to \windows\system32\ dir (and add some lines to windows registry). On my x64 machine, the amd64.msi requests two dlls : the one in \amd64\ is copied to \system32\ and the other in \wow64\ to \sysWOW64\. (I read above that the i386 dll was needed for sys32 dir, this is wrong, at last under win7.) I began using kbdutool.exe to build the four .dll in order to bypass one of the MSKLC guy error (can't add underscore in AltGr+space). These dlls can be used with the MSKLC generated .exe/.msi files to have user friendly setup files (overwriting MSKLC dlls). I started to look at the Neo2 german layout (http://www.neo-layout.org/) wich works with WDK and source files. This layout is kindly innovating (using six layers and having a compose-like deadkey) and I wanted to adapt this for our french bepo. I can't find how to build the WOW64 dll to be able to still use older .exe/.msi :*ia64 build environnement builds the ia64 dll;*x64 build environnement builds the amd64 dll;*x86 build environnement builds the i386 dll. I don't have Itanium machine (IA64), I imagine ia64.msi from MSKLC needs at last the \ia64\ dll and probably the \wow64\ one too. If I use the amd64 dll in wow64 dir, the installation fail. The contrary works, it seems logic. For the moment I'm copying the amd64 dll manualy in sys32/64 dirs to have the layout working, adding the good registry entries. The problem being that I'd like to have a clean installer for lambda users. So my questions are :* is there a way to build the wow64 dll with WDK?* where to look in order to have a Windows installer for my WDK dll otherwise? Quickly, another thing I don't understand : it seems that the the file formats needed for .klc files in kbdutool.exe is different then those used by MSKLC? Do you have recommandations about that? (I must convert my .klc to little endian (perhaps something else is better) to be able to use kbdutool.exe -u). — A2
Hi Michael.
(I already posted this message one or two months ago and can't find if you published it or if you even received it! I wanted to answer to this thread : http://blogs.msdn.com/michkap/archive/2007/01/30/1557184.aspx at the beginning. I prefer now using the contact form system. Sorry if my message bother you, I won't send it again.)
So I'm wondering how to have a WOW64 keyboard layout dll using WDK7 (if it's really needed…)
I'm on Win7 (x64 machine) with MSKLC 1.4 and WDK 7.0. I'm building Windows drivers for french keyboard layout bepo (http://bepo.fr). Here is where I am with all this. Please correct me if I'm wrong.
MSKLC 1.4 generate a .exe, three .msi and four .dll. The .exe only choose the good .msi depending of the computer architecture. Installation or uninstallation only need the good .msi (and one or two .dll for installation). For example, on x86 machines, i386.msi copy \i386\ .dll to \windows\system32\ dir (and add some lines to windows registry).
On my x64 machine, the amd64.msi requests two dlls : the one in \amd64\ is copied to \system32\ and the other in \wow64\ to \sysWOW64\. (I read above that the i386 dll was needed for sys32 dir, this is wrong, at last under win7.)
I began using kbdutool.exe to build the four .dll in order to bypass one of the MSKLC guy error (can't add underscore in AltGr+space). These dlls can be used with the MSKLC generated .exe/.msi files to have user friendly setup files (overwriting MSKLC dlls).
I started to look at the Neo2 german layout (http://www.neo-layout.org/) wich works with WDK and source files. This layout is kindly innovating (using six layers and having a compose-like deadkey) and I wanted to adapt this for our french bepo.
I can't find how to build the WOW64 dll to be able to still use older .exe/.msi :*ia64 build environnement builds the ia64 dll;*x64 build environnement builds the amd64 dll;*x86 build environnement builds the i386 dll.
I don't have Itanium machine (IA64), I imagine ia64.msi from MSKLC needs at last the \ia64\ dll and probably the \wow64\ one too.
If I use the amd64 dll in wow64 dir, the installation fail. The contrary works, it seems logic.
For the moment I'm copying the amd64 dll manualy in sys32/64 dirs to have the layout working, adding the good registry entries. The problem being that I'd like to have a clean installer for lambda users.
So my questions are :* is there a way to build the wow64 dll with WDK?* where to look in order to have a Windows installer for my WDK dll otherwise?
Quickly, another thing I don't understand : it seems that the the file formats needed for .klc files in kbdutool.exe is different then those used by MSKLC? Do you have recommandations about that? (I must convert my .klc to little endian (perhaps something else is better) to be able to use kbdutool.exe -u).
— A2
It was Igor Levicki who figured out how to get the WOW64 version of the files built.
It is in If you just don't think you can hold it (64-bit style!), in this comment:
Well, because I hate to leave things half-finished I dug out the right way to deal with that issue during compilation :) It is just a matter of compiling using 32-bit compiler with -DBUILD_WOW6432. So now I have the complete solution.
He integrated it into his full page with instructions, which used to be at http://levicki.blogspot.com/2006/09/how-to-build-keyboard-layouts-for.html but now is on his new site, at http://levicki.net/articles/tips/2006/09/29/HOWTO_Build_keyboard_layouts_for_Windows_x64.php and I am glad as the full story is worth having. :-)
Anyway, as Igor determined, the WOW64 file is built with:
You can look to Igor's site for the other details.
For those who want to understand the BUILD_WOW6432 issue, it is relatively simple.
Almost all of the files you will find in the SYSWOW64 directory of a 64-bit machine are actually the 32-bit files that exist on a 32-bit i386 machine.
Because just the same way that your 32-bit apps can run on 64-bit hardware, most of the system's files do as well.
HOWEVER, there are a small number of files that are 32-bit files that have to deal with 64-bit pointers because of the nature of the work they do on 64-bit systems (where those pointers have to do 64-bit thunks) that requires a different pointer size to be used for exported functions that have pointers in their parameter and/or return values.
This includes kernel32.dll, user32.dll, all of the keyboard layout DLL files, and other core system files.
Some but not all of the system files would have to be built this way for the SYSWOW64 subdirectory, but the bulk of these files are not built in the WDK or by anyone outside of the Windows team, which is why this is not documented better.
In fact in the Windows 7 RTM build, there are fewer than 200 such files out of the ~2500 files in the syswow64 directory, and almost all of those (like ~95%) are keyboard DLLs!
(If you build Windows, you can check these out in the WOW6432 subdirectory)
The actual utility of all this may be somewhat questionable given the fact that the pointers in question are really just sign-extended 32-bit pointers (as discussed in 32 bit vs. 62 bit HKLs?), but as an arcane build issue that no one really understands it is unclear whether it would be worth doing anything different about, in the long run. I suspect there are a few oldtimers who might be able to explain why this makes the whole thing easier....
During Vista, it certainly caused me (as the dev owner of the keyboard layout DLLs) some interesting extra work as the problem of building setup manifests to handle these files was very complicated since the new setup didn't really support the idea at first and the ways that various experts instructed me to author the files tended to break the validation scripts that the same team kept building to improve setup quality. Thank goodness for Perl scripts is all I'm going to say!
Gerardo on the test team was the person to find out directly how the first two of the five setup manifest iteratons (authored by the instructions of the setup team) actually led to the wrong versions of keyboard layout files being put in the SYSWOW64 directory of 64-bit machines. Though those manifests were the only ones that never failed validation routines like te next two versions that did. Kind of ironic that only the invalid manifests were validaing properly (as the valid manifests kept failing validation), huh?
As a bizarre final twist, after Vista shipped and shortly after I changed teams, yet another set of setup manifest validation tools declared all of the keyboard manifests were incorrecrly authored (and CompCentral declared me to be the owner of these many wayward binaries), but at that point the work had been transitioned to someone else so I gaqve the bugs to them with instructions and avoided having to do the work yet again.
Igor may be the first non-internal Microsoft person to ever figure it out. Internally most don't figure it out either, they just build the files using scripts written ages ago and never pay attention to the details. I certainly never knew about it until doing the 64-bit work for MSKLC 1.4, despite having built the keyboards hundreds of times and kernel32.dll thousands of times; when I finally did it, it was by reverse engineering the keyboard layout DLLs being built by Windows....
I believe that covers most of the question, though a few more bits to add:
I suppose IA64 is not really so important anymore. I won't say anything else on this subject, other than to (not for nothing) mention that if software tech companies were run entirely by women there are certain types of strategies that probably would never happen. Intel's IA64 plan is one of them and the Compaq plan for Alpha 64 and Alpha 32 are two others, in my opinion. I won't explain further; either you understand what I mean or you don't (and if you don't you might be offended once you do; if you do then you may agree!). So I'll just leave it there.
Microsoft does not, AFAIK, document any way to get the keyboard layout DLLs running other than MSKLC. Though obviously there are WDK samples for the DLLs, there is real dearth of info on how to get them installed on systems. The setup MSKLC creates takes care of all of the details, and I highly recommend taking that approach for building setups.
The files MSKLC creates are the very ones it passes to kbdutool.exe itself for building. It should already be little endian Unicode, for example. Not sure what kind of errors are being hit, but if MSKLC and kbdutool were not compatible then (looking at the latest download statistics) there would be up to half a million unhappy keyboard authors out there! So I am not sure what problems were appening but there shouldn't be.
Hopefully that takes care of all the issues for A2, if not then let me know; I'm around. :-)
An interesting hypothetical came up the other day.
Let's say that the Windows 7 install base is around 100 million users.
It isn't exactly that, but it makes the percentages easier so we'll go with it since I am going to throw some percents out for you to consider.
And I am not trying to give you overly complicated math problems.
Get it? I am doing ths FOR YOU.
Anyway....
Let's say you found a bug in a specific calendar. You know, in one of these calendars:
Calendar identifier Meaning 1 CAL_GREGORIAN Gregorian (localized) 2 CAL_GREGORIAN_US Gregorian (English strings always) 3 CAL_JAPAN Japanese Emperor Era 4 CAL_TAIWAN Taiwan calendar 5 CAL_KOREA Korean Tangun Era 6 CAL_HIJRI Hijri (Arabic Lunar) 7 CAL_THAI Thai 8 CAL_HEBREW Hebrew (Lunar) 9 CAL_GREGORIAN_ME_FRENCH Gregorian Middle East French 10 CAL_GREGORIAN_ARABIC Gregorian Arabic 11 CAL_GREGORIAN_XLIT_ENGLISH Gregorian transliterated English 12 CAL_GREGORIAN_XLIT_FRENCH Gregorian transliterated French 23 CAL_UMALQURA Windows Vista and later: Um Al Qura (Arabic lunar) calendar
We will assume for the sake of argument that we are not talking about the first, second, or third entries in the table. Since we aren't..
It is not an algorithm problem, just something displaying kind of wrong. Not exactly a misspelling. And not a typo. But if it had been something like that, the results would be similar.
Just so you can screw your head on straight about the problem. I'm not asking you to fix the oil spill here.
So if you wanted to ship an update to fix the bug but you figured only a specific (small) percentage (I won't give the actual number, assume it is less than 5%) of the 100 million were going to be affected, how would you detect what users are most likely to be impacted?
Bear in mind all of the following data points:
So now for the hypothetical:
What would you recommend here?
1) Would you recommend deploying the fix?
2) If the answer to #1 is YES, would you limit the number of machines who would be offered the fix?
3) If the answers to #1 and #2 are YES, how would you craft the limit, exactly? (be sure to properly balance accuracy of hitting the target market and simplicity of the fix to minimize flaws in the design of the filter!)
4) Would any of the above answers change if the impact were not 5% but instead 10%? 20% How about 1%?
5) Can you name both sources of the quote I modified for the title, without looking them up anywhere?
I have obfuscated enough details in the above to make it a proper hypothetical (plus everything is already figured out, so no opinion could weigh any actual decision to be made!) and although I am asking you what you would do as if you are the lone person deciding, in reality there is no one person who makes this call and even the most expert person would be a single voice that would have to have any opinion weighed in terms of how well that person could back up the opinion to a triaging group. And how well they could get people to pay attention, of course.
Anyone want to share how they would answer those five questions, especially the first four? :-)
Of course then after you answer that I have to point out that, as it turns out, architecturally the update process cannot detect all of the possible detection vectors listed above, which lead to a sixth question:
6) If the best possible fix is not available, is a less-good fix that will get some hits acceptable? Metaphorically, you could imagine it like testing for H1N1 by testing for other varieties of seasonal flu; you will get some hits, but you will miss some people who definitely have the bug....
Your thoughts on questions 1-4 and question 6 would be appreciated. The answer to question 5 (if you didn't cheat to get it!) would tickle, at least....
So, where do I start?
Oh yes, I remember.
The .Net Framework's first and in the minds of some still respectable to be using right now UI technology, WinForms.
Windows Forms.
There is a particular feature they have, an AutoSize feature. When used (and used properly) it tremendously lightens the burden on localization since it will resize forms and controls to fit the text they contain.
Note the "used properly" notation there. This is important as I know of a project or two (or ten, or twenty!) that are part of a tiny little product you have never heard of called Windows that didn't really tend to do it right.
Which is not the end of the world. Not for you, or for me, or for the developers who created the forms, or for the localizers who had to do some resizing when text would truncate.
Everyone continued to function normally.
I guess the localizers had to work a little harder.
So no big deal right?
Right.
Oh wait, I forgot something.
Something about this AutoSize feature.
Now obviously a developer who was trying to use this feature might want to exert a little control over what it does, right?
I mean, letting people do stuff with no safety controls over how much they do leads to derivative market inspired economic collapse or unprecedented oil spills.
We know we don't want our WinForms to be all bankrupt and oily. So some ability to rein in the way that things might want to grow can make a little sense.
Of course the complexity of those ways to control the unprecedented growth is one of the big reasons why the AutoSize feature was so poorly utilized.
Why Windows became the son and heir to more than just a shyness that is criminally vulgar; it also inherited a whole bunch of oily, bankrupt WinForms applications.
The Smiths would be so disappointed.
But that is not the principal issue I wanted to discuss.
I really wanted to talk about the localization process, and then a couple of the properties that the original developers have to help rein in AutoSize if they believe they have a need to, and how all of that fits together.
The process, in a nutshell:
Easy, right?
Well, there was a problem or two.
Or more.
But for the moment I'll just talk about one or two of them.
Now one way that the developer can exert some control over the AutoSize beast is by use of the Control.MaximumSize and Control.MinimumSize properties.
These properties can be used to keep the difference between the original Control.Size and the eventual size from going way beyond what the developer ever really wanted.
That really does make sense (well, the Control.MaximumSize more than the Control.MinimumSize, but they both make at least some sense). And I would never want to imply otherwise.
Everything still looks okay, right?
Well, let me include the spanner in the works.
Those two properties? Control.MaximumSize and Control.MinimumSize?
They are not included in the localizable .ResX.
This leads to three specific problems:
Now the combination of these first two factors often leads (as you can perhaps imagine) to the kind of bug that goes back and forth several times between the localizer fixing the truncation bug and the tester reporting it with the kind of "the problem is fixed"/"no it isn't" kind of argument that so often can come from looking at two different things and thinking they are the same.
Or make it a core bug -- perhaps only found after everything has been frozen and no one is willing to make changes.
Okay.
Fair enough.
Now with all that said, in the world of Visual Studio, this bug is not such a big deal.
I mean, from their point of view it is really quite unreasonable to even set Control.MaximumSize or Control.MinimumSize to a size that could break localization; in fact, one of the more senior people I talked to about this bug couldn't even see why anyone would set either property in a form meant to be localizable.
Of course I don't know of any other reason why one would set it, which means that someone was admitting to me that the property was a bad idea! But that can be a subject for another day... :-)
Now the WinForms people are not being arbitrary about this judgment; the bug, which has existed since the very initial 1.0 version of the .Net Framework and WinForms, has (I am told) never ever been reported by any other customer external or internal to Microsoft.
Just Windows.
Now to Windows it led to hundreds of bugs (and no, this is not an exaggeration; the actual number is even higher though the "even higher" part is due in part to other problems that I'll talk about in some future blog).
Pain in the butt bugs with all those back and forth problems and difficulty pinning the problems down. And so forth.
Windows actually shipped with many of these bugs only partially fixed or worked around.
And some of the worst of the offenders in the dialogs are known by name to people on the localization team, since they know how many bugs they can expect to have to deal with any time one of them is changed.
But reportedly no one else has ever complained about the problem. Ever.
So, okay.
Eventually there will be a fix for this problem, a fix that I guess no one outside of the internal Windows team even cares about, since no one else apparently ran into the problem.
And there will be a KB article describing it (I'll link to it once I find it exists). In case it turns out anyone wants it.
From a social engineering standpoint I wish I had the time, resources, and knowledge to study the factors that can cause a bug to so hugely impact multiple developers spread across teams and groups and divisions and even continents within one large product while never affecting any other project in the entire world.
I can't even try and fathom that one; in fact I get a headache just thinking about it....
It has been almost a week since the new platform was rotated in, with its new version of Community Server and the new look and feel for MSDN Blogs and TechNet Blogs.
Raymond Chen included a Welcome to The New Old New Thing, 2010 edition for when the new site went live, and although I have done blogs like that in the past, I decided not to this time.
Since most of the problems pointed out get fixed right away anyway.
Anyway, if you find anything that looks wrong, from missing images to incorrect links to unreadable formatting in the thousands of blogs on this Blog, let me know. I'll try to fix it up.
On the whole I can't claim to be especially happy with the change; there is too much stuff that just looks wrong to me and that I really miss, especially things like collapsible panels. I'll get used to it eventually, or else eventually I'll dive in and figure out how to add them back (or Raymond will, he has threatened to do it already at least once!), but fotr the most part I am much more interested in adding stuff to the blog itself (aka CONTENT) rather than in the Blog (aka FRAMEWORK).
Maybe if the Blog were about blogging itself I'd have a different take on all of this.
So, getting back to the content....
I have been oscillating back and forth between being over a month ahead on blogs to being less than a day or two ahead.
The former is a bad thing for me since I keep going back and reshuffling and editing, which wastes time. The latter is kind of fun since I never know what I'll will see here until after its up.
It's weird, but the other day someone was asking if I would do some trainings for them and she kind of started the request off with "As one of the most popular faces in the Globalization world" which I am pretty sure made me blush when I read it; that sort of thing doesn't integrate cleanly with my own self-image.
But if more people are going to look at me as being less an outlier and more of an actual something or other in the space, I suppose I should pay them the compliment of taking it a little more seriously. :-)
One of big "backend changes here in the content department" is that for the first time ever I have a management structure above me that actually looks at Sorting it all Out as an asset to the group. This change has both good points and bad points to it, though the benefit of being able to write during normal hours while at work alone outweighs most of the bad I could list.
I suppose that has added a bit more discipline to the content adding process.
There is a part of me that realizes I could have moved the entire blog somewhere else during that period when I had management that didn't care that much for the blog, leaving nothing but a single-page pointer to the new location. Too late for that now!
I will get around to removing some of the specific "disclaimer" text I was required to add from that time when I was a little less appreciated than I am now. No hurry, just something I will have to get to eventually.
If you are a regular (or a consistent even though irregular!) reader than thanks for your support, I really do appreciate it.
If you count back to the very first blog here in the end of 2004 (very few of you can make that claim, I mostly know who you are though!), it has been a very long, strange trip.
And who knows what it will look like tomorrow? :-)
Okay, a little Spot the Bug for everyone on a Monday morning when one shouldn't need to be working anyway....
The other day a question came up about some code.
It looked something like this:
whcar_t* newParams = new wchar[MAX_PATH + MAX_PATH]; whcar_t* p = newParams; while (*params) { *p++ = *params; params = ::CharNext(params); } *p = 0; return newParams;
Can you figure out what this code is doing? Assume it is compiled with UNICODE (since the compile would fail, otherwise!).
Well, I know what it is doing. The key is trying to understand what it was trying to do.
You can probably gather why whatever they were trying to do is doomed to failure, of course.
Also, you can look at previous blogs like The torrents of breaking CharNext/CharPrev if you want a quick refresher, of course.
Ignore the bug mentioned there, and think about what CharNextW does.
So, what does the code do, and what did the original authors want it to do?
Please excuse the South Park reference. And the probably terrible transliteration!
"You hear that Mr. Anderson?... That is the sound of inevitability... It is the sound of your LIP..." -- Agent Smith, talking to Neo in The Matrix....
You knew it was going to happen.
It was inevitable.
But like in a good way.
The Kannada Language Interface Pack for Windows 7 is now available!
Currently only in 32-bit, and you must have English resources for language fallback.
You can download it from right here....
The Kannada Windows 7 LIP is produced as part of the Local Language Program sponsored by Public Sector.
And now a little background information about Kannada:
NUMBER OF SPEAKERS: 45 million speakers NAME IN THE LANGUAGE ITSELF: ಕನ್ನಡ Kannada is the state language of Karnataka, where it is mainly spoken, and one of India's many official languages. Sometimes also called Kanarese, Kannada is one of the Dravidian languages spoken in the South of India. It has about 20 dialects which can differ considerably, though the written form is rather consistent throughout. FUN FACTS: Works of Kannada literature have received seven Jnanpith awards, which is the highest number awarded for the literature in any Indian language. Several transliteration schemes/tools are used to type Kannada characters using a standard keyboard. Nudi, the government of Karnataka's standard for Kannada Input, is a phonetic layout loosely based on transliteration. Kannada has a non-trivial number of loan words from Sanskrit and Marathi, by report many relate to feudalism and militia. The language (and script) is almost perfectly phonetic, but for the sound of a "half n" (which becomes a half m). A few letters have dropped out of the language over the years: ಱ ('ṟ' or 'rh'), which dropped out in the 12th century. Later Kannada works replaced 'rh' with ರ (ra) ೞ ('ḻ', 'lh' or 'zh'), which dropped out in the 18th century. Later Kannada works replaced 'lh' with ಳ (la) ( 'nh' or 'inn'), which as observed until the 1980s. This letter has been replaced by ನ್ (consonant n) CLASSIFICATION: Kannada, together with Tamil, Malayalam and others, belongs to the Southern group of the Dravidian languages. These form a language family on its own. Its languages are spoken on the Indian subcontinent, but are not related at all to Indic languages of the Indo-European family (like Hindi): The Dravidian languages are agglutinative (Words are formed by joining morphemes together) and have the interesting feature of an exclusive "we" (in which the addressee is not included). To some this is known as "The Medical We", like in a doctor who says to the patient "How are we feeling, today?". SCRIPT: Kannada is written in its own script, which is also called Kannada. The Kannada script is also used to write several other languages in Karnataka, such as Tulu, Kodava Takk, Beary bashe and Konkani.
45 million speakers
ಕನ್ನಡ Kannada is the state language of Karnataka, where it is mainly spoken, and one of India's many official languages. Sometimes also called Kanarese, Kannada is one of the Dravidian languages spoken in the South of India. It has about 20 dialects which can differ considerably, though the written form is rather consistent throughout. FUN FACTS: Works of Kannada literature have received seven Jnanpith awards, which is the highest number awarded for the literature in any Indian language. Several transliteration schemes/tools are used to type Kannada characters using a standard keyboard. Nudi, the government of Karnataka's standard for Kannada Input, is a phonetic layout loosely based on transliteration. Kannada has a non-trivial number of loan words from Sanskrit and Marathi, by report many relate to feudalism and militia. The language (and script) is almost perfectly phonetic, but for the sound of a "half n" (which becomes a half m). A few letters have dropped out of the language over the years: ಱ ('ṟ' or 'rh'), which dropped out in the 12th century. Later Kannada works replaced 'rh' with ರ (ra) ೞ ('ḻ', 'lh' or 'zh'), which dropped out in the 18th century. Later Kannada works replaced 'lh' with ಳ (la) ( 'nh' or 'inn'), which as observed until the 1980s. This letter has been replaced by ನ್ (consonant n) CLASSIFICATION: Kannada, together with Tamil, Malayalam and others, belongs to the Southern group of the Dravidian languages. These form a language family on its own. Its languages are spoken on the Indian subcontinent, but are not related at all to Indic languages of the Indo-European family (like Hindi): The Dravidian languages are agglutinative (Words are formed by joining morphemes together) and have the interesting feature of an exclusive "we" (in which the addressee is not included). To some this is known as "The Medical We", like in a doctor who says to the patient "How are we feeling, today?". SCRIPT: Kannada is written in its own script, which is also called Kannada. The Kannada script is also used to write several other languages in Karnataka, such as Tulu, Kodava Takk, Beary bashe and Konkani.
ಕನ್ನಡ
Kannada is the state language of Karnataka, where it is mainly spoken, and one of India's many official languages. Sometimes also called Kanarese, Kannada is one of the Dravidian languages spoken in the South of India. It has about 20 dialects which can differ considerably, though the written form is rather consistent throughout.
Kannada, together with Tamil, Malayalam and others, belongs to the Southern group of the Dravidian languages. These form a language family on its own. Its languages are spoken on the Indian subcontinent, but are not related at all to Indic languages of the Indo-European family (like Hindi): The Dravidian languages are agglutinative (Words are formed by joining morphemes together) and have the interesting feature of an exclusive "we" (in which the addressee is not included). To some this is known as "The Medical We", like in a doctor who says to the patient "How are we feeling, today?".
Kannada, together with Tamil, Malayalam and others, belongs to the Southern group of the Dravidian languages. These form a language family on its own. Its languages are spoken on the Indian subcontinent, but are not related at all to Indic languages of the Indo-European family (like Hindi): The Dravidian languages are agglutinative (Words are formed by joining morphemes together) and have the interesting feature of an exclusive "we" (in which the addressee is not included).
To some this is known as "The Medical We", like in a doctor who says to the patient "How are we feeling, today?".
Kannada is written in its own script, which is also called Kannada. The Kannada script is also used to write several other languages in Karnataka, such as Tulu, Kodava Takk, Beary bashe and Konkani.
Web developer Matt's question was to my way of thinking a very reasonable one:
Hi all… Is there any way to automatically change the UI culture for every background thread that .NET creates? At application startup we force the UI culture on the main thread since our application is localized independently of the OS. This works fine for exceptions that we throw from the UI thread – we’ve already forced the culture and so we look up the resource strings in the application language, instead of the OS/.NET language. However, we’ve added a bunch of multithreading this release and noticed that all of the exceptions on the background threads aren’t getting localized since we haven’t forced the culture on those threads. It would be a LOT of work to go force the thread culture EVERYTIME we create a thread. We’re also using the TPL extensively so it’s not even clear when threads are being created since we’re not explicitly creating them ourselves – the TPL is! With the move to more parallel applications, this seems like something that other applications must have run into, so I’m wondering if there’s any way to hook into the framework to override the default culture for all new threads? One response: No. There is currently no way to make this happen. Your option will be store the culture in a static variable and use that culture to load resources on the background thread. Right – except that once the TPL comes into play I don’t even KNOW when I’m on a background thread or not, or if the culture has already been forced on said thread. It also requires driving knowledge of the application’s localization strategy into EVERY single piece of code that runs in the application – I now have to pepper calls to force the culture like spaghetti all over the place into every single piece of code that could conceivably run on a background thread, which just seems like a terrible, terrible mess. With the advent of much more parallel programming, this sounds like it could be a nice scenario for the framework to help with by providing me with some way to tell the framework how to force the culture for all new threads.
Hi all…
Is there any way to automatically change the UI culture for every background thread that .NET creates?
At application startup we force the UI culture on the main thread since our application is localized independently of the OS. This works fine for exceptions that we throw from the UI thread – we’ve already forced the culture and so we look up the resource strings in the application language, instead of the OS/.NET language. However, we’ve added a bunch of multithreading this release and noticed that all of the exceptions on the background threads aren’t getting localized since we haven’t forced the culture on those threads.
It would be a LOT of work to go force the thread culture EVERYTIME we create a thread. We’re also using the TPL extensively so it’s not even clear when threads are being created since we’re not explicitly creating them ourselves – the TPL is!
With the move to more parallel applications, this seems like something that other applications must have run into, so I’m wondering if there’s any way to hook into the framework to override the default culture for all new threads?
One response:
No. There is currently no way to make this happen. Your option will be store the culture in a static variable and use that culture to load resources on the background thread.
Right – except that once the TPL comes into play I don’t even KNOW when I’m on a background thread or not, or if the culture has already been forced on said thread. It also requires driving knowledge of the application’s localization strategy into EVERY single piece of code that runs in the application – I now have to pepper calls to force the culture like spaghetti all over the place into every single piece of code that could conceivably run on a background thread, which just seems like a terrible, terrible mess.
With the advent of much more parallel programming, this sounds like it could be a nice scenario for the framework to help with by providing me with some way to tell the framework how to force the culture for all new threads.
This is a question that is asked fairly often.
And although I have mentioned in blogs like New for Windows 7: The PROCESS to keep MUI from being THREADbare.... how .Net really could and in fact ought to be doing something better here, another question comes to mind, one that is perhaps due to my Win32 grounding and the straightforward nature of the web applications and sites I have been tasked to design.
In Win32, the UI is by its nature meant to be very single threaded even in the most complex multi-threaded applications. And any time something must be done in another thread complex interactions have to be done for the application to behave reliably.
Thus as big of a fan as I am of the process default user interface language, I hardly need for every thread in a threadpool to be updated since most of those worker threads are probably doing nothing where the user interface language is even relevant.
Now I may be missing something in the web scenario, or perhaps there is some sort of nut-job object oriented purity objection to an object like thread having to know more about some external setting to do its work, but is its really that common for so many worker threads to be doing things that need the UI language, and that retrieving the value is such a bad idea technically?
I mean, I will be happy when they solve the problem, but my happiness is based on a scenario that seems much more defensible to me.
In Matt's scenario, are the errant threads all popping up their own UI every time? I think I have seen those kinds of web sites, the ones that pop up random alerts one on top of the next, without waiting for me to respond. My rule is to avoid those kind of sites, but maybe that is just me....
In the world of a complex web application that spans multiple servers and has thousands or tens of thousands of clients, each client's settings that are relevant to work done for the client will have to obtain whatever settings they need -- and language is just another of these settings that a lowly threadpool thread will have to obtain to do its work.
Is there some other scenario I am unaware of?
What am I missing here?
Now at long last I can point everyone to the Indonesian Language Interface Pack for Windows 7!
It is available for both 32-bit and 64-bit systems, and you can get it right here.
Yet another LIP brought to you by the Local Language Program,. sponsored by public Sector.
Indonesian is a huge market that is growing very fast (as befits the language known by such a uge percentage of all the people of Indonesia, in the fourth largest country in the world!).
A little background information on Indonesian:
30 million native, 140 million second language speakers
Bahasa Indonesia
Indonesian is the official language of Indonesia since the country's independence in 1945. It is spoken by about 30 million native speakers, mostly on the island of Java, while another 140 million use it as a second language in the multilingual archipelago. Most formal education in Indonesia is in Indonesia as are nearly all national media, and the government is promoting the language.Linguistically spoken, it is a variant of a diasystem, representing a standardized dialect of Malay, which has been a trade language in the region for at least a thousand years. While Malay borrowed many words from English in colonial times, Indonesian was influenced by Dutch. The word for exhaust pipe demonstrates this very strikingly: it is knalpot in Indonesian, but ekzos (from exhaust) in Malay. Today, many words from other languages spoken in Indonesia, most prominently from Javanese, are finding their way into the Indonesian language.
As in Bahasa Melayu (Malay), the Bahasa in Bahasa Indonesia simply means language, so shortening the name to Bahasa does not make any sense.
Indonesian shows the influences of many languages in its vocabulary: A lot of different peoples coming into the area brought new concepts and left their traces:
From Sanskrit, words like agama (religion), bahasa (language) or pustaka (book) were borrowed; Arabic left kitab (book) or halal (lawful); portuguese keju (cheese, from queijo), mentega (butter, from manteiga), sepatu (shoe, from sapato), or jendela (window, from janela); Dutch more than 10,000 words, among them kantor (office, from kantoor), rekening (account, from rekening), kartu (card, from kaart), apotek (pharmacy, from apotheek) or buku (book, from boek).
As the word book, appearing three times in the list above, shows, Indonesian often draws from different foreign sources and the different loanwords can have slightly different meanings.
Indonesian belongs to the Western Malayo-Polynesian languages, along with languages like Javanese, Balinese, which are also spoken in Indonesia, Malagasy, spoken in Madagascar, or Tagalog, spoken in the Philippines. The Malayo-Polynesian languages form a subgroup of the Austronesian language family.
Indonesian is written in Latin script. In 1972 Indonesia and Malaysia agreed on a unified spelling for Bahasa Indonesia and Bahasa Melayu. The Indonesian spelling until then had still shown major influences of Dutch, like the tj which was used for the sound in the beginning of the English chin, or the dj.
For more information on Indonesian, click here.
Nothing technical in the work sense, you know the drill. Or should....
So one of the things that you can have if you work for Microsoft used to be a FlexPass to let you ride on Metro Transit or Sound Transit.
You know, a perk that is a way to encourage people to do The Right Thing™ in regard to not driving every day, etc.
As someone who seldom drove even when I had a car (before it died a few years ago), this was a tremendous boon.
Such a boon that once my car did die, I simply decided to try pretty more "independent of oil", only occasionally using a ZipCar or a taxi but usually either wheeling there with the iBot or taking the bus.
Then Seattle got rid of the FlexPass and moved to ORCA (One Regional Card for All).
Of course some people didn't like the "track-ability" that could be used with ORCA, and the promises that Microsoft made to never do anything like that were treated by people like me as cynically as one might expect.
But that was no biggee, I am used to my cynicism; that is The Right Thing™ for me.
But the bigger problem was that to get the ORCA I was "signing" an agreement that it would be used principally to get to and from work.
It didn't say exclusively, but the language implied (to me, a non-lawyer) that at least 51% of the time it would be work-related travel and/or travel to/from work.
Now I live across the street from work.
I can get to my office in under ten minutes in the iBot in Standard mode, and under twenty minutes in Balance mode (up on two wheels).
If, at the moment I head out my door, it is not beautiful weather and a 233 or 269 or 242 happen to be 30 seconds away, I'll take that bus four stops and get to work quicker. And the same thing going home. And if the bus is more than 2 minutes away I won't bother.
But most of my bus travel is to Kirkland, and Bellevue, and Belltown, and Capitol Hill, and Pioneer Square, and Ballard, and Fremont and so on.
If I was going to have to pay for some of the buses, I'd rather get the handicapped rate - which is roughly half. I'm just saying, you know?
But the ORCA I got from Microsoft wasn't that -- it was full fare ORCA.
I could put money on it for personal travel, but I'd be paying twice as much, every time I used it.
So I talk to the commute people at Microsoft and explain my dilemma. And I ask how to get the RRFP (Regional Reduced Fare Permit) ORCA, which would save Microsoft some money anyway, and let me save money when I had to pay.
They are shocked.
Which shocks me a bit.
Apparently it has never occurred to any of the people who "sign" that agreement that they might actually follow its guidelines. Or at least no one asked about it.
And they do nothing for RRFP or handicapped or over 65 stuff -- they just pay for the card and that is that.
So this is apparently The Right Thing™.
Of course I saved the email where I was explicitly told to not worry about violating the rules of the agreement. Just in case someone ever checked my usage later and saw how I was going all those places that weren't work (out of 100 trips that cross th bridge, maybe one or two is work-related -- maybe ten if it is just getting to work in the morning when I stayed over on the wrong side of the bridge!).
I have talked to a couple of the bus drivers, and they just suggested I scan the card every other time, which would make the money come out right. But that seems wrong too. That isn't The Right Thing™.
And since there is no way to get a RRFP ORCA with corporate sponsorship unless the company does the work, I am costing them a bit more money than I would have otherwise. I offered to try and reduce that but they declined. Because that wouldn't be The Right Thing™ either.
I can't help but feel a little disconnected from reality on all of this. Like every step of the way I try to do what seems like The Right Thing™ and I am told not to bother....
I can't decide if my moral compass is being magnetized, or if I just don't fully understand what The Right Thing™ is.
In other news (following up from that Arising from one's own ashes. Like [up to 80% of ]a phoenix.... blog from the end of April:
First an entirely gratuitous repeat of the Elvira shot:
The reason for that was that every person who talks to me about this drug officially other than the drug company is mispronouncing it. They want it to rhyme with Elvira!
I have received the Ampyra, and am taking it now. Well, not right now, but about every 12 hours.
Now insurance picked it up 100% -- but I swear I had to talk to a nurse in my neurologist's office, someone from the Ampyra company, someone from Medco, and someone from the specialty pharmacy entrusted to deal with expensive medicines (whose name I can't remember). Each one of them had checked with the insurance company itself and wanted to make sure it wasn't an error that insurance was paying 100% of the $1094.27 charge. Remember they also paid for the iBot within months if the iBot being discontinued for lack of insurance companies willing to pay, which surprised people too (though at least that one was on appeal; this one was practically automatic, within months of FDA approval!).
You know its weird when people who regularly deals with Microsoft insurance doubts it.
In fact, if you are a Microsoft employee you may want to consider running over me at an intersection or something. Our insurance is now being so generous that even the people who routinely deal with our insurance are wigging out over what they cover. This has to be a bad thing that will impact coverage in the long run, right? Sheesh!
Good for me may not actually be good for us!
Anyway, I am just a few days in (sent to me by UPS Next Day Air 5/27, I got it on 5/28) and it is already eligible for refill on 6/1. I'm going to wait to see if it looks like its helping. And maybe ask them to not bother with the next day air next time. Maybe the price can be driven down a bit....
If close to the end of the month it doesn't seem to be helping, I'll stop. No idea why they'd approve it for renewal so fast, are they getting a kickback or something? Sheesh. Again.
Plus the Twitterverse is awash with people talking about the high cost and low effectveness. Check here, you'll see what I mean. But I've also heard some positive reports (sites like this one have some of the typical comments you can see if you aren't looking at the news stories, tweets, and blogs that just parrot each other -- I am continuing to doubt that Twitter is the best way to find out truth in such circumstances!). Sheesh, the third.
Apparently the drug is helpful for some people, though the criteria they used to determine usefulness was not as good as it could have been.
But now for the Ampyra IRONY I promised.
As I actually expected, when you read the Ampyra literature, one of the potential adverse side effects for this medication meant to primarily deal with imbalance is...
...wait for it...
BALANCE PROBLEMS!
This is akin to Zofran causing nausea. Remember that one? Sheesh, the fourth.
So, how am I supposed to know if it is helping and I am just seeing the side effect, or it isn't helping? I'll let you know how the course goes but I'll admit to frank amazement that they have not overflowed their irony stack buffer.
Anyway, for now I am going to keep up the Ampyra and see what happens....