EdwardG has asked for the wisdom of the Perl Monks concerning the following question:

I was considering a reply to Need to determine state of mousepointer, thinking it would be easy, just a few trips to the right APIs, when lo - I got stuck calling GetCursorInfo (user32.dll).

use strict; use warnings; use Data::Dumper; use Win32::API; Win32::API::Struct->typedef( POINT => qw{ LONG x; LONG y; }); Win32::API::Struct->typedef( PCURSORINFO => qw{ DWORD cbSize; DWORD flags; HCURSOR hCursor; POINT ptScreenPos; }); my $pci = Win32::API::Struct->new('PCURSORINFO'); $pci->{cbSize} = $pci->sizeof(); Win32::API->Import("user32", "BOOL GetCursorInfo(PCURSORINFO pci)"); print Dumper($pci); # before, empty but for cbSize my $result = GetCursorInfo($pci) or die $^E; # DIES HERE, RESULTS BELO +W print Dumper($pci); # after, hopefully full of useful information

This dies upon calling GetCursorInfo because - as documented - the result is zero, and $^E (ie GetLastError) is telling me my parameter is incorrect -

The parameter is incorrect at getmouseshape.pl line 27, <DATA> line 16 +4.

And here is $pci before dying

$VAR1 = bless( { '__typedef__' => 'PCURSORINFO', 'ptScreenPos' => bless( { '__typedef__' => 'POINT', 'typedef' => [ [ 'x', 'l', 'LONG' ], [ 'y', 'l', 'LONG' ] ] }, 'Win32::API::Struct' ), 'cbSize' => 16, 'typedef' => [ [ 'cbSize', 'L', 'DWORD' ], [ 'flags', 'L', 'DWORD' ], [ 'hCursor', 'L', 'HCURSOR' ], [ 'ptScreenPos', '>', 'POINT' ] ] }, 'Win32::API::Struct' );

 

Replies are listed 'Best First'.
Re: Win32::API::Struct and GetCursorInfo with PCURSORINFO
by dfaure (Chaplain) on Jun 25, 2004 at 12:41 UTC

    Win32::API::Struct->sizeof() seems not to compute correctly struct size when nesting them:

    use strict; use warnings; use Win32::API; Win32::API::Struct->typedef('POINT', qw( LONG x; LONG y; )); my $Point = Win32::API::Struct->new('POINT'); print "sizeof('POINT') = " . $Point->sizeof() . "\n"; Win32::API::Struct->typedef('CURSORINFO', qw( DWORD cbSize; DWORD flags; HANDLE hCursor; POINT ptScreenPos; )); my $CursorInfo = Win32::API::Struct->new('CURSORINFO'); print "sizeof('CURSORINFO') = " . $CursorInfo->sizeof() . "\n"; Win32::API::Struct->typedef('MYSTRUCT', qw( DWORD cbSize; DWORD flags; HANDLE hCursor; )); my $Struct = Win32::API::Struct->new('MYSTRUCT'); print "sizeof('MYSTRUCT') = " . $Struct->sizeof() . "\n"; __DATA__ sizeof('POINT') = 8 sizeof('CURSORINFO') = 16 sizeof('MYSTRUCT') = 12

    8 + 12 != 16

    Update: investigating a bit more, the problem seems linked with structure member alignment computations used in sizeof method (and require more knowledge than I've available for now :-)).

    Bug discovered in v0.40 of Win32::API::Struct and reported as bug#6757 "Win32::API::Struct->sizeof() seems not to compute correctly struct size when nesting them".

    ____
    HTH, Dominique
    My two favorites:
    If the only tool you have is a hammer, you will see every problem as a nail. --Abraham Maslow
    Bien faire, et le faire savoir...

      cross posted from CPAN RT

      Running the code on perlmonks in 0.72 I got
      sizeof('POINT') = 8 sizeof('CURSORINFO') = 20 sizeof('MYSTRUCT') = 12
      on perlmonks you said you got
      sizeof('POINT') = 8 sizeof('CURSORINFO') = 16 sizeof('MYSTRUCT') = 12
      DWORD cbSize; 4 DWORD flags; 4 HANDLE hCursor; 4 POINT ptScreenPos; -> LONG x; 4 LONG y; 4 = 20
      So I believe this has been already fixed so I am closing this bug.
Re: Win32::API::Struct and GetCursorInfo with PCURSORINFO
by BrowserUk (Patriarch) on Jun 25, 2004 at 20:54 UTC

    The simplest fix is to set the size of the structure manually.

    $pci->{cbSize} = 20; ## $pci->sizeof();

    That allows the call to return successfully.


    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
      wasn't that clear from dominiqes post?