in reply to How to call GetSystemDefaultLangID() with Win32::API

In your API protptype declaration, replace LANGID by 'long', and it works fine.

My guess is that the LANGID type is not interpreted properly, but, since that is a 'long' anyway, you can use that directly.

use strict; use warnings; use Win32::API; Win32::API->Import('kernel32.dll', 'long GetSystemDefaultLangID()') or die "Can't import GetSystemDefaultLangID: $^E\n"; my $langid = GetSystemDefaultLangID() or die "ERROR: LANGID Returned < +undef>\n"; print "Returned '$langid'\n"; printf "Lang ID: 0x%04X\n", $langid; #---- Run on Win XP (US English) Returns --- #Returned '2011563017' #Lang ID: 0x77E60409

Earth first! (We'll rob the other planets later)

Replies are listed 'Best First'.
Re^2: How to call GetSystemDefaultLangID() with Win32::API
by shay (Beadle) on Jun 23, 2004 at 16:11 UTC
    Well, Win32::API::Types lists LANGID as 's', which I assume means a (signed?) short. Actually, LANGID is typedef'd as WORD (in <winnt.h>), which is an unsigned short (not a LONG), so specifying USHORT should have fixed it, but still doesn't.

    Your idea of specifying LONG certainly produces some output: I get similar output to you:

    Returned '2011563020' Lang ID: 0x77E6040C

    but it's utter crap: the Lang ID is actually 0x0809 (2057) for UK English or 0x0409 (1033) for US English. (And the C program in my original post correctly produces these numbers.)

    How do I get the /right/ answer out of it, not just any old rubbish?

      OK - since this is a SHORT, you need to mask out the high-order bytes for this to make sense.

      The following code DOES produce the expected "1033" value for English:

      use strict; use warnings; use Win32::API; Win32::API->Import('kernel32.dll', 'long GetSystemDefaultLangID()') or die "Can't import GetSystemDefaultLangID: $^E\n"; my $langid = GetSystemDefaultLangID() & 0xFFFF # Mask out the garbage + in high-order bytes or die "ERROR: LANGID Returned <undef>\n"; print "Returned '$langid'\n"; printf "Lang ID: 0x%04X\n", $langid; # Print output---- # Returned '1033' # Lang ID: 0x0409

      Earth first! (We'll rob the other planets later)

        Thanks for that.

        So is this a bug in Win32::API, then? It seems that it doesn't correctly handle functions returning WORD's. Pretending that I want a DWORD and then masking off the high WORD that I didn't actually want seems like a rather awkward way of doing things.

      How do I get the /right/ answer out of it, not just any old rubbish?

      You work out for yourself how to make the 9 character addition to the snippet I posted required to get the answer you need.

      use strict; use warnings; use Win32::API::Prototype; ApiLink( 'kernel32.dll', 'LONG GetSystemDefaultLangID( VOID )' ) or die "Can't import GetSystemDefaultLangID: $^E\n"; my $langid = GetSystemDefaultLangID( 0 ) & 0xffff; if (defined $langid) { print "Returned '$langid'\n"; printf "Lang ID: 0x%04X\n", $langid; } else { print "Returned <undef>\n"; } __END__ P:\test>369060 Returned '1033' Lang ID: 0x0409

      Of course, I could have searched through the header files, looked up what a LANGID was, and added these characters to my post, but I didn't have any real interest in doing that. You need the solution, not me.

      Perhaps I could clean your keyboard for you?


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon