Update of /cvsroot/perl-win32-gui/Win32-GUI/Win32-GUI-DropFiles/t
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2364/Win32-GUI-DropFiles/t

Added Files:
        01_load.t 02_old_callback.t 03_new_callback.t 
        04_GetDroppedFiles.t 05_GetDroppedFile.t 06_GetDropPos.t 
        07_DragQueryFile.t 08_DragQueryPoint.t 09_DragFinish.t 
        10_Unicode.t 11_invalid_handles.t 98_pod.t 99_pod_coverage.t 
        DropTest.pm 
Log Message:
Add Win32::GUI::DropFiles

--- NEW FILE: 99_pod_coverage.t ---
#!perl -wT
# Win32::GUI::DropFiles test suite.
# $Id: 99_pod_coverage.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $

# Check the POD covers all method calls

use strict;
use warnings;

use Test::More;
eval "use Test::Pod::Coverage 1.04";
plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" 
if $@;
plan skip_all => "Pod Coverage tests for Win32::GUI::DropFiles done by core" if 
$ENV{W32G_CORE};
all_pod_coverage_ok();

--- NEW FILE: 10_Unicode.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 10_Unicode.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles Unicode support

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;

BEGIN {
    #No unicode support before WinNT
    plan skip_all => "No Unicode filename support in Win95/98/ME" if 
Win32::GetOSVersion() < 2;
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing Uniocde Support" if 
$@;
    eval "use Unicode::String";
    plan skip_all => "Unicode::String required for testing Unicode Support" if 
$@;
}

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my @tests = (
    # Ascii chars only
    [ "AB", "C", "Longer Name with spaces", ],
    # Simley face
    [ "\x{263A}", ],
    # Hello World - multi-lingual
    [ "Hello world",
      "\x{039A}\x{03B1}\x{03BB}\x{3B7}\x{03BC}\x{1F73}\x{03C1}\x{03B1}",
      "\x{03B1}\x{1F79}\x{03C3}\x{03BC}\x{03B5}, 
\x{30B3}\x{30F3}\x{30CB}\x{30C1}\x{30CF}",
    ],
    # Thai
    [ "\x{0E4F} 
\x{0E41}\x{0E1C}\x{0E48}\x{0E19}\x{0E14}\x{0E34}\x{0E19}\x{0E2E}\x{0E31}\x{0E48}\x{0E19}\x{0E40}\x{0E2A}\x{0E37}\x{0E48}\x{0E2D}\x{0E21}\x{0E42}\x{0E17}\x{0E23}\x{0E21}\x{0E41}\x{0E2A}\x{0E19}\x{0E2A}\x{0E31}\x{0E07}\x{0E40}\x{0E27}\x{0E0A}",
"\x{0E1E}\x{0E23}\x{0E30}\x{0E1B}\x{0E01}\x{0E40}\x{0E01}\x{0E28}\x{0E01}\x{0E2D}\x{0E07}\x{0E1A}\x{0E39}\x{0E4A}\x{0E01}\x{0E39}\x{0E49}\x{0E02}\x{0E36}\x{0E49}\x{0E19}\x{0E43}\x{0E2B}\x{0E21}\x{0E48}",
    ],
);

plan tests => 1 * scalar @tests;

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();

my $files;
while($files = shift @tests) {
    my $dt = DropTest->new(files => $files, wide => 1);
    $dt->PostDropMessage($W);
    Win32::GUI::Dialog();
}

exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    my @f = $dropobj->GetDroppedFiles();
    ok(eq_set($files,[EMAIL PROTECTED]), "Correct set of files found");
    
    return -1;
}

--- NEW FILE: 98_pod.t ---
#!perl -wT
# Win32::GUI::DropFiles test suite.
# $Id: 98_pod.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $

# Check that our pod documentation has valid syntax

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

use Test::More;
eval "use Test::Pod 1.14";
plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
plan skip_all => "Pod tests for Win32::GUI::DropFiles done by core" if 
$ENV{W32G_CORE};
all_pod_files_ok();

--- NEW FILE: 03_new_callback.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 03_new_callback.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI DropFiles callback after loading Win32::GUI::DropFiles

# - check pre-requsites
# - check both OEM and NEM callbacks
# - check callback parameter types
# - check that DragFinish is called

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;

BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing New Callback API" if 
$@;
}

plan tests => 7;

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my $dropobj = DropTest->new();

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
    -eventmodel  => "byname",
);

Win32::GUI::DoEvents();

# Do the OEM tests

$dropobj->PostDropMessage($W);

Win32::GUI::Dialog();

# Check that the receiver freed the handle
ok($dropobj->Free(), "OEM frees the drop object");

# Now do the NEM tests:

$W->Change(-eventmodel => "byref");

$dropobj->PostDropMessage($W);

Win32::GUI::Dialog();
ok($dropobj->Free(), "NEM frees the drop object");

exit(0);

sub win_DropFiles {
    my ($dropobj) = shift;

    ok(defined $dropobj, "OEM callback, dropobj defined");
    isa_ok($dropobj, "Win32::GUI::DropFiles", "OEM dropobj is a 
Win32::GUI::DropFiles object");
    
    return -1;
}

sub drop {
    my ($self, $dropobj) = @_;

    is($self, $W, "NEM callback gets window object");
    ok(defined $dropobj, "NEM callback, dropobj defined");
    isa_ok($dropobj, "Win32::GUI::DropFiles","NEM dropobj is a 
Win32::GUI::DropFiles object");
    
    return -1;
}

--- NEW FILE: 07_DragQueryFile.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 07_DragQueryFile.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles DragQueryFile() function

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing DragQueryFile()" if 
$@;
}

plan tests => 33;

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

# Some Useful constants:
sub EINVAL() {22}
sub ERROR_INVALID_INDEX() {1413}

# Cygwin doesn't provide Win32 extended errors, so $^E == $!
my $EXPECTED_E = (lc $^O eq "cygwin") ? EINVAL : ERROR_INVALID_INDEX;

my @files = ( "A", "B", "Longer Name with spaces" );

my $dropobj = DropTest->new(
    files => [EMAIL PROTECTED],
);

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();
$dropobj->PostDropMessage($W);
Win32::GUI::Dialog();
exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    # DragQueryFile with no params returns the number of files
    is(Win32::GUI::DropFiles::DragQueryFile($dropobj), scalar @files, "Correct 
number of files when passed object");
    is(Win32::GUI::DropFiles::DragQueryFile($dropobj->{-handle}), scalar 
@files, "Correct number of files when passed handle");
    is($dropobj->DragQueryFile(), scalar @files, "Correct number of files when 
called as method");

    # DragQueryFile with one param returns file name
    my $count = $dropobj->GetDroppedFiles();
    
    {
        my @f;
        for (0..$count-1) {
            push @f, Win32::GUI::DropFiles::DragQueryFile($dropobj, $_);
        }

        ok(eq_set([EMAIL PROTECTED],[EMAIL PROTECTED]), "Correct set of files 
found when passed object");

        # Test out of range indices
        for my $index (-1, $count, 1000) {
            my($r, $e);

            $!=$^E=0;
            $r = Win32::GUI::DropFiles::DragQueryFile($dropobj,$index);
            $e = $^E; # record value of $^E immediately

            is($r, undef , "Out of range index ($index) returns undef when 
passed object");
            SKIP: {
                skip "Can't test error values if no error", 2 if defined $r;

                cmp_ok($!, '==', EINVAL, "errno set to EINVAL");
                cmp_ok($^E, '==', $EXPECTED_E, "GetLastError returns 
ERROR_INVALID_INDEX");
            }
        }
    }
    {
        my @f;
        for (0..$count-1) {
            push @f, Win32::GUI::DropFiles::DragQueryFile($dropobj->{-handle}, 
$_);
        }

        ok(eq_set([EMAIL PROTECTED],[EMAIL PROTECTED]), "Correct set of files 
found when passed handle");

        # Test out of range indices
        for my $index (-1, $count, 1000) {
            my($r, $e);

            $!=$^E=0;
            $r = 
Win32::GUI::DropFiles::DragQueryFile($dropobj->{-handle},$index);
            $e = $^E; # record value of $^E immediately

            is($r, undef , "Out of range index ($index) returns undef when 
passed handle");
            SKIP: {
                skip "Can't test error values if no error", 2 if defined $r;

                cmp_ok($!, '==', EINVAL, "errno set to EINVAL");
                cmp_ok($^E, '==', $EXPECTED_E, "GetLastError returns 
ERROR_INVALID_INDEX");
            }
        }
    }
    {
        my @f;
        for (0..$count-1) {
            push @f, $dropobj->DragQueryFile($_);
        }

        ok(eq_set([EMAIL PROTECTED],[EMAIL PROTECTED]), "Correct set of files 
found when called as method");

        # Test out of range indices
        for my $index (-1, $count, 1000) {
            my($r, $e);

            $!=$^E=0;
            $r = $dropobj->DragQueryFile($index);
            $e = $^E; # record value of $^E immediately

            is($r, undef , "Out of range index ($index) returns undef when 
called as method");
            SKIP: {
                skip "Can't test error values if no error", 2 if defined $r;

                cmp_ok($!, '==', EINVAL, "errno set to EINVAL");
                cmp_ok($^E, '==', $EXPECTED_E, "GetLastError returns 
ERROR_INVALID_INDEX");
            }
        }
    }
    
    return -1;
}

--- NEW FILE: 08_DragQueryPoint.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 08_DragQueryPoint.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles DragQueryPoint() function

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing DragQueryPoint()" if 
$@;
}

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my @testdata = (
  { x => 100, y => 120, c => 1 },
  { x => 1,   y => -1,  c => 0 },
);
my $numtests = scalar @testdata;

plan tests => 9 * $numtests;

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();

my $testnum;
for (0..$numtests-1) {
    $testnum = $_;
    my $dropobj = DropTest->new(
        x => $testdata[$testnum]->{x},
        y => $testdata[$testnum]->{y},
        client => $testdata[$testnum]->{c},
    );
    $dropobj->PostDropMessage($W);
    Win32::GUI::Dialog();
}
exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    # DragQueryPoint returns a list of x, y, client info
    {
        my ($x, $y, $c) = Win32::GUI::DropFiles::DragQueryPoint($dropobj);
        is($x, $testdata[$testnum]->{x}, "X-pos reported correctly when passed 
object");
        is($y, $testdata[$testnum]->{y}, "Y-pos reported correctly when passed 
object");
        is($c, $testdata[$testnum]->{c}, "client pos reported correctly when 
passed object");
    }
    {
        my ($x, $y, $c) = 
Win32::GUI::DropFiles::DragQueryPoint($dropobj->{-handle});
        is($x, $testdata[$testnum]->{x}, "X-pos reported correctly when passed 
handle");
        is($y, $testdata[$testnum]->{y}, "Y-pos reported correctly when passed 
handle");
        is($c, $testdata[$testnum]->{c}, "client pos reported correctly when 
passed handle");
    }
    {
        my ($x, $y, $c) = $dropobj->DragQueryPoint();
        is($x, $testdata[$testnum]->{x}, "X-pos reported correctly when called 
as method");
        is($y, $testdata[$testnum]->{y}, "Y-pos reported correctly when called 
as method");
        is($c, $testdata[$testnum]->{c}, "client pos reported correctly when 
called as method");
    }
    
    return -1;
}

--- NEW FILE: 01_load.t ---
#!perl -wT
# Win32::GUI::DropFiles test suite
# $Id: 01_load.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# - check pre-requsites
# - check module loads
# - check module has a version
# - check we didn't import lots of constants from Win32::GUI

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# Pre-requisites: Bail out if we havent got Test::More
eval "use Test::More";
if($@) {
    # As we haven't got Test::More, can't use diag()
    print "#\n# Test::More required to perform any Win32::GUI::DragDrop test\n";
    chomp $@;
    $@ =~ s/^/# /gm;
    print "[EMAIL PROTECTED]";
    print "Bail Out! Test::More not available\n";
    exit(1);
}

plan( tests => 4 );

# Pre-requisites: Check that we're on windows or cygwin
# bail out if we're not
if ( not ($^O =~ /MSwin32|cygwin/i)) {
    diag("\nWin32::GUI can only run on MSWin32 or cygwin, not '$^O'");
    print "Bail out! Incompatible Operating System\n";
}
pass("Correct OS: $^O");
    
# Check that Win32::GUI::DropFiles loads, and bail out of all
# tests if it doesn't
use_ok('Win32::GUI::DropFiles')
  or print STDOUT "Bail out! Can't load Win32::GUI::DropFiles";

# Check that Win32::GUI::DropFiles has a version
ok(defined $Win32::GUI::DropFiles::VERSION, "Win32::GUI::DropFiles version 
check");

# Check that we didn't accidently import lots of constants from Win32::GUI
ok(!defined &Win32::GUI::DropFiles::ES_WANTRETURN, "No Win32::GUI constants");

--- NEW FILE: 05_GetDroppedFile.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 05_GetDroppedFile.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles GetDroppedFile() method

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing GetDroppedFile()" if 
$@;
}

plan tests => 10;

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

# Some Useful constants:
sub EINVAL() {22}
sub ERROR_INVALID_INDEX() {1413}

# Cygwin doesn't provide Win32 extended errors, so $^E == $!
my $EXPECTED_E = (lc $^O eq "cygwin") ? EINVAL : ERROR_INVALID_INDEX;

my @files = ( "A", "B", "Longer Name with spaces" );

my $dropobj = DropTest->new(
    files => [EMAIL PROTECTED],
);

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();
$dropobj->PostDropMessage($W);
Win32::GUI::Dialog();
exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    # GetDroppedFiles in scalar context returns number of files
    my $count = $dropobj->GetDroppedFiles();

    my @f;
    for (0..$count-1) {
        push @f, $dropobj->GetDroppedFile($_);
    }

    ok(eq_set([EMAIL PROTECTED],[EMAIL PROTECTED]), "Correct set of files 
found");

    # Test out of range indices
    for my $index (-1, $count, 1000) {
        my($r, $e);

        $!=$^E=0;
        $r = $dropobj->GetDroppedFile($index);
        $e = $^E; # record value of $^E immediately

        is($r, undef , "Out of range index ($index) returns undef");
        SKIP: {
            skip "Can't test error values if no error", 2 if defined $r;

            cmp_ok($!, '==', EINVAL, "errno set to EINVAL");
            cmp_ok($^E, '==', $EXPECTED_E, "GetLastError returns 
ERROR_INVALID_INDEX");
        }
    }
    
    return -1;
}

--- NEW FILE: 04_GetDroppedFiles.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 04_GetDroppedFiles.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles GetDroppedFiles() method

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing GetDroppedFiles()" 
if $@;
}


# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my @tests = (
    [ "A", "B", "Longer Name with spaces" ],
    [],   # no files should never happen, but just in case ...
);

plan tests => 2 * scalar @tests;

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();

my $files;
while($files = shift @tests) {
    my $dt = DropTest->new(files => $files);
    $dt->PostDropMessage($W);
    Win32::GUI::Dialog();
}

exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    # GetDroppedFiles in scalar context returns number of files
    is(scalar $dropobj->GetDroppedFiles(), scalar @{$files}, "Correct number of 
files");

    # GetDroppedFiles in list context returns the list of files
    my @f = $dropobj->GetDroppedFiles();
    ok(eq_set($files,[EMAIL PROTECTED]), "Correct set of files found");
    
    return -1;
}

--- NEW FILE: 11_invalid_handles.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 11_invalid_handles.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles win32 API doesn't barf with invalid handles

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI::DropFiles will load.

use Test::More;
use Win32::GUI::DropFiles;

my @handles = (0, int(rand(2**32)),);

plan tests => 6 * scalar @handles;

# Useful Constants:
sub EINVAL() {22}
sub ERROR_INVALID_HANDLE() {6}

# On cygwin, $^E == $! (no OS extended errors)
my $EXPECTED_E = ERROR_INVALID_HANDLE;
if(lc $^O eq "cygwin") {
    $EXPECTED_E = EINVAL;
}

for my $h (@handles) {
    my ($r, $e);

    # DragQueryFile
    $!=0;$^E=0;
    $r = Win32::GUI::DropFiles::DragQueryFile($h);
    $e = $^E;  # Record $^E immediately after call
    is($r , undef, "DragQueryFile: Invalid handle $h returns undef");
    SKIP: {
        skip "DragQueryFiles: Can't test error codes if we didn't get an 
error", 2 if defined $r;

        cmp_ok($!, "==", EINVAL, "DragQueryFile: Errno set to EINVAL");
        cmp_ok($e, "==", $EXPECTED_E, "DragQueryFile: LastError set to 
ERROR_INVALID_HANDLE");
    }

    # DragQueryPoint
    $!=0;$^E=0;
    $r = Win32::GUI::DropFiles::DragQueryPoint($h);
    $e = $^E;  # Record $^E immediately after call
    is($r, undef, "DragQueryPoint: Invalid handle $h returns undef");
    SKIP: {
        skip "DragQueryPoint: Can't test error codes if we didn't get an 
error", 2 if defined $r;

        cmp_ok($!, "==", EINVAL, "DragQueryPoint: Errno set to EINVAL");
        cmp_ok($^E, "==", $EXPECTED_E, "DragQueryPoint: LastError set to 
ERROR_INVALID_HANDLE");
    }

    # DragFinish
    # DragFinish sets LastError inconsistently, using ERROR_INVALID_PARAMETER
    # on win98 and ERROR_INVALID_HANDLE on winNT.  Also on WinNT, doesn't
    # consider 0 to be invalid.   As there is no return value from DragFinish,
    # the user can't tell if there was an error or not, so doen't know if
    # $^E contains anything useful or not, so we don't need to do the test.
}

--- NEW FILE: 02_old_callback.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 02_old_callback.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI DropFiles callback without loading Win32::GUI::DropFiles
# This is really a Win32::GUI test, not a Win32::GUI::Dropfiles test,
# but is here for completeness

# This old callback format is kept for backwards compatibility with
# The GUI Loft's Win32::GUI::DragDrop package.

# - check pre-requsites
# - check both OEM and NEM callbacks
# - check callback parameter types
# - check that DragFinish is called

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;

BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing Old Callack API" if 
$@;
}

plan tests => 7;

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;

my $dropobj = DropTest->new();

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
    -eventmodel  => "byname",
);

Win32::GUI::DoEvents();

# Do the OEM tests

$dropobj->PostDropMessage($W);

Win32::GUI::Dialog();

# Check that the receiver freed the handle
ok($dropobj->Free(), "OEM frees the drop object");

# Now do the NEM tests:

$W->Change(-eventmodel => "byref");

$dropobj->PostDropMessage($W);

Win32::GUI::Dialog();
ok($dropobj->Free(), "NEM frees the drop object");

exit(0);

sub win_DropFiles {
    my ($drophandle) = shift;

    ok(defined $drophandle, "OEM callback, drophandle defined");
    is(ref($drophandle), "", "OEM drophandle is a scalar");
    
    return -1;
}

sub drop {
    my ($self, $drophandle) = @_;

    is($self, $W, "NEM callback gets window object");
    ok(defined $drophandle, "NEM callback, drophandle defined");
    is(ref($drophandle), "", "NEM drophandle is a scalar");
    
    return -1;
}

--- NEW FILE: DropTest.pm ---
package DropTest;

# $Id: DropTest.pm,v 1.1 2006/04/25 21:38:19 robertemay Exp $
# package to hide away the complexity of generating a WM_DROPEVENT on a window.
# Written by Robert May, April 2006
#
# This would be an ideal candidate for implementing in XS within a 
Win32::GUI::Test
# module
#


use strict;
use warnings;

use Win32();
use Win32::GUI();
use Win32::API();

Win32::API->Import('Kernel32', 'GlobalAlloc', 'LL', 'L') || die "No 
GlobalAlloc: $^E";
Win32::API->Import('Kernel32', 'GlobalLock', 'L', 'L') || die "No GlobalLock: 
$^E";
Win32::API->Import('Kernel32', 'GlobalUnlock', 'L', 'L') || die "No 
GlobalUnlock: $^E";
Win32::API->Import('Kernel32', 'GlobalFree', 'L', 'L') || die "No GlobalFree: 
$^E";
Win32::API->Import('Kernel32', 'GlobalFlags', 'L', 'L') || die "No GlobalFree: 
$^E";
Win32::API->Import("kernel32", "RtlMoveMemory", "LPI", "V") || die "No 
RtlMoveMemory: $^E";

sub WM_DROPFILES() {563}
sub NO_ERROR()     {0}
sub GHND()         {0x0042} # GHND = GMEM_MOVEABLE|GMEM_ZERO_INIT = 0x0042
sub GMEM_INVALID_HANDLE() {32768}

sub new {
    my $class = shift;
    my %options = @_;

    $options{x} ||= 0;
    $options{y} ||= 0;
    $options{wide} ||= 0;
    $options{client} = 1 unless defined $options{client};
    my $files = [];
    if(exists $options{files}) {
        if(ref($options{files}) eq "ARRAY") {
            for my $file (@{$options{files}}) {
                push @{$files}, $file;
            }
        }
        else {
            die("files option must be an array ref");
        }
    }
    else {
        $files = ['File1', 'File2', 'File3',];
    }
    if($options{wide}) {
        require Unicode::String; # use this in place of Encode, as Encode does 
not ship with Perl 5.6
        for my $file (@{$files}) {
            $file = Unicode::String::utf8($file)->byteswap->ucs2;
        }
    }
    $options{files} = $files;

    return bless \%options, $class;
}

sub PostDropMessage {
    my ($self,$dest) = @_;

    # always create a new handle, as the receiver is supposed to  free it.
    my $hdrop = $self->_create_new_drop_handle();

    $dest->PostMessage(WM_DROPFILES, $hdrop, 0);

    # The recieving process should free the hdrop handle,
    # and the handle should be invalid sometime after this call
    # Check using isFree before calling PostDropMessage again

    return;
}

# return TRUE if the hdrop handle associated with the object is freed (invalid)
# if not freed, free it and return false
sub Free {
    my ($self) = @_;

    my $hdrop = $self->{hdrop};

    return 1 unless $hdrop;

    my $locks = GlobalFlags($hdrop);
    delete $self->{hdrop};

    return 1 if $locks == GMEM_INVALID_HANDLE;

    GlobalFree($hdrop);

    return 0;
}

sub _create_new_drop_handle
{
    my ($self) = @_;

    # Free any previous handle, and warn us if it wasn't freed
    if(!$self->Free()) {
        warn "Old drop handle not freed - check for error";
    }

    # DROPFILES struct:
    # typedef struct _DROPFILES {
    #   DWORD pFiles;
    #   POINT pt;
    #   BOOL fNC;
    #   BOOL fWide;
    # } DROPFILES, *LPDROPFILES;
    # followed by double NULL terminated string structure

    my $term = "x";
    $term = "xx" if $self->{wide};

    my $buffer = pack("LLLLL" . "a*$term" x @{$self->{files}} . $term,
               20,    # sizeof(DROPFILES) - string ptr offset
               $self->{x},
               $self->{y},
               $self->{client} ? 0 : 1,
               $self->{wide} ? 1 : 0,
               @{$self->{files}},
           );

    my $size = length($buffer);

    my $hdrop = GlobalAlloc(GHND, $size) or die "GlobalAlloc failed: $^E";
    my $ptr = GlobalLock($hdrop)         or die "GlobalLock failed: $^E";
    RtlMoveMemory($ptr, $buffer, $size);
    GlobalUnlock($hdrop);
    return $self->{hdrop} = $hdrop;
}

sub dump {
    my $self = shift;

    if($self->{hdrop}) {
        my $hdrop = $self->{hdrop};
        print "Dumping handle: $hdrop\n";

        my $ptr = GlobalLock($hdrop);
        die "GlobalLock failed: $^E" unless $ptr;

        # Get the header (HROPFILES) structure
        my ($poff, $x, $y, $nc, $fwide) = unpack("LLLLL", unpack("P20", 
pack("L", $ptr)));
        print "  poff:\t$poff\n";
        print "  x:\t$x\n";
        print "  y:\t$y\n";
        print "  nc:\t$nc\n";
        print "  wide:\t$fwide\n";

        my $count = 0;
        $ptr += $poff;

        # This is probably hideously slow, but as it's only for debug ...
        my $pack_str = "C";
        my $char_len = 1;
        if($fwide) {
            $pack_str = "v";
            $char_len = 2;
        }
        my $last_char_null = 0;
        my $file = "";
        while(1) {
            my $char = unpack($pack_str, unpack("P$char_len", pack("L", $ptr)));
            $ptr += $char_len;

            last if $last_char_null && $char == 0;

            if($char == 0) {
                $last_char_null = 1;
                printf "  File $count: $file [%vx]\n", $file;
                $count++;
                $file = "";
                next;
            }

            $last_char_null = 0;
            $file .= chr $char;
        }

        GlobalUnlock($hdrop);
    }
    else {
        print "No data to dump\n";
    }
    return;
}

sub DESTROY
{
    # free the handle if necessary
    $_[0]->Free();
}

# Static function to determine if a drop handle is valid or not
sub isValidHandle
{
    my $handle = shift;

    my $locks = GlobalFlags($handle);
    return 0 if $locks == GMEM_INVALID_HANDLE;
    return 1;
}
1; # End of DropTest.pm

--- NEW FILE: 09_DragFinish.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 09_DragFinish.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles DragFinish() function

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing DragFinish()" if $@;
}

plan tests => 1;

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my $dropobj = DropTest->new();

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();
$dropobj->PostDropMessage($W);
Win32::GUI::Dialog();
exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    #Calling DragFinish should make the HDROP handle invalid
    Win32::GUI::DropFiles::DragFinish($dropobj->{-handle});

    is(DropTest::isValidHandle($dropobj->{-handle}), 0, "handle invalidated");
    
    return -1;
}

--- NEW FILE: 06_GetDropPos.t ---
#!perl -w
# Win32::GUI::DropFiles test suite
# $Id: 06_GetDropPos.t,v 1.1 2006/04/25 21:38:19 robertemay Exp $
#
# Test Win32::GUI::DropFiles GetDropPos() method

use strict;
use warnings;

BEGIN { $| = 1 } # Autoflush

# We assume that 01_load.t has been run, so we know we have Test::More
# and that Win32::GUI and Win32::GUI::DropFiles will load.

use Test::More;
 
BEGIN {
    eval "use Win32::API 0.41";
    plan skip_all => "Win32::API 0.41 required for testing GetDropPos()" if $@;
}

# Load our helpers
use FindBin;
use lib "$FindBin::Bin";
use DropTest;

use Win32::GUI 1.03_02;
use Win32::GUI::DropFiles;

my @testdata = (
  { x => 100, y => 120, c => 1 },
  { x => 1,   y => -1,  c => 0 },
);
my $numtests = scalar @testdata;

plan tests => 6 * $numtests;

my $W = Win32::GUI::Window->new(
    -name  => 'win',
    -title => "Win32::GUI DropFiles Test",
    -size  => [400,300],
    -onDropFiles => \&drop,
);

Win32::GUI::DoEvents();

my $testnum;
for (0..$numtests-1) {
    $testnum = $_;
    my $dropobj = DropTest->new(
        x => $testdata[$testnum]->{x},
        y => $testdata[$testnum]->{y},
        client => $testdata[$testnum]->{c},
    );
    $dropobj->PostDropMessage($W);
    Win32::GUI::Dialog();
}
exit(0);

sub drop {
    my ($self, $dropobj) = @_;

    # GetDropPos in scalar context returns client area or not
    is($dropobj->GetDropPos(), $testdata[$testnum]->{c}, "Correct client 
indication");

    # In list context give x, y and client indicators:
    { my ($x, $y) = $dropobj->GetDropPos();
      is($x, $testdata[$testnum]->{x}, "X-pos reported correctly");
      is($y, $testdata[$testnum]->{y}, "Y-pos reported correctly");
    }
    { my ($x, $y, $client) = $dropobj->GetDropPos();
      is($x, $testdata[$testnum]->{x}, "X-pos reported correctly");
      is($y, $testdata[$testnum]->{y}, "Y-pos reported correctly");
      is($client, $testdata[$testnum]->{c}, "client pos reported correctly");
    }
    
    return -1;
}


Reply via email to