File Coverage

blib/lib/Win32/API/Interface.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Win32::API::Interface;
2            
3 2     2   49751 use strict;
  2         6  
  2         111  
4            
5 2     2   11 use vars qw/$VERSION $INSTANCE %API_GENERATED/;
  2         4  
  2         214  
6             $VERSION = '0.03';
7             $INSTANCE = Win32::API::Interface->new;
8            
9 2     2   2750 use Win32::API ();
  0            
  0            
10            
11             =head1 NAME
12            
13             Win32::API::Interface - Object oriented interface generation
14            
15             =head1 SYNOPSIS
16            
17             package MyModule;
18             use base qw/Win32::API::Interface/;
19            
20             __PACKAGE__->generate( "kernel32", "GetCurrentProcessId", "", "N" );
21             __PACKAGE__->generate( "kernel32", "GetCurrentProcessId", "", "N", 'get_pid' );
22            
23             1;
24            
25             my $obj = MyModule->new );
26             print "PID: " . $obj->GetCurrentProcessId . "\n";
27             print "PID: " . $obj->get_pid . "\n";
28            
29             =head1 DESCRIPTION
30            
31             This module provides functions for generating a object oriented interface to
32             Win32 API functions.
33            
34             =head1 METHODS
35            
36             =head2 new
37            
38             my $obj = Module->new;
39            
40             Win32::API::Interface provides a basic constructor. It generates a
41             hash-based object and can be called as either a class method or an object
42             method.
43            
44             =cut
45            
46             sub new {
47             my $proto = shift;
48             my $class = ref $proto || $proto;
49            
50             return bless {}, $class;
51             }
52            
53             =head2 self
54            
55             my $self = $obj->self;
56            
57             Returns itself. Acutally useless and mainly used internally.
58             Can also be called as a object method.
59            
60             Win32::API::Interface->self
61            
62             =cut
63            
64             sub self {
65             my $self = shift;
66             $self = $Win32::API::Interface::INSTANCE unless ref $self;
67             return $self;
68             }
69            
70             =head2 generate
71            
72             __PACKAGE__->generate( "kernel32", "GetCurrentProcessId", "", "N" );
73            
74             This generates a method called I which is exported
75             by I. It does not take any input parameters but returns a value
76             of type I.
77            
78             __PACKAGE__->generate( "kernel32", "GetCurrentProcessId", "", "N", "get_pid" );
79            
80             Actually the same as above, but this will generate a method called I.
81             This is useful if you do not want to rely on the API function name.
82            
83             __PACKAGE__->generare(
84             "advapi32",
85             "EncryptFile",
86             "P", "I", "",
87             sub {
88             my ( $self, $filename ) = @_;
89             return $self->Call( File::Spec->canonpath($filename) );
90             }
91             );
92            
93             As the seventh and last parameter you may provide a function reference for modifying
94             the input to and output from the API function.
95            
96             __PACKAGE__->generate(
97             [ "kernel32", "GetTempPath", "NP", "N" ],
98             [ "kernel32", "GetCurrentProcessId", "", "N", "get_pid" ],
99             [ "advapi32" ,"EncryptFile", "P", "I", "", $coderef ],
100             );
101            
102             You may call I passing an hash reference of array references.
103            
104             __PACKAGE__->generate( {
105             "kernel32" => [
106             [ "GetTempPath", "NP", "N" ],
107             [ "GetCurrentProcessId", "", "N", "get_pid" ],
108             ],
109             "user32" => [
110             [ "GetCursorPos", "P", "I"]
111             ],
112             "advapi32" => [
113             [ "EncryptFile", "P", "I", "", $coderef ],
114             ].
115             } );
116            
117             =cut
118            
119             {
120             no strict 'refs';
121            
122             sub generate {
123             my $self = shift;
124            
125             if ( 'ARRAY' eq ref $_[0] ) {
126             foreach my $args (@_) {
127             $self->generate( @{$args} );
128             }
129             }
130             elsif ( 'HASH' eq ref $_[0] ) {
131             while ( my ( $library, $params ) = each %{ $_[0] } ) {
132             foreach my $args ( @{$params} ) {
133             $self->generate( $library, @{$args} );
134             }
135             }
136             }
137             else {
138            
139             my ( $library, $name, $params, $retr, $alias, $call ) = @_;
140             my $class = ref $self || $self;
141             $alias ||= $name;
142            
143             *{"${class}::$alias"} =
144             $self->_generate( $library, $name, $params, $retr, $call )
145             unless defined &{"${class}::$alias"};
146             }
147            
148             return 1;
149             }
150             }
151            
152             sub _generate {
153             my ( $class, $library, $name, $params, $retr, $call ) = @_;
154            
155             my $key = uc "$library-$name";
156             $API_GENERATED{$name} = 1;
157            
158             return sub {
159             my $self = shift->self;
160            
161             $self->{api} ||= {};
162            
163             my $api =
164             defined $self->{api}->{$key}
165             ? $self->{api}->{$key}
166             : $self->{api}->{$key} =
167             Win32::API->new( $library, $name, $params, $retr );
168             die "Unable to import API $name from $library: $^E"
169             unless defined $api;
170            
171            
172             my $retval;
173             if( 'CODE' eq ref $call ) {
174             $retval = $call->($api, @_);
175             } else {
176             $retval = $api->Call(@_);
177             }
178             return $retval;
179             };
180             }
181            
182             #sub generate_ex {
183             # my $self = shift;
184             # my %args = 'HASH' eq ref $_[0] ? %{ $_[0] } : @_;
185             #
186             # while ( my ( $library, $params ) = each %args ) {
187             # foreach my $args ( @{$params} ) {
188             # $self->generate( $library, @{$args} );
189             # }
190             # }
191             #
192             # return 1;
193             #}
194            
195             =head2 generated
196            
197             Returns a list of all real generated API function names
198            
199             __PACKAGE__->generated( );
200            
201             =cut
202            
203             sub generated {
204             return keys %API_GENERATED;
205             }
206            
207             =head1 AUTHOR
208            
209             Sascha Kiefer, L
210            
211             =head1 COPYRIGHT AND LICENSE
212            
213             Copyright (C) 2006 Sascha Kiefer
214            
215             This library is free software; you can redistribute it and/or modify
216             it under the same terms as Perl itself.
217            
218             =cut
219            
220             1;
221