For what it is worth, I have written the following subroutines to make it easy to print pretty much any file to any printer on Windows. Also to get a list of available printers, get the default printer, etc... Thanks to node 193470 for the inspiration to do this.
Enjoy :)
Enjoy :)
######################################################## ### subs_win32printer.pl - requires the following modules #use Win32::GUI(); #use Win32::GUI::AxWindow; #use Win32::API; #use Win32::TieRegistry ( Delimiter=>"/", ArrayValues=>0 ); ######################################################## ### References ### http://www.perlmonks.org/?node_id=193470 ### http://support.microsoft.com/kb/267240 ######################################################## ############## sub printText { my $text=shift; my $printer=shift || getDefaultPrinter(); if(-e $text){$text=getFileContents($text);} #initialize Win32 API calls my $OpenPrinter = new Win32::API('winspool.drv', 'OpenPrinter',['P +','P','P'], 'N'); my $StartDocPrinter = new Win32::API('winspool.drv','StartDocPrint +er', ['N','N','P'], 'N'); my $StartPagePrinter = new Win32::API('winspool.drv','StartPagePri +nter', ['N'], 'N'); my $WritePrinter = new Win32::API('winspool.drv','WritePrinter +', ['N','P','N','P'], 'N'); my $EndPagePrinter = new Win32::API('winspool.drv','EndPagePrint +er', ['N'], 'N'); my $EndDocPrinter = new Win32::API('winspool.drv', 'EndDocPrint +er', ['N'], 'N'); my $ClosePrinter = new Win32::API('winspool.drv', 'ClosePrinte +r', ['N'], 'N'); #Setup devicename $printer .= "\0"; my $hprinter = pack('x4'); # RAW mode my $datatype = "RAW\0"; # devmode not passed in pdefaults # user selected paper/orientation/duplex have no effect in RAW mod +e # defaults set at printer will be used my $pdefaults = pack('px4L', $datatype, 0x8); # PRINTER_ACCESS_USE $OpenPrinter->Call($printer, $hprinter, $pdefaults) || return $^E; $hprinter = unpack('L', $hprinter); # name of document in print manager display # this won't be there very long unless the printer is off or busy +with another job my $docname = "Win32::API print test\0"; my $docinfo = pack("px12", $docname); $StartDocPrinter->Call($hprinter, 1, $docinfo) || return $^E; $StartPagePrinter->Call($hprinter) || return $^E; my $written = pack('x4'); $text .= "\f"; my $len = length $text; $WritePrinter->Call($hprinter, $text, $len, $written) || return $^ +E; # one canvas per sheet, next postscript would start new sheet $EndPagePrinter->Call($hprinter) || return $^E; $EndDocPrinter->Call($hprinter) || return $^E; $ClosePrinter->Call($hprinter); return 1; } ############## sub printHtml{ my $file=shift || return "No file passed to printHtml"; my $printer=shift || getDefaultPrinter(); my $navigate=''; if($file=~/^http/is){$navigate=$file;} else{ if($file !~/[\\\/]/s && -e "$progpath\\$file"){$navigate="file +://$progpath\\$file";} elsif(-e $file){$navigate="file://$file";} } if(!length($navigate)){return("No such file: $file");} if(length($printer) && !changeDefaultPrinter($printer)){return "Un +able to change printer to $printer";} # Create a window to host the axWindow in my $Window = new Win32::GUI::Window( -name => "Window", -title => "Win32::GUI::AxWindow test", -pos => [100, 100], -size => [400, 400], ); # Add a WebBrowser AxtiveX my $Control = new Win32::GUI::AxWindow ( -parent => $Window, -name => "Control", -control => "Shell.Explorer", -pos => [0, 0], -size => [400, 400], ); our $loaded=0; # Register some event $Control->RegisterEvent("StatusTextChange", sub { my $self = shift; my $eventid = shift; my $event = shift; print "Event : [$eventid][$event]\n" if length($event) && +$debug; if($eventid==102 && $event=~/^done$/is){$loaded=1;} } ); # Call Method Navigate to load the page print "printing $navigate\n" if $debug; $Control->CallMethod("Navigate", $navigate); #loop until the page has loaded while(!$loaded){ Win32::GUI::DoEvents(); select(undef,undef,undef,.1); } #Print the URL, page, or image my $PRINT = 6; my $DONTPROMPTUSER = 2; print "Printing $file to $printer\n" if $debug; #Setting custom header and footer - does not work yet #http://support.microsoft.com/kb/267240 #my $array = Win32::OLE::Variant->new(VT_ARRAY | VT_BSTR, 2); #$array->Put(0, 'Custom Header'); #$array->Put(1, 'Custom Footer'); #Call print without prompting user my $ok=$Control->CallMethod("ExecWB",$PRINT,$DONTPROMPTUSER); print "Done printing [$ok]...\n" if $debug; # Event loop $Window->Hide(); $Window->AddTimer('Shutdown', 1500); Win32::GUI::Dialog(); exit(0); sub Shutdown_Timer{ print "shutting down\n" if $debug; changeDefaultPrinter('',1); return -1; } } ################ sub changeDefaultPrinter { my $printer=shift; my $reset=shift; #Get current Default Printer my $default = $Registry->{"CUser/Software/Microsoft/Windows NT/Cur +rentVersion/Windows/Device"}; if($reset && length($Registry->{"CUser/Software/Microsoft/Windows +NT/CurrentVersion/Windows/PreDevice"})) { #Reset default printer back my $previous = $Registry->{"CUser/Software/Microsoft/Windows N +T/CurrentVersion/Windows/PreDevice"}; $Registry->{"CUser/Software/Microsoft/Windows NT/CurrentVersio +n/"}={ "Windows/" => {"/Device"=>$previous} }; #remove previous key $Registry->{"CUser/Software/Microsoft/Windows NT/CurrentVersio +n/"}={ "Windows/" => {"/PreDevice"=>''} }; return 1; } if(!length($printer)){return 0;} #if the printer is already set, return true if($default=~/^\Q$printer\E\,/is){return 1;} #Does the printer exist? if(!defined $Registry->{"CUser/Software/Microsoft/Windows NT/Curre +ntVersion/Devices/$printer"}){return 0;} #Set PreDevice to current default printer $Registry->{"CUser/Software/Microsoft/Windows NT/CurrentVersion/"} +={ "Windows/" => {"/PreDevice"=>$default} }; my $newval=$Registry->{"CUser/Software/Microsoft/Windows NT/Curren +tVersion/Devices/$printer"}; $Registry->{"CUser/Software/Microsoft/Windows NT/CurrentVersion/"} +={ "Windows/" => {"/Device"=>"$printer\,$newval"} }; return 1; } ################ sub getDefaultPrinter { my ($printer,$drv,$port)=split(/\,/,$Registry->{"CUser/Software/Micros +oft/Windows NT/CurrentVersion/Windows/Device"},3); return $printer; } ################ sub getPrinters { my $printers=$Registry->{"CUser/Software/Microsoft/Windows NT/Curr +entVersion/Devices/"}; my @printers=(); foreach my $printer (keys(%{$printers})) { $printer=~s/^\/+//sg; push(@printers,$printer); #print "Printer: $printer\n"; } if(wantarray){return @printers}; return join(',',@printers); } return 1;
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Printing a file in M$ Windows
by ww (Archbishop) on Jun 05, 2007 at 18:31 UTC |
Back to
Cool Uses for Perl