#############################################################################
## Name: lib/Wx/ActiveX.pm
## Purpose: Wx::ActiveX
## Author: Graciliano M. P.
## Created: 25/08/2002
## SVN-ID: $Id: ActiveX.pm 2530 2009-02-12 16:51:45Z mdootson $
## Copyright: (c) 2002 - 2008 Graciliano M. P., Mattia Barbon, Mark Dootson
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################
#----------------------------------------------------------------------------
package Wx::ActiveX;
#----------------------------------------------------------------------------
# init
use strict;
use Wx;
use vars qw( $AUTOLOAD );
require Exporter;
our @ISA = qw( Wx::Window Exporter );
use XSLoader;
our $VERSION = '0.12'; # Wx::ActiveX Version
our $__wxax_debug;
our @EXPORT_OK = qw ( wxACTIVEX_CLSID_MOZILLA_BROWSER wxACTIVEX_CLSID_WEB_BROWSER );
our %EXPORT_TAGS = ( everything => \@EXPORT_OK );
our %__wxax_dynamic_loadevent_data = ();
#Wx::wx_boot( 'Wx::ActiveX', $VERSION ) ;
XSLoader::load 'Wx::ActiveX', $VERSION;
# Base ActiveX Event
push @EXPORT_OK, ( 'EVENTID_ACTIVEX' );
push @{ $EXPORT_TAGS{'activex'} }, ( 'EVENTID_ACTIVEX' );
push @EXPORT_OK, ('EVT_ACTIVEX');
push @{ $EXPORT_TAGS{'activex'} }, ( 'EVT_ACTIVEX' );
sub EVENTID_ACTIVEX () { -1 }
sub EVT_ACTIVEX ($$$$) { $_[0]->Connect( $_[1], -1, &Wx::ActiveXEvent::RegisterActiveXEvent( $_[2] ), Wx::ActiveXEvent::ActiveXEventSub( $_[3] ) ) };
# Autoload
sub AUTOLOAD {
my ($method) = ( $AUTOLOAD =~ /:(\w+)$/gs ) ;
if ($method =~ /^DESTROY$/) { return ;}
my $activex = shift;
return( $activex->Invoke($method,@_) ) ;
}
# ActiveX Helper Methods
sub PropSet {
my ( $activex , $name , $val ) = @_ ;
my $pt = $activex->PropType($name) ;
if ($pt eq 'bool') {
$activex->PropSetBool($name , $val) ;
}
elsif ($pt eq 'long'||$pt eq 'int') {
$activex->PropSetInt($name , $val) ;
}
else {
$activex->PropSetString($name , $val) ;
}
}
sub ListEvents {
my $this = shift ;
my @events ;
for my $i (0..($this->GetEventCount-1)) {
my $evt_name = $this->GetEventName($i) ;
push(@events , $evt_name) if $evt_name ne '' ;
}
return( @events ) ;
}
sub ListProps {
my $this = shift ;
my @props ;
for my $i (0..($this->GetPropCount-1)) {
my $name = $this->GetPropName($i) ;
push(@props , $name) if $name ne '' ;
}
return( @props ) ;
}
sub ListMethods {
my $this = shift ;
my @methods ;
for my $i (0..($this->GetMethodCount-1)) {
my $method = $this->GetMethodName($i) ;
push(@methods , $method) if $method ne '' ;
}
return( @methods ) ;
}
sub ListMethods_and_Args {
my $this = shift ;
my @methods ;
for my $i (0..($this->GetMethodCount-1)) {
my $method = $this->GetMethodName($i) ;
my @args ;
for my $j (0..($this->GetMethodArgCount($i)-1)) {
my $arg = $this->GetMethodArgName($i,$j) ;
push(@args , $arg) if $arg ne '' ;
}
push(@methods , "$method(". join(" , ", @args) .")") if $method ne '' ;
}
return( @methods ) ;
}
sub ListMethods_and_Args_Hash {
my $this = shift ;
my @methods ;
for my $i (0..($this->GetMethodCount-1)) {
my $method = $this->GetMethodName($i) ;
my @args ;
for my $j (0..($this->GetMethodArgCount($i)-1)) {
my $arg = $this->GetMethodArgName($i,$j) ;
push(@args , $arg) if $arg ne '' ;
}
push(@methods , $method , [$method]) if $method ne '' ;
}
return( @methods ) ;
}
sub ActivexInfos {
my $this = shift ;
my @evts = $this->ListEvents ;
my @props = $this->ListProps ;
my @methods = $this->ListMethods_and_Args ;
my $ret ;
$ret .= "\n" ;
foreach my $i ( @evts ) { $ret .= " $i\n" ;}
$ret .= "\n" ;
$ret .= "\n\n" ;
foreach my $i ( @props ) { $ret .= " $i\n" ;}
$ret .= "\n" ;
$ret .= "\n\n" ;
foreach my $i ( @methods ) { $ret .= " $i\n" ;}
$ret .= "\n" ;
return( $ret ) ;
}
# load activex event functions
sub activex_load_activex_event_types {
my ($packagename, $namespace, $eventname, $exporttag, $events) = @_;
# convert activex events
my $passeventlist = {};
for my $activexname ( @$events ) {
my $key = $eventname . '_' . uc($activexname);
$passeventlist->{$key} = $activexname;
}
my @codelines = activex_get_event_code($packagename, $namespace, $eventname, $exporttag, 'activex', 1, $passeventlist, 1, 1 );
my $code = join("\n", @codelines);
Wx::LogMessage("Wx::ActiveX ActiveX Event Code:\n %s", $code ) if $Wx::ActiveX::__wxax_debug;
#my $eventfile = 'c:\eventfile.txt';
#open my $fh, '>>', $eventfile;
#print $fh $code;
eval $code;
if( my $errors = $@ ) {
# print $fh qq(eval result for $packagename\n\n);
# print $fh $errors;
Wx::LogError("Evaluation of Dynamic Event Code failed:\n %s", $errors);
# return undef;
}
#close($fh);
return 1;
}
sub activex_load_standard_event_types {
my ($packagename, $namespace, $eventname, $exporttag, $events) = @_;
# convert standard events
my $passeventlist = {};
for my $shortkey ( keys(%$events) ) {
my $key = $eventname . '_' . $shortkey;
$passeventlist->{$key} = $events->{$shortkey};
}
my @codelines = activex_get_event_code($packagename, $namespace, $eventname, $exporttag, 'standard', 1, $passeventlist, 1, 1 );
my $code = join("\n", @codelines);
Wx::LogMessage("Wx::ActiveX Standard Event Code:\n %s", $code ) if $Wx::ActiveX::__wxax_debug;
eval "$code";
if( my $errors = $@ ) {
Wx::LogError("Evaluation of Dynamic Event Code failed:\n %s", $errors);
return undef;
}
return 1;
}
#---------------------------------
# activex_get_class_code
#---------------------------------
sub activex_get_class_code {
my $callingclass = shift;
my $axinfo = $__wxax_dynamic_loadevent_data{$callingclass}->{activex};
my $stinfo = $__wxax_dynamic_loadevent_data{$callingclass}->{standard};
my @standard = activex_get_event_code($callingclass,
$stinfo->{namespace},
$stinfo->{eventname},
$stinfo->{exporttag},
'standard',
1,
$stinfo->{events},
0,
1);
my @activex = activex_get_event_code($callingclass,
$axinfo->{namespace},
$axinfo->{eventname},
$axinfo->{exporttag},
'activex',
1,
$axinfo->{events},
0,
1);
my $code = join("\n", ( @activex, @standard ) );
return $code;
}
#---------------------------------
# activex_get_event_code
#---------------------------------
sub activex_get_event_code {
my ( $packagename, $namespace, $eventname, $exporttag, $eventtype, $commentcode, $events, $store, $foreval ) = @_;
if ($store) {
my %eventcopy = %$events;
# store the data
$__wxax_dynamic_loadevent_data{$packagename}->{$eventtype} = {
namespace => $namespace,
eventname => $eventname,
exporttag => $exporttag,
events => \%eventcopy,
};
}
# code lines
my @cl_id; # create event id scalar
my @cl_idsub; # make export sub for event id scalar
my @cl_idsub_ex; # store the sub name for export
my @cl_evsub; # create an event subroutine
my @cl_evsub_ex; # store the event name for export
my $idprefix = $namespace . '::';
foreach my $eventname (keys(%$events)) {
my $extraparam = $events->{$eventname}; # numargs or activex event name
my $eventid = Wx::NewEventType;
# basenames
my $codeline;
my $evt_id = '$wxEVENTID_AX_' . $eventname;
my $evt_idsub_ex = 'EVENTID_AX_' . $eventname;
my $evt_evsub_ex = 'EVT_ACTIVEX_' . $eventname;
push @cl_idsub_ex, $evt_idsub_ex;
push @cl_evsub_ex, $evt_evsub_ex;
# event id
$codeline = 'my '. $evt_id . ' = Wx::NewEventType;';
push @cl_id, $codeline;
# event id sub
$codeline = 'sub ' . $evt_idsub_ex . ' () { ' . $evt_id . ' }';
push @cl_idsub, $codeline;
# evt sub
my $subcode;
if ( $eventtype ne 'activex' ) {
if ( $extraparam == 2 ) {
$subcode = ' ($$) { $_[0]->Connect( -1, -1, &' . $idprefix . $evt_idsub_ex . ', $_[1] ) };';
} elsif( $extraparam == 3 ) {
$subcode = ' ($$$) { $_[0]->Connect( $_[1], -1, &' . $idprefix . $evt_idsub_ex . ', $_[2] ) };';
} else {
$subcode = ' ($$$$) { $_[0]->Connect( $_[1], $_[2], &' . $idprefix . $evt_idsub_ex . ', $_[3] ) };';
} # 5 params would be EVT_COMMAND_RANGE
} else {
# activex
$subcode = ' { &Wx::ActiveX::EVT_ACTIVEX($_[0],$_[1],"' . $extraparam . '",$_[2]) ;}';
}
$codeline = 'sub ' . $evt_evsub_ex . $subcode;
push @cl_evsub, $codeline;
Wx::LogMessage("Wx::ActiveX Creating Event: %s", $evt_evsub_ex ) if $Wx::ActiveX::__wxax_debug;
}
# combine
my @output = ();
push (@output, q() ) if $commentcode;
push (@output, q(#-----------------------------------------------------) ) if $commentcode && $foreval;
push (@output, q(package ) . $namespace . ';' ) if $foreval;
push (@output, q(#-----------------------------------------------------) ) if $commentcode && $foreval;
push (@output, q() ) if $commentcode;
push (@output, q(our ( @EXPORT_OK, %EXPORT_TAGS );) ) if $foreval;
push (@output, q() ) if $commentcode;
push (@output, q(# Local Event IDs) ) if $commentcode;
push (@output, q() ) if $commentcode;
push (@output, @cl_id);
push (@output, q() ) if $commentcode;
push (@output, q(# Event ID Sub Functions) ) if $commentcode;
push (@output, q() ) if $commentcode;
push (@output, @cl_idsub);
push (@output, q() ) if $commentcode;
push (@output, q(# Event Sub Functions) ) if $commentcode;
push (@output, q() ) if $commentcode;
push (@output, @cl_evsub);
push (@output, q() ) if $commentcode;
push (@output, q(# Exports & Tags) ) if $commentcode;
push (@output, q() ) if $commentcode;
my $tabprefix = $commentcode ? qq(\t\t\t) : '';
push (@output, '{' );
push (@output, "\t" . 'my @eventexports = qw(' );
for ( @cl_idsub_ex, @cl_evsub_ex ) {
push ( @output, $tabprefix . $_ );
}
push (@output, "\t" . ');' );
push (@output, q() ) if $commentcode;
push (@output, "\t" . '$' . 'EXPORT_TAGS{"' . $exporttag . '"} = [] if not exists $EXPORT_TAGS{"' . $exporttag . '"};' );
push (@output, "\t" . 'push @' . 'EXPORT_OK, ( @eventexports ) ;' );
push (@output, "\t" . 'push @{ $' . 'EXPORT_TAGS{"' . $exporttag . '"} }, ( @eventexports );' );
if ($foreval) {
for ( qw( all activex ) ) {
my $subst = $_;
next if $exporttag eq $subst; # don't import twice
push (@output, "\t" . 'push (@{ $' . 'EXPORT_TAGS{"' . $subst . '"} }, ( @eventexports )) if exists $EXPORT_TAGS{"' . $subst . ' "};');
}
}
push (@output, '}' );
push (@output, q() ) if $commentcode;
push (@output, q(package Wx::ActiveX; # return to base package) ) if $foreval;
push (@output, q() ) if $commentcode && $foreval;
return @output;
}
#----------------------------------------------------------------------------
# package Wx::IEHtmlWin;
#----------------------------------------------------------------------------
#our @ISA = qw( Wx::ActiveX );
#our $VERSION = '0.07'; # Wx::ActiveX Version
#----------------------------------------------------------------------------
# package Wx::MozillaHtmlWin;
#----------------------------------------------------------------------------
#our @ISA = qw( Wx::ActiveX );
#our $VERSION = '0.07'; # Wx::ActiveX Version
#----------------------------------------------------------------------------
package Wx::ActiveXEvent;
#----------------------------------------------------------------------------
use base qw( Wx::CommandEvent Wx::EvtHandler );
our $VERSION = '0.11'; # Wx::ActiveX Version
my (%EVT_HANDLES) ;
no strict ;
sub ParamSet {
my ( $evt , $idx , $val ) = @_ ;
my $pt = $evt->ParamType($idx) ;
if ($pt eq 'bool') {
$evt->ParamSetBool($idx , $val) ;
}
elsif ($pt eq 'long'||$pt eq 'int') {
$evt->ParamSetInt($idx , $val) ;
}
else {
$evt->ParamSetString($idx , $val) ;
}
}
sub ActiveXEventSub {
my ( $sub ) = @_ ;
return(
sub {
my $evt = $_[1] ;
$evt = Wx::ActiveX::XS_convert_isa($evt,"Wx::ActiveXEvent") ;
for(0..($evt->ParamCount)-1) {
my $pn = $evt->ParamName($_);
my $pv = $evt->ParamVal($_);
$evt->{$pn} = $pv ;
$evt->{ParamID}{$pn} = $_ ;
}
my @ret = &$sub( $_[0] , $evt ) ;
for(0..($evt->ParamCount)-1) {
my $pn = $evt->ParamName($_);
my $pv = $evt->ParamVal($_);
if ($pv ne $evt->{$pn}) { $evt->ParamSet($_, $evt->{$pn} ) ;}
}
return( @ret ) ;
}
);
}
sub Veto {
my ($event) = @_;
$event->{Cancel} = 1;
}
sub DESTROY { 1 };
#----------------------------------------------------------------------------
package Wx::ActiveX;
#----------------------------------------------------------------------------
1;
__END__
=head1 NAME
Wx::ActiveX - ActiveX Control Interface for Wx
=head1 VERSION
Version 0.10
=head1 SYNOPSIS
use Wx::ActiveX qw( EVT_ACTIVEX );
use Wx qw( wxID_ANY wxDefaultPosition , wxDefaultSize );
........
my $activex = Wx::ActiveX->new(
$parent,
"WMPlayer.OCX",
wxID_ANY,
wxDefaultPosition,
wxDefaultSize );
EVT_ACTIVEX( $this, $activex, "PlaylistCollectionChange", \&on_event_handler );
$activex->PropSet("URL",'pathtomyfile.avi') ;
..........
$activex->Invoke("launchURL", "http://my.url.com/file.movie") ;
... or ...
$activex->launchURL("http://my.url.com/file.movie") ;
----------------------------------------------------------------
package MyActiveXControl;
use Wx::ActiveX;
use base qw( Wx::ActiveX );
our (@EXPORT_OK, %EXPORT_TAGS);
$EXPORT_TAGS{everything} = \@EXPORT_OK;
my @activexevents = qw(
OnReadyStateChange
FSCommand
OnProgress
);
my $exporttag = 'elviscontrol';
my $eventname = 'ELVIS';
__PACKAGE__->activex_load_activex_event_types( __PACKAGE__,
$eventname,
$exporttag,
\@activexevents );
...
EVT_ACTIVEX_ELVIS_ONPROGRESS( $this, $activex,\&on_event_handler );
=head1 DESCRIPTION
Load ActiveX controls for wxWindows.
The package installs a module in Wx::Demo for reference.
There are some wrapped controls included with the package:
Wx::ActiveX::IE Internet Explorer Control
Wx::ActiveX::Mozilla Mozilla Browser Control
Wx::ActiveX::WMPlayer Windows Media Player
Wx::ActiveX::ScriptControl MS Script Control
Wx::ActiveX::Document Control Wrapper via Browser
Wx::ActiveX::Acrobat Acrobat ActiveX Control
Wx::ActiveX::Flash Adobe Flash Control
Wx::ActiveX::Quicktime Apple QuickTime ActiveX Control
See the POD for each indvidual control.
There is also a Template producer that will provide code for
a module given an ActiveX ProgID.
wxactivex_template
or
perl -MWx::ActiveX::Template -e"run_wxactivex_template();"
=head1 METHODS
=head2 new ( PARENT , CONTROL_ID , ID , POS , SIZE )
Create the ActiveX control.
PARENT need to be a Wx::Window object.
CONTROL_ID The control ID (PROGID/string).
=over
=item PropVal ( PROP_NAME )
Get the value of a propriety of the control.
=item PropSet ( PROP_NAME , VALUE )
Set a propriety of the control.
PROP_NAME The propriety name.
VALUE The value(s).
=item PropType ( PROP_NAME )
Return the type of the propriety.
=item GetEventCount
Returnt the number of events that the control have.
=item GetPropCount
Returnt the number of proprieties.
=item GetMethodCount
Returnt the number of control methods.
=item GetEventName( X )
Returnt the name of the event X, where X is a integer.
=item GetPropName( X )
Returnt the name of the propriety X, where X is a integer.
=item GetMethodName( X )
Returnt the name of the method X, where X is a integer.
=item GetMethodArgCount( MethodX )
Returnt the number of arguments of the MethodX.
=item GetMethodArgName( MethodX , ArgX )
Returnt the name of the ArgX of MethodX.
=item ListEvents()
Return an ARRAY with all the events names.
=item ListProps()
Return an ARRAY with all the proprieties names.
=item ListMethods()
Return an ARRAY with all the methods names.
=item ListMethods_and_Args()
Return an ARRAY with all the methods names and arguments. like:
foo(argx, argy)
=item ListMethods_and_Args_Hash()
Return a HASH with all the methods names (keys) and arguments (values). The arguments are inside a ARRAY ref:
my %methods = $activex->ListMethods_and_Args_Hash ;
my @args = @{ $methods{foo} } ;
=item ActivexInfos()
Return a string with all the informations about the ActiveX Control:
MouseUp
MouseMove
MouseDown
FileName
Close()
Load(file)
=back
=head1 Win32::OLE
From version 0.5 Wx::ActiveX is compatible with Win32::OLE objects:
use Wx::ActiveX ;
use Win32::OLE ;
my $activex = Wx::ActiveX->new( $this , "ShockwaveFlash.ShockwaveFlash" , 101 , wxDefaultPosition , wxDefaultSize ) ;
my $OLE = $activex->GetOLE() ;
$OLE->LoadMovie('0' , "file:///F:/swf/test.swf") ;
$OLE->Play() ;
=head1 EVENTS
All the events use EVT_ACTIVEX.
EVT_ACTIVEX($parent , $activex , "EventName" , sub{...} ) ;
** You can get the list of ActiveX event names using ListEvents():
Each ActiveX event has its own argument list (hash), and the method 'Veto' can be used to ignore the event.
In this example any new window will be canceled, seting $evt->IsAllowed to False:
EVT_ACTIVEX($this,$activex, "EventX" , sub{
my ( $obj , $evt ) = @_ ;
$evt->Veto;
}) ;
=head1 SEE ALSO
L, L, L, L
=head1 AUTHORS & ACKNOWLEDGEMENTS
Wx::ActiveX has benefited from many contributors:
Graciliano Monteiro Passos - original author
Contributions from:
Simon Flack
Mattia Barbon
Eric Wilhelm
Andy Levine
Mark Dootson
Thanks to Justin Bradford and Lindsay Mathieson
who wrote the C classes for wxActiveX and wxIEHtmlWin.
=head1 COPYRIGHT & LICENSE
Copyright (C) 2002-2008 Authors & Contributors, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=head1 CURRENT MAINTAINER
Mark Dootson
=cut
# Local variables: #
# mode: cperl #
# End: #