Программная печать в Adobe Reader 9 с использованием .NET Interop
-
04-07-2019 - |
Вопрос
Я использую VB.Net WinForms. Я хотел бы вызвать элемент управления Adobe Reader 9 ActiveX для печати некоторых PDF-файлов. Я добавил элемент управления ActiveX в панель инструментов VS (dll - AcroPDF.dll, COM-имя «Adobe PDF Reader»). После некоторого эксперимента работает следующий код.
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
Без бита Юк это будет печатать только некоторые PDF-файлы, кажется, что оператор End Using вызывает dispose для элемента управления до того, как он закончит печать.
Поэтому кажется, что вызов printAll не является блокирующим, но я не могу найти обратный вызов или свойство status, которое я могу запросить, чтобы убедиться, что спулинг печати завершен. Мне не хватает свойства / метода или существует более элегантный (и более отзывчивый) способ обхода?
Решение
Использование этого метода для печати нескольких документов не будет работать хорошо, как вы обнаружили.
Работать с ним довольно сложно, но вот общее описание решения.
Я использую System.Diagnostics.Process для печати с использованием myProcess.StartInfo.Verb = " Печать " Затем я проверяю состояние и состояние очереди принтера в два этапа, чтобы убедиться, что печать достаточно готова для печати следующего документа. Используйте WMI и ManagementObjectSearcher для перечисления информации о принтере, используя " SELECT * FROM Win32_Printer " ;. Логика в том, что я пытаюсь увидеть, запущена ли буферизация, прежде чем продолжать печатать следующую. Р>
См. http://msdn.microsoft.com/en-us/ library / aa394363.aspx для класса WMI Win32_Printer.
Другие советы
У меня была та же проблема с использованием AcroPDF в Delphi ... затем я понял, что когда я "останавливаюсь" Когда процесс использует сообщение, AcroPDF начинает печатать.
Итак, я просто создаю модальную TForm, которая закрывается через несколько секунд. Р>
var
formModal : TFormModal;
begin
formModal := TFormModal.Create(self);
//PrintMethodHere
frmPecas.CarregarDocumentoParaImpressao();
formModal.ShowModal;
end;
TFormModal - это так, и я просто вставляю значок загрузки в форму, чтобы обозначить что-то вроде "печати".
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;
В итоге мы использовали Adobe PDF Verifier для собственных целей тестирования. Чтобы сделать это, нам пришлось запустить acrobat и программно управлять его интерфейсом, используя SendInput а>. Р>
Мне было бы очень интересно узнать, можно ли вместо этого использовать внутренний API.
Вы можете использовать этот код для отображения любого файла с соответствующим программным обеспечением.
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