Программная печать в Adobe Reader 9 с использованием .NET Interop - PullRequest
2 голосов
/ 24 октября 2008

Я использую 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 не является блокирующим, но я не могу найти свойство обратного вызова или состояние, которое я могу запросить, чтобы убедиться, что спулинг печати завершен. Мне не хватает свойства / метода или существует более элегантный (и более отзывчивый) способ обхода?

Ответы [ 4 ]

2 голосов
/ 28 декабря 2008

Использование этого метода для печати нескольких документов не будет работать хорошо, как вы обнаружили.

Работать довольно сложно, но вот общее описание решения.

Я использую System.Diagnostics.Process для печати с использованием myProcess.StartInfo.Verb = "Print" Затем я проверяю состояние и состояние очереди принтера в два этапа, чтобы убедиться, что печать достаточно готова для печати следующего документа. Используйте WMI и ManagementObjectSearcher для перечисления информации о принтере, используя «SELECT * FROM Win32_Printer». Логика в том, что я пытаюсь увидеть, запущена ли буферизация, прежде чем продолжать печатать следующую.

См. http://msdn.microsoft.com/en-us/library/aa394363.aspx для класса WMI Win32_Printer.

1 голос
/ 10 февраля 2012

У меня была та же проблема с использованием 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;
0 голосов
/ 07 декабря 2009

Вы можете использовать этот код для отображения любого файла с соответствующим программным обеспечением.

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
0 голосов
/ 24 октября 2008

В итоге мы использовали Adobe PDF Verifier для собственных целей тестирования. Для этого нам пришлось запустить acrobat и программно управлять его интерфейсом, используя SendInput

Мне было бы очень интересно узнать, можно ли вместо этого использовать внутренний API.

...