Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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 :)
######################################################## ### 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;

In reply to Printing a file in M$ Windows by slloyd

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-03-29 15:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found