Announcement

Collapse
No announcement yet.

Language ID from Locale ID, how?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Language ID from Locale ID, how?

    I need to derive a language identifier from a locale (LCID). This is what I found in MSDN:
    The LANGIDFROMLCID macro is defined as follows:
    #define LANGIDFROMLCID(lcid) ((WORD) (lcid))


    Does someone know how to convert this to Power Basic code?
    If I try the code below, I get the correct result, but that might be a coincidence. Is my give-it-a-try-code a correct "translation" of the above mentioned definition?
    Code:
    wLangID = LO(WORD, dwLocale)

    Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
    http://zijlema.basicguru.eu
    *** Opinions expressed here are not necessarily untrue ***

  • #2
    wLangID = CWRD(lcid)
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Originally posted by José Roca View Post
      wLangID = CWRD(lcid)
      José,
      This is not correct in my opinion. Your code simply converts the value of a var to a different vartype. But the macro needs to extract the language identifier from the locale, that is made out of a language ID and a sort ID. Only because this sort ID happens to be zero (%SORT_DEFAULT) the result of the math equals the value of the initial locale, so it may look like a simple conversion.

      Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
      http://zijlema.basicguru.eu
      *** Opinions expressed here are not necessarily untrue ***

      Comment


      • #4
        It's not coincidence, you did it correctly.

        Maybe this will help you see why it's correct:

        Code:
        DWORD MAKELCID(
          WORD wLanguageID,  // language identifier
          WORD wSortID       // sorting identifier
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          This is not correct in my opinion. Your code simply converts the value of a var to a different vartype.
          And what else does the C macro?

          An even shorter way:

          Code:
          DIM wLangID AS WORD
          wLangID = lcid
          Just try it.
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            Thanks Michael!

            Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
            http://zijlema.basicguru.eu
            *** Opinions expressed here are not necessarily untrue ***

            Comment


            • #7
              Sorry José,

              It's not about a shorter way, it's about correct math. In countries where the sort identifier is non-zero, Korea for instance (SORT_KOREAN_UNICODE = &H1), your method would return a wrong value.

              Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
              http://zijlema.basicguru.eu
              *** Opinions expressed here are not necessarily untrue ***

              Comment


              • #8
                Why you don't try it? You will we surprised...
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #9
                  Code:
                     LOCAL x AS DWORD
                     x = MAKELCID(%LANG_KOREAN, %SORT_KOREAN_UNICODE)
                     LOCAL w AS WORD
                     w = x
                     MSGBOX HEX$(w)
                  Forum: http://www.jose.it-berater.org/smfforum/index.php

                  Comment


                  • #10
                    Code:
                     LOCAL x AS DWORD
                       x = MAKELCID(%LANG_KOREAN, %SORT_KOREAN_UNICODE)
                       LOCAL w AS WORD
                       w = x
                    If this "works" it is dumb luck, because the assignment statement results in a numeric overflow.

                    Jose, I am disappointed because I know you know better than to code like this. We veterans owe the newbies something more than cute tricks.



                    MCM
                    Michael Mattias
                    Tal Systems Inc. (retired)
                    Racine WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      If this "works" it is dumb luck, because the assignment statement results in a numeric overflow.
                      This is why my first reply has been wLangID = CWRD(lcid) instead of wLangID = lcid. But with PB it works both ways.

                      The C macro simply casts a DWORD to a WORD, that is what CWRD does.

                      Jose, I am disappointed because I know you know better than to code like this. We veterans owe the newbies something more than cute tricks.
                      If you look at the join dates, you will notice that Egbert is not a "newbie".

                      What surprises me is that he says that it will fail without trying it.
                      Forum: http://www.jose.it-berater.org/smfforum/index.php

                      Comment


                      • #12
                        Sheesh, if Egbert is a newbie, that makes me like... a zygote.

                        Comment


                        • #13
                          >you will notice that Egbert is not a "newbie".

                          As a certain high-ranking official of PowerBASIC Inc who happens to have his listing near the end of the white pages likes to point out, it's not only "askers" and "answerers" who read and view these threads; there are numerous "lurkers" as well.

                          With the current forum software, the first page contains some "member" and "currently on-line" statistics. Check it out; you might be as surprised as was I.

                          I would bet Real Money many of the lurkers would classify themselves "newbies."

                          MCM
                          Michael Mattias
                          Tal Systems Inc. (retired)
                          Racine WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            >What surprises me is that he says that it will fail without trying it

                            Excuse me, but Egbert DID try it (Most of us old-schoolers do that. However, I don't think "try it" is taught in programming school anymore).

                            He said it worked but - as many of us old-schoolers do - he felt uncomfortable using something for which he did not understand the underlying rationale. You will note he was "happy in his work" (source: Bridge on the River Kwai, 1957) when he had a chance to review the MAKELCID macro and saw how LCIDs are manufactured.
                            Michael Mattias
                            Tal Systems Inc. (retired)
                            Racine WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              The C macro simply casts a DWORD to a WORD, that is what CWRD does.
                              that's not what CWRD does according to my (8.03) help file:
                              Purpose Convert a value to specific variable type.
                              ...
                              wordvar?? = CWRD(numeric_expression)
                              ....
                              Remarks Each of these functions converts a numeric expression to a particular variable type. In each case, numeric_expression must be within the legal range for the result type [Italics mine. MCM].
                              Note the italicized portion of remarks.

                              As far as it "working", were I writing the library code to implement CWRD, I just might use a "casting" method by simplly reading the first two bytes of the source operand... ignoring the high-order word.

                              Then again, I might use a Boolean AND vs &hFFFFFFF in a 32-bit register and round (not truncate) the result when moving to the 16-bit destination.

                              Regardless, "how" I chose to implement CWRD would perforce be proprietary and therefore subject to change without notice. That is, using either an assignment statement or CWRD is poor technique: LOWRD is not only technically correct, it is guaranteed to work the same way regardless of changes in the compiler's implementation.
                              Last edited by Michael Mattias; 28 Mar 2008, 09:50 AM.
                              Michael Mattias
                              Tal Systems Inc. (retired)
                              Racine WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                To begin with: I'm glad, guys, that some or at least one of you take(s) the liberty to call me, 69-year old chap, a newbie. Makes me feel young again

                                Now about the "problem" discussed here. In its sample code in message #9 José Roca uses the name constant %LANG_KOREAN. This is only the "primary language identifier", valued 18 (&H12). It's surely not the language ID that a coder should use to create a Locale (LangId + SortID). Before doing so you should create a LangID first by combining the primary language ID and the sublang identifier, as follows:
                                Code:
                                wLangID = Primlang + (SubLang * 1024)
                                And no, I did not try it because I do not even know how to create a Locale or LCID. The macro function MAKELCID is not present in my copy of WIN32API.INC and the definition as given in the Win32 Programmer's reference is abracadabra for me. So I can simply not test it. But I remember from reading one or another MSDN document that the locale or LCID only equals the language ID in case the sortID is zero.
                                Last edited by Egbert Zijlema; 28 Mar 2008, 11:41 AM. Reason: message number added

                                Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
                                http://zijlema.basicguru.eu
                                *** Opinions expressed here are not necessarily untrue ***

                                Comment


                                • #17
                                  Now you can try it, if you wish.

                                  Code:
                                  '#define MAKELCID(lgid, srtid)  ((DWORD)((((DWORD)((WORD  )(srtid))) << 16) |  \
                                  '                                         ((DWORD)((WORD  )(lgid)))))
                                  
                                  #IF %DEF(%USEMACROS)
                                     MACRO MAKELCID (wLanguageID, wSortID) = MAK(DWORD, wLanguageID, wSortID AND &H000F)
                                  #ELSE
                                     FUNCTION MAKELCID (BYVAL wLanguageID AS WORD, BYVAL wSortID AS WORD) AS DWORD
                                        FUNCTION = MAK(DWORD, wLanguageID, wSortID AND &H000F)
                                     END FUNCTION
                                  #ENDIF
                                  Forum: http://www.jose.it-berater.org/smfforum/index.php

                                  Comment


                                  • #18
                                    The proof of the pudding

                                    Okay guys,

                                    Just run this code to see that a language identifier only equals its Locale (or LCID) when the sortID is 0. But using the Korean Unicode sortID is, perhaps, a bad idea. It's no longer supported. See: http://msdn2.microsoft.com/en-us/lib...89(VS.85).aspx

                                    Code:
                                    #COMPILE EXE
                                    #DIM ALL
                                    
                                    #INCLUDE "WIN32API.INC"
                                    
                                    FUNCTION MAKELCID(BYVAL wLanguageID AS WORD, BYVAL wSortID AS WORD) AS DWORD
                                      FUNCTION = MAK(DWORD, wLanguageID, wSortID AND &H000F)
                                    END FUNCTION
                                    
                                    FUNCTION PBMain () AS LONG
                                      LOCAL wLangID AS WORD
                                      LOCAL dwLocale AS DWORD
                                      LOCAL sOutput AS STRING, szDate AS ASCIIZ * 64
                                      LOCAL st AS SYSTEMTIME
                                      
                                      wLangID = MAKELANGID(%LANG_GERMAN, %SUBLANG_GERMAN)
                                      sOutput = "The language identifier for Germany is: " & FORMAT$(wLangID) & CHR$(46, 32)
                                    
                                      dwLocale = MAKELCID(wLangID, %SORT_DEFAULT)
                                      sOutput = sOutput & "The most common Locale for this country," & $CRLF & _
                                                "using %SORT_DEFAULT, is: " & FORMAT$(dwLocale) & CHR$(46, 32)
                                      sOutput = sOutput & "So, this LCID equals the language identifier." & REPEAT$(2, $CRLF)
                                    
                                      dwLocale = MAKELCID(wLangID, %SORT_GERMAN_PHONE_BOOK)
                                      sOutput = sOutput & "But if we use a different sort identifier, for instance %SORT_GERMAN_PHONE_BOOK, " & $CRLF & _
                                                "the Locale will be totally different: " & FORMAT$(dwLocale) & CHR$(46)
                                                
                                      GetLocalTime st
                                      GetDateFormat dwLocale, %DATE_LONGDATE, st, BYVAL 0, szDate, SIZEOF(szDate)
                                      sOutput = sOutput & " Passed through the GetDateFormat API, " & $CRLF & "we nevertheless get a valid German date: " & _
                                                REMOVE$(szDate, CHR$(0)) & CHR$(46)
                                      
                                      MSGBOX sOutput, 64, " The proof of the pudding... "
                                    END FUNCTION
                                    Last edited by Egbert Zijlema; 29 Mar 2008, 08:09 AM. Reason: changed the source code again

                                    Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
                                    http://zijlema.basicguru.eu
                                    *** Opinions expressed here are not necessarily untrue ***

                                    Comment

                                    Working...
                                    X