Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Problem displaying the Print Preview form when adding a button to the Print Preview toolbar

edited February 2013 in General
Hi,

I used the example in
http://www.digital-metaphors.com/tips/AddButtonToPreview.zip (obtained
from
http://www.digital-metaphors.com:8080/Output/Preview/How_To...Add_a_Button_to_the_Preview)
to add a button to the Preview toolbar screen.

I modified the button's OnClick method to create a PDF file and
automatically open it (so a kind of "speed button"). Here's the code I
used to achieve that which works for me:


procedure TmyPreview.ehFilebutton_Click(Sender: TObject);
begin

With Viewer.Report do
begin
AllowPrintToFile := True;
ShowPrintDialog := False;
DeviceType := 'PDF';
TextFileName := 'C:\temp\testPDF_' + FormatDateTime('YYYY-MM-DD
HH-NN-SS',now) + '.pdf';
PDFSettings.Author := 'RB Master';
PDFSettings.Title := 'Export to PDF!';
PDFSettings.OpenPDFFile := True;
print;
end;

end;

However, if I do the actions described below, the Print Preview form is
not displayed anymore. Instead the lastly generated PDF is opened in the
default PDF viewer:
1) run the application and click on Button1 which opens the Print
Preview form
2) click on the newly added button which generates a PDF file and opens
it in the default PDF viewer. Close the PDF viewer.
3) close the Print Preview form
4) click on Button1. Now instead of displaying the Print Preview form
(as it happens in step 1 above), the lastly generated PFD is opened in
the default PDF viewer.


I tried to debug and it seems that in step 4 described above no code is
run in the unit myPreview - the call "ppreport1.Print" in Unit1 returns
immediately. I guess I didn't write well the code in the
ehFilebutton_Click method, since I call the report's print method a
second time (so before ppreport1.Print called in Unit1 returns). If
needed I can upload the full testcase.

Am I doing something obviously wrong? The main goal of the newly added
button is to create a PDF from the displayed report without displaying
the Print dialog. If the code above can be fixed or if this
functionality can be achieved in some other way, I'd be very grateful
for any suggestion.

Thanks in advance.

Regards,
Jure

Comments

  • edited February 2013
    Hi Jure,

    When printing from the preview, you need to do something similar to the
    Viewer.Print method. This is the routine that gets called when the
    Print button is clicked.

    The main item you need to take from this routine is to disconnect the
    screen device from the report before printing to PDF.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2013
    Hi Nico,

    thanks for the reply.

    I'm not sure I understand correctly what you mean with "you need to do
    something similar to the Viewer.Print method". Do you mean I have to
    override it somehow or to copy its functionality from
    \Source\ppViewr.pas and modify it? If I call Viewer.Print I get the
    printer print dialog which is exactly what I want to avoid.


    I found a post dated 25.5.2006 where you described how to use a
    TppPDFDevice, so I guess using the below code I disconnect the screen
    device from the report:

    -------------8<--------------------

    The easiest way to accomplish this is to manually create a TppPDFDevice
    object and assign its publisher to the report's publisher before calling
    Report.Print. For instance...

    uses
    ppPDFDevice;


    procedure TForm1.Button1Click(Sender: TObject);
    var
    lPDFDevice: TppPDFDevice;
    begin

    lPDFDevice := TppPDFDevice.Create(self);

    try

    lPDFDevice.Publisher := ppReport1.Publisher;
    lPDFDevice.FileName := 'c:\myPDF.pdf';
    lPDFDevice.PDFSettings.OpenPDFFile := True;

    ppReport1.Print;

    finally
    lPDFDevice.Free;
    end;

    end;

    -------------8<--------------------

    If I use the above code it creates the PDF if it's called from the form
    where ppReport1 is located. However, if I try to move that code in the
    "myPreview" unit so that it would be available also to other reports, id
    doesn't create the PDF file anymore. The change I made from the above
    code is to replace the reference from "ppReport1" to "Viewer.Report":

    procedure TmyPreview.ehFilebutton_Click(Sender: TObject);
    var
    lPDFDevice: TppPDFDevice;
    begin

    lPDFDevice := TppPDFDevice.Create(self);

    try
    lPDFDevice.Publisher := Viewer.Report.Publisher;
    lPDFDevice.FileName := 'C:\temp\testPDF_' +
    FormatDateTime('YYYY-MM-DD HH-NN-SS',now) + '.pdf';
    lPDFDevice.PDFSettings.OpenPDFFile := True;

    Viewer.Report.Print;

    finally
    lPDFDevice.Free;
    end;

    end;

    Is Viewer.Report the reference to the underlying report or am I doing
    something wrong?

    Regards,
    Jure

  • edited February 2013
    Sorry if I was unclear. I meant that you will need to mimic the code in
    Viewer.Print inside your own button click event.

    The code you have below is fine but you are not disconnecting the
    ScreenDevice before making the call to Viewer.Report.Print as I
    mentioned in my previous post.

    procedure TmyPreview.ehFilebutton_Click(Sender: TObject);
    var
    lPDFDevice: TppPDFDevice;
    begin

    Viewer.ScreenDevice.Publisher := nil; //Disconnect the screen device

    lPDFDevice := TppPDFDevice.Create(self);

    try
    lPDFDevice.Publisher := Viewer.Report.Publisher;
    lPDFDevice.FileName := 'C:\temp\testPDF_' +
    FormatDateTime('YYYY-MM-DD HH-NN-SS',now) + '.pdf';
    lPDFDevice.PDFSettings.OpenPDFFile := True;

    Viewer.Report.Print;

    finally
    lPDFDevice.Free;
    end;

    end;

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2013
    Hi Nico,

    thanks for the answer. I tried the code you corrected in the previous
    post, but unfortunately the PDF file is still not created if the code is
    called from the newly added button.

    I've created a TForm1.ppReport1BeforePrint event handler with a message
    dialog to see if the event is triggered when Viewer.Report.Print is
    called and it isn't. If I assume the code in you previous reply is OK,
    can you please suggest me what else can I do?

    (I assume that mimicking the code in Viewer.Print inside my own button
    click event is already performed by the code mentioned in the previous
    post?)

    Thanks again and regards,
    Jure


  • edited February 2013
    Hi Jure,

    The post from 2006 is applying to a different topic (printing to the
    preview and PDF at the same time). When creating your own device, you
    will want to call PrintToDevices rather than Print.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2013
    Hi Nico,

    Now it works, thank you very much.

    I'd like to ask another question about the toolbar in the Print Preview
    form - if you think I should create a new post I'll do it.

    I'd like to create a dropdown box with some items (e.g. "Print to PDF",
    "Print to XLS", etc.). I've found out that using a TppTBXSubmenuItem
    object it's probably possible to achieve that (is there any other way?):

    var FDropDown: TppTBXSubmenuItem;
    .
    .
    FDropDown := Toolbar.AddSubMenu;
    FDropDown.DropdownCombo := True;
    FDropDown.Caption := 'Test dropdown';
    .
    .

    Can you point me to any documentation or any example of how to add items
    to the dropdown (probably using FDropDown.Add?), handling events when a
    item is clicked, etc.

    Regards,
    Jure


  • edited February 2013
    There is a TppTBXComboBoxItem defined in ppTBXExtItems.pas. Examples of its
    use can be found in the RB source. Open ppDesignToolItemsTBX.pas and search
    for TppGradientPalette.CreateControls and you will find code like this...

    FStyleDropDown := TppTBXComboBoxItem.Create(nil);
    aParent.Add(FStyleDropDown);
    FStyleDropDown.DropDownList := True;
    FStyleDropDown.Strings.Add('None');
    FStyleDropDown.Strings.Add('Horizontal');
    FStyleDropDown.Strings.Add('Vertical');
    FStyleDropDown.Loaded;
    FStyleDropDown.ItemIndex := 0;
    FStyleDropDown.OnChange := ehStyle_Change;




    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited February 2013
    Thanks, it works.

    Regards,
    Jure

This discussion has been closed.