Programaticamente impressão no Adobe Reader 9 usando .NET Interop
-
04-07-2019 - |
Pergunta
Eu estou usando VB.Net WinForms. Gostaria de chamar o controle Adobe Reader 9 ActiveX para imprimir alguns PDFs. Eu adicionei o controle ActiveX para a caixa de ferramentas VS (a dll é AcroPDF.dll, o nome COM "Adobe PDF Reader". Depois de algum experimento o seguinte código funciona.
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
Sem o Yuk mordeu isso só vai imprimir alguns dos PDFs, parece que o fim Usando declaração está chamando dispor no controle antes que ele tenha a impressão final.
Portanto, parece que a chamada para PRINTALL é não-bloqueio, mas não consigo encontrar um callback ou condição de propriedade I pode consultar para ver se o spool de impressão foi concluída. Eu estou faltando uma propriedade / método ou há um trabalho mais elegante (e mais responsivo) em torno de?
Solução
Usando este método para imprimir vários documentos não está indo para o trabalho bom como você o encontrou.
Tê-lo trabalho é bastante complicado, mas aqui é uma descrição geral da solução.
Eu uso System.Diagnostics.Process para imprimir usando myProcess.StartInfo.Verb = "Imprimir" Então eu verificar o status e Estado de fila de impressão em duas etapas para certificar-se de que a impressão está pronto o suficiente para ser capaz de imprimir o documento seguinte. Use WMI e ManagementObjectSearcher para enumerar as informações de impressora usando "* SELECT FROM Win32_Printer". A lógica é que eu tento ver se o spool é iniciado antes de continuar a imprimir o próximo.
http://msdn.microsoft.com/en-us/ biblioteca / aa394363.aspx para a classe Win32_Printer WMI.
Outras dicas
Eu tive o mesmo problema usando AcroPDF em Delphi .. então eu descobri que quando eu "stop" do Processo através de uma mensagem, AcroPDF começa a imprimir.
Então, eu só criar um TForm modal que se fecha após alguns segundos.
var
formModal : TFormModal;
begin
formModal := TFormModal.Create(self);
//PrintMethodHere
frmPecas.CarregarDocumentoParaImpressao();
formModal.ShowModal;
end;
O TFormModal é isso e eu só inserir um ícone de carregamento no formulário para representa algo como "impressão".
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;
Nós acabamos usando o Adobe PDF Verificador para os nossos próprios fins de teste. A fim de fazer isso, tivemos que realmente lançar acrobata e manipulá-lo da interface de programação usando SendInput .
Eu estaria muito interessado em ver se seria possível usar uma API interna vez.
Você pode usar este código para exibir qualquer arquivo com seu software apropriado.
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