Domanda

Sto usando VB.Net WinForms. Vorrei chiamare il controllo ActiveX di Adobe Reader 9 per stampare alcuni PDF. Ho aggiunto il controllo ActiveX alla casella degli strumenti VS (la dll è AcroPDF.dll, il nome COM " Adobe PDF Reader " ;. Dopo qualche esperimento il seguente codice funziona.

Dim files As String() = Directory.GetFiles(TextBoxPath.Text, "*.pdf", SearchOption.TopDirectoryOnly)

Using ActiveXPDF As New AxAcroPDFLib.AxAcroPDF

    Me.Controls.Add(ActiveXPDF)
    ActiveXPDF.Hide()

    For Each filename As String In files

        ActiveXPDF.LoadFile(filename)
        ActiveXPDF.printAll()

        'Begin Yukky Hack    '


        Dim endTime As Date = DateAdd(DateInterval.Second, 20, Now)
        Do While Now < endTime
            My.Application.DoEvents()
        Loop

        'End Yuk   '

    Next

End Using

Senza il bit Yuk questo stamperà solo alcuni dei PDF, sembra che l'istruzione End Using stia chiamando dispose sul controllo prima che abbia finito di stampare.

Quindi sembra che la chiamata a printAll non sia bloccante ma non riesco a trovare una proprietà di callback o status che posso interrogare per vedere se lo spool di stampa è stato completato. Mi manca una proprietà / metodo o c'è un modo più elegante (e più reattivo) di aggirare?

È stato utile?

Soluzione

L'uso di questo metodo per stampare più documenti non funzionerà come hai trovato.

Farlo funzionare è piuttosto complicato, ma ecco una descrizione generale della soluzione.

Uso System.Diagnostics.Process per stampare usando myProcess.StartInfo.Verb = " Print " Quindi controllo lo stato e lo stato della coda di stampa in due passaggi per assicurarmi che la stampa sia abbastanza pronta per poter stampare il documento successivo. Usa WMI e ManagementObjectSearcher per enumerare le informazioni sulla stampante usando " SELECT * FROM Win32_Printer " ;. La logica è che provo a vedere se lo spooling viene avviato prima di continuare a stampare quello successivo.

Vedi http://msdn.microsoft.com/en-us/ libreria / aa394363.aspx per la classe WMI Win32_Printer.

Altri suggerimenti

Ho avuto lo stesso problema usando AcroPDF in Delphi .. poi ho capito che quando ho "fermato" il processo utilizzando un messaggio, AcroPDF inizia a stampare.

Quindi ho appena creato un TForm modale che si chiude dopo alcuni secondi.

var
  formModal : TFormModal;
begin
  formModal := TFormModal.Create(self);
  //PrintMethodHere  
  frmPecas.CarregarDocumentoParaImpressao();
  formModal.ShowModal;
end;

TFormModal è questo e inserisco semplicemente un'icona di caricamento sul modulo per rappresentare qualcosa come "stampa".

unit FModal;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Animate, GIFCtrl;

type
  TFormModal = class(TForm)
    Timer: TTimer;
    imgGif: TRxGIFAnimator;
    procedure TimerTimer(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormModal: TFormModal;

implementation

{$R *.dfm}
//    Author: Anderson Mello  Date: 09-fev-2012
//  DEscription: Using TTimer after 5 seconds I close this form
procedure TFormModal.TimerTimer(Sender: TObject);
begin
 close;
end;

//    Author: Anderson Mello  Date: 09-fev-2012
//  Description: Enable the timer only when the form is shown
procedure TFormModal.FormShow(Sender: TObject);
begin
 Timer.Enabled := true;
end;

//  Description: disable when close
procedure TFormModal.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Timer.Enabled := false;
end;

//    Author: Anderson Mello  Date: 09-fev-2012
//  Description: disable close button "X", so the user can't close 
procedure TFormModal.FormCreate(Sender: TObject);
var
  hSysMenu:HMENU;
begin
  hSysMenu:=GetSystemMenu(Self.Handle,False);
  if hSysMenu <> 0 then begin
    EnableMenuItem(hSysMenu,SC_CLOSE,MF_BYCOMMAND or MF_GRAYED);
    DrawMenuBar(Self.Handle);
  end;
  KeyPreview:=True;
end;

//    Author: Anderson Mello  Date: 09-fev-2012
//  Description: disable shortcuts to close
procedure TFormModal.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_F4) and (ssAlt in Shift) then
    Key:=0;
end;

Abbiamo finito per utilizzare Adobe PDF Verifier per i nostri scopi di test. Per fare ciò abbiamo dovuto avviare effettivamente acrobat e manipolarne l'interfaccia in modo programmatico utilizzando SendInput .

Sarei molto interessato a vedere se fosse possibile utilizzare invece un'API interna.

Puoi usare questo codice per visualizzare qualsiasi file con il suo software appropriato.

Sub Show_Document(ByVal FILENAME As String)
    Dim p As Process = Nothing
    Try
        If My.Computer.FileSystem.FileExists(FILENAME) Then
            p = Process.Start(FILENAME)
            p.Dispose()
        End If

    Catch ex As Exception

    Finally

    End Try

End Sub
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top