How To detect that a culture is bidi

by Michael S. Kaplan, published on 2006/07/12 04:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/07/12/663013.aspx


Andy Canfield asked:

I read your post here:

How To [NOT] detect that a locale is bidi

and I have recently come up against this issue but have a slightly different problem. I know how to do what you showed in C but I need to translate it to C# for .Net 1.1 because the .Net environment I have to work in will not allow me to upgrade to .Net 2.0 where textinfo has a property that tells you wether or not it is bidi. So my question is ( since I do not know C# well at all ), is will you take a look at my code for a bidi aware MessageBox and tell me if I translated the C to C# correctly? If you will my code is below. If not then thank you for your time.

Andy

I did not include Andy's code (since it was really wrong; sorry Andy!). But here is a quick example of the code converted to C#:

using System;
using System.Globalization;
using System.Runtime.InteropServices;

namespace Sig {
    class test {
        private unsafe struct LOCALESIGNATURE {
            public fixed uint lsUsb[4];
            public fixed uint lsCsbDefault[2];
            public fixed uint lsCsbSupported[2];
        }; 

        private const uint LOCALE_FONTSIGNATURE = 0x00000058;   // font signature

        [DllImport("kernel32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
        private static extern int GetLocaleInfoW(int Locale, uint LCType, out LOCALESIGNATURE lpLCData, int cchData);

        [STAThread]
        static void Main(string[] args) {
            if(args.Length > 0) {
                Console.WriteLine(IsBiDirectional(new CultureInfo(args[0])));
            } else {
                Console.WriteLine("You must pass a culture name.");
            }
        }

        internal unsafe static bool IsBiDirectional(CultureInfo ci) {
            LOCALESIGNATURE ls;

            if(GetLocaleInfoW(ci.LCID, LOCALE_FONTSIGNATURE, out ls, 16) > 0 &&
              ((ls.lsUsb[3] & 0x8000000) != 0)) {
                return(true);
            } else {
                return(false);
            }
        }
    }
}

One of the advantages that both C# and C++ have over C is that you can define multiple overloads for a function if there are different ways to call it. So a new, safe overload for GetLocaleInfo that returns LOCALESIGNATURE structs is just what we need. :-)

When you compile it, make sure you use the /unsafe flag to csc.exe.... then just call your binary with the name of a culture (like ar-SA, he-IL, fr-FR, or whatever) and it will return the answer to the bidirectional question....

From there you can do whatever you like to flip the MessageBox as needed.

 

This post brought to you by ת (U+05ea, a.k.a. HEBREW LETTER TAV)


# dono on 12 Jul 2006 4:38 AM:

I do not have a 1.1 compiler available at the moment, but wasn't the fixed size buffer syntax added in the 2.0 release? ie, code like "public fixed uint lsUsb[4];" etc.
Andy specifically stated that he can not upgrade to 2.0.

# Michael S. Kaplan on 12 Jul 2006 8:30 AM:

Is it a 2.0 feature? Hmmmm.....

Well, another easy way to do it is a slightly different struct definition that will do the same thing:

       private struct LOCALESIGNATURE {
           public uint lsUsb0;
           public uint lsUsb1;
           public uint lsUsb2;
           public uint lsUsb3;
           public uint lsCsbDefault0;
           public uint lsCsbDefault1;
           public uint lsCsbSupported0;
           public uint lsCsbSupported1;
       };

This should work in all versions, and even lets you avoid the unsafe keyword!

# Andy on 14 Jul 2006 11:52 AM:

Michael,
   Thank you for your help on this! C# is very new to me and I am still trying to get sorted out what I know in C and C++ and how it translates to C#. I got a compile error on having "fixed" in a declaration saying I can't do it. Is the fixed keyword something I could get rid of or do I need to ensure it stays pinned some other way?
Thank you. This has been a great help so far,
Andy

# Michael S. Kaplan on 14 Jul 2006 1:32 PM:

Check the comment above yours.... :-)

# Andy on 14 Jul 2006 4:21 PM:

Worked like a charm. Thank you again for your help on this.

referenced by

2012/01/16 I'm reasonably certain that those who disagree with me here are wrong!

2006/12/21 It's not right when IsRightToLeft is wrong

go to newer or older post, or back to index or month or day