Impression par programme dans Adobe Reader 9 à l'aide de .NET Interop
-
04-07-2019 - |
Question
J'utilise WinForms VB.Net. Je souhaite appeler le contrôle ActiveX d'Adobe Reader 9 pour imprimer certains fichiers PDF. J'ai ajouté le contrôle ActiveX à la boîte à outils du VS (la DLL est AcroPDF.dll, le nom COM "Adobe PDF Reader". Après quelques expériences, le code suivant fonctionne.
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
Sans le bit Yuk, cela n'imprimera que certains des PDF, il semble que l'instruction End Using appelle la suppression du contrôle avant la fin de l'impression.
Par conséquent, il semble que l'appel à printAll soit non bloquant, mais je ne trouve pas de propriété de rappel ou d'état que je puisse interroger pour savoir si le spooling d'impression a été terminé. Il me manque une propriété / méthode ou existe-t-il une solution de travail plus élégante (et plus réactive)?
La solution
L'utilisation de cette méthode pour imprimer plusieurs documents ne fonctionnera pas correctement, contrairement à ce que vous avez constaté.
Le faire fonctionner est assez délicat, mais voici une description générale de la solution.
J'utilise System.Diagnostics.Process pour imprimer à l'aide de myProcess.StartInfo.Verb = " Print " Ensuite, je vérifie l'état et l'état de la file d'impression en deux étapes pour m'assurer que l'impression est suffisamment prête pour pouvoir imprimer le document suivant. Utilisez WMI et ManagementObjectSearcher pour énumérer les informations de l'imprimante à l'aide de "SELECT * FROM Win32_Printer". La logique est que j'essaie de voir si la mise en file d'attente est lancée avant de continuer à imprimer la suivante.
Voir http://msdn.microsoft.com/en-us/ bibliothèque / aa394363.aspx pour la classe WMI Win32_Printer.
Autres conseils
J'ai eu le même problème d’utilisation d’AcroPDF dans Delphi .. puis j’ai compris que, lorsque je m’arrête, j'arrête " En utilisant un message, AcroPDF commence à imprimer.
Je viens donc de créer un TForm modal qui se ferme après quelques secondes.
var
formModal : TFormModal;
begin
formModal := TFormModal.Create(self);
//PrintMethodHere
frmPecas.CarregarDocumentoParaImpressao();
formModal.ShowModal;
end;
La TFormModal est la suivante et je viens d'insérer une icône de chargement sur le formulaire pour représenter quelque chose comme "impression".
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;
Nous avons finalement utilisé le vérificateur de PDF d'Adobe à nos propres fins de test. Pour ce faire, nous avons dû lancer acrobat et manipuler son interface par programmation à l'aide de SendInput .
Je serais très intéressé de voir s'il serait possible d'utiliser une API interne à la place.
Vous pouvez utiliser ce code pour afficher n’importe quel fichier avec le logiciel approprié.
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