More languages
Some test text!
More languages
Sample C# code for using PDFTron SDK's PDF viewer control to implement a number of custom tools (such as freehand tool, link creation tool, rectangular zoom etc) and custom GUI elements (such as custom navigation and printing). For a more introductory example of how to use PDFViewCtrl, please take a look at the PDFViewSimple sample code. Learn more about our C# PDF Library and PDF Viewer SDK.
Get Started Samples DownloadTo run this sample, get started with a free trial of Apryse SDK.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using pdftron;
using pdftron.PDF;
using pdftron.SDF;
using pdftron.Common;
namespace PDFViewCS
{
/// <summary>
/// Summary description for PDFViewForm.
/// </summary>
public class PDFViewForm : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
#if CUSTOM_NAV
// The following variables are used for custom page navigation pane...
private System.Windows.Forms.TabControl _pdfdoc_tab;
private System.Windows.Forms.TabPage _bookmarks_tab;
private System.Windows.Forms.TabPage _pages_tab;
private System.Windows.Forms.TabPage _layers_tab;
private System.Windows.Forms.TreeView bookmark_tree;
private System.Windows.Forms.TreeView layer_tree;
private System.Windows.Forms.Splitter splitter1;
private ThumbView _thumbview = null; // Custom thumbnail view.
#endif
private PDFDoc _pdfdoc = null; // Currently open PDF document.
private MyPDFView _pdfview = null; // Main PDF view.
public PDFViewForm(MainForm main_form)
{
this.MdiParent = main_form;
// Create other controls created using Windows Form Designer
InitializeComponent();
// Create the main PDFViewCtrl control (we do it here manually for greater control)
_pdfview = new MyPDFView(this);
_pdfview.Location = new System.Drawing.Point(0, 0);
_pdfview.Dock = System.Windows.Forms.DockStyle.Fill;
// Optional: Set the error and current page delegates...
_pdfview.SetErrorReportHandler(new PDFViewErrorDelegate(ErrorMsg), null);
_pdfview.SetCurrentPageHandler(new PDFViewCurrentPageDelegate(UpdateStatusBar), main_form);
_pdfview.SetDownloadReportHandler(new PDFViewDownloadDelegate(OnDownload), null);
_pdfview.SetUrlExtraction(false);
Controls.Add(_pdfview);
}
public bool OpenPDF(String filename)
{
try
{
try { // Try to open as a PDF document...
_pdfdoc = new PDFDoc(filename);
}
catch (Exception ex) {
// Try to open as a PNG, JPEG, TIF, BMP, GIF, etc.
_pdfdoc = OpenImage(filename);
if (_pdfdoc == null) {
throw ex; // re-throw the original exception
}
}
if (!_pdfdoc.InitSecurityHandler()) // In case _pdfdoc is encrypted
{
MessageBox.Show("Document authentication error", "PDFViewCtrl Error");
return false;
}
#if CUSTOM_NAV
// Populates a custom bookmark tree control with bookmark nodes (if any).
Bookmark root = _pdfdoc.GetFirstBookmark();
if (root.IsValid())
{
bookmark_tree.BeginUpdate();
BuildBookmarkTree(root, bookmark_tree.Nodes);
bookmark_tree.EndUpdate();
}
else
{
// Optional: Uncomment the following line to hide the bookmark
// tab if the document does not containing bookmarks?:
// _pdfdoc_tab.Hide();
}
// Add OCGs (if any) to 'PDF Layers' tab.
if (_pdfdoc.HasOC())
{
pdftron.PDF.OCG.Config cfg = _pdfdoc.GetOCGConfig();
Obj order = cfg.GetOrder();
if (order != null) {
layer_tree.BeginUpdate();
BuildLayerTree(order, cfg, layer_tree.Nodes, null);
layer_tree.EndUpdate();
}
}
#endif
// Optional: Set page view and page presentation mode.
// _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page);
// _pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_page);
// _pdfview.SetProgressiveRendering(false);
if (_pdfdoc.GetPageCount() > 2000)
{
// If the document has many pages use single page mode to seed up initial rendering.
_pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page);
}
_pdfview.SetDoc(_pdfdoc);
#if CUSTOM_NAV
_thumbview.SetDoc(_pdfdoc, _pdfview);
#endif
SetToolMode(MyPDFView._base_tool_mode, MyPDFView._tool_mode); // Set the view to use the currently selected tool (i.e. hand, text selection, pencil, etc).
}
catch(PDFNetException ex)
{
MessageBox.Show(ex.Message);
return false;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
return false;
}
this.Text = filename; // Set the title
return true;
}
public bool OpenPDFUrl(String url, String password)
{
try
{
// Open a PDF file at the given url. This works best with PDF's that
// are linearized, as pages can be downloaded and viewed in random access order,
// without the need to download the entire document. A viewing session can also be
// persisted across multiple viewing/application sessions to remove redundant downloads
// and improve overall performance by using the optional cache_file parameter.
_pdfview.OpenURLAsync(url, "", password);
}
catch (PDFNetException ex)
{
MessageBox.Show(ex.Message);
return false;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return false;
}
this.Text = url; // Set the title
return true;
}
/// <summary>
/// This callback method (delegate) was registered using _pdfview.SetDownloadReportHandler
/// in PDFViewCS constructor. The callback can be used to update download progress
/// within GUI applications etc.
/// </summary>
private void OnDownload(DownloadedType type, Int32 page_num, Int32 obj_num, String msg, Object obj)
{
switch (type)
{
case DownloadedType.e_opened:
// e_opened indicates that we have a valid, but incomplete PDFDoc.
_pdfdoc = _pdfview.GetDoc();
MainForm main_form = (MainForm) this.MdiParent;
main_form.UpdateStatusBar(_pdfview.GetCurrentPage(), _pdfview.GetDoc().GetPageCount());
// the PDF should be treated as read only, and only simple functions
// should be called on the doc, until e_finished has been called.
break;
case DownloadedType.e_page:
// this indicates the entire page is downloaded and it is safe to modify.
// for example add a new annotation
break;
case DownloadedType.e_finished:
// we now have the full PDF file and it can be treated like any other
if (MessageBox.Show("Download complete, would you like to save the PDF locally?",
"PDF Downloaded", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
SaveAs();
}
break;
case DownloadedType.e_failed:
// downloading has stopped if this occurs
MessageBox.Show(msg);
this.Text = "";
break;
}
}
// A utility function used to display other images types besides PDF
// inside MyPDFView. This functionality can be used to display TIF, JPEG,
// BMP, PNG, etc.
public PDFDoc OpenImage(string filename)
{
try
{
PDFDoc pdfDoc = new PDFDoc(); // create new document
ElementBuilder f = new ElementBuilder();
ElementWriter writer = new ElementWriter();
Page page = pdfDoc.PageCreate(); // Add a blank page
writer.Begin(page);
// Add image to the document.
pdftron.PDF.Image img = pdftron.PDF.Image.Create(pdfDoc, filename);
// get image rectangle
Rect imgBox = new Rect(0, 0, img.GetImageWidth(),
img.GetImageHeight());
Rect scaledBox = new Rect();
double scaleFactor;
if(imgBox.Height()/imgBox.Width()>792/612)
{
scaleFactor=imgBox.Height()/792;
}
else
{
scaleFactor=imgBox.Width()/612;
}
scaledBox.x2=imgBox.x2/scaleFactor;
scaledBox.y2=imgBox.y2/scaleFactor;
// set crop and media box of this page to fit with the scaled image
page.SetCropBox(scaledBox);
page.SetMediaBox(scaledBox);
// create the image element and add it to the page
int width = (int)scaledBox.Width();
int height = (int) scaledBox.Height();
int offsetX = 0;
int offsetY = 0;
Element element = f.CreateImage(img, new Matrix2D(width, 0, 0,
height, offsetX, offsetY));
writer.WritePlacedElement(element);
writer.End(); // Finish writing to the page
pdfDoc.PagePushBack(page);
return pdfDoc;
}
catch (Exception)
{
// MessageBox.Show(ex.ToString());
return null;
}
}
public Boolean IsNavSidebarVisible()
{
return _pdfview.IsNavPanelVisible();
}
public void ShowNavSidebar(Boolean show)
{
_pdfview.ShowNavPanel(show);
}
public PDFDoc GetPDFDoc()
{
if (_pdfview == null) return null;
else return _pdfview.GetDoc();
}
public void FitPage()
{
_pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_page);
}
public void FitWidth()
{
_pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_width);
}
public void ZoomIn()
{
_pdfview.SetZoom(_pdfview.GetZoom()*2);
}
public void ZoomOut()
{
_pdfview.SetZoom(_pdfview.GetZoom()/2);
}
public void FirstPage()
{
_pdfview.GotoFirstPage();
}
public void PrevPage()
{
_pdfview.GotoPreviousPage();
}
public void NextPage()
{
_pdfview.GotoNextPage();
}
public void LastPage()
{
_pdfview.GotoLastPage();
}
public void PageSingle()
{
_pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page);
}
public void PageSingleContinuous()
{
_pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_continuous);
}
public void PageFacingContinuous()
{
_pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_facing_continuous);
}
public void PageFacing()
{
_pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_facing);
}
public void RotateClockwise()
{
_pdfview.RotateClockwise();
}
public void RotateCounterClockwise()
{
_pdfview.RotateCounterClockwise();
}
public void DocProperties()
{
_pdfview.DocProperties();
}
public void DeletePages()
{
_pdfview.DeletePages();
}
public void InsertBlankPages()
{
_pdfview.InsertBlankPages();
}
public void InsertPages()
{
_pdfview.InsertPages();
}
public void ReplacePages()
{
_pdfview.ReplacePages();
}
public void SetAntiAliasing(bool anti_alias)
{
_pdfview.SetAntiAliasing(anti_alias);
_pdfview.Update();
}
public void SetRasterizer(bool built_in)
{
if (built_in)
_pdfview.SetRasterizerType(PDFRasterizer.Type.e_BuiltIn);
else
_pdfview.SetRasterizerType(PDFRasterizer.Type.e_GDIPlus);
_pdfview.Update();
}
public void SetSmoothImages(bool smooth_images)
{
_pdfview.SetImageSmoothing(smooth_images);
_pdfview.Update();
}
public void Save (string filename)
{
if (_pdfdoc == null) return;
_pdfdoc.Lock();
try
{
// If the user created new markup, merge it before saving the document.
if (_pdfview != null)
{
if (_pdfview._freehand_markup != null)
{
foreach( DictionaryEntry itr in _pdfview._freehand_markup)
{
int annot_page_num = (int) itr.Key;
Page pg = _pdfdoc.GetPage(annot_page_num);
if (pg != null)
{
FreeHandAnnot annot = (FreeHandAnnot) itr.Value;
annot.DrawAnnots(pg, Pens.Red);
}
}
_pdfview._freehand_markup = null;
_pdfview.Invalidate();
_pdfview.Update();
}
}
_pdfdoc.Save(filename, pdftron.SDF.SDFDoc.SaveOptions.e_remove_unused);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString(), "Error during the Save");
}
_pdfdoc.Unlock();
}
public void SaveAs ()
{
// Check if there are any annotations that need to
// be merged with the document.
if (_pdfdoc != null && _pdfview != null)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*";
dlg.DefaultExt = ".pdf";
dlg.FileName = Text;
DialogResult res = dlg.ShowDialog();
if (res == DialogResult.OK)
{
this.Save(dlg.FileName);
}
}
}
protected override void OnClosing (CancelEventArgs e)
{
// Check if there are any annotations that need to
// be merged with the document.
if (_pdfdoc != null && _pdfview != null &&
(_pdfdoc.IsModified() || _pdfview._freehand_markup != null))
{
DialogResult save = MessageBox.Show("Would you like to save the changes to the document?", "PDFViewCtrl", MessageBoxButtons.YesNoCancel);
if (save == DialogResult.Yes)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*";
dlg.DefaultExt = ".pdf";
dlg.FileName = Text;
DialogResult res = dlg.ShowDialog();
if (res == DialogResult.OK)
{
this.Save(dlg.FileName);
}
else if (res == DialogResult.Cancel)
{
e.Cancel = true;
}
}
else if (save == DialogResult.Cancel)
{
e.Cancel = true;
}
base.OnClosing(e);
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if( disposing )
{
#if CUSTOM_NAV
_thumbview.Dispose(); // Close the thumbnail view.
#endif
if (_pdfview != null)
{
_pdfview.CloseDoc();
_pdfview.Dispose(); // Close the open PDF document in the view.
}
if (_pdfdoc != null)
{
_pdfdoc.Dispose(); // Close the PDF document.
}
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
/// <summary>
/// This callback method (delegate) was registered using _pdfview.SetErrorReportProc
/// in PDFViewCS constructor. The callback can be used to report any errors that may
/// occur during page rendering.
/// </summary>
public static void ErrorMsg(String message, Object obj)
{
MessageBox.Show(message, "PDFViewCtrl Error");
}
#if CUSTOM_NAV // Custom bookmark and PDF layer navigation sample
// Handle the the bookmark select event (i.e. when the user selects a node in the bookmark tree).
private void BookmarkTreeAfterSelect(System.Object sender, System.Windows.Forms.TreeViewEventArgs e)
{
if (e.Node.Tag == null) return;
_pdfdoc.Lock();
Bookmark item = (Bookmark) e.Node.Tag;
Action action = item.GetAction();
if (action.IsValid()) // Handle goto actions.
{ // Other types of actions can be handled in similar way.
if (action.GetType() == Action.Type.e_GoTo)
{
Destination dest = action.GetDest();
if (dest.IsValid())
{
Page page = dest.GetPage();
if (page != null) _pdfview.SetCurrentPage(page.GetIndex());
}
}
}
_pdfdoc.Unlock();
}
// Populate the bookmark tree control with bookmark items.
static void BuildBookmarkTree(Bookmark item, TreeNodeCollection nodes)
{
for (int i=0; item.IsValid(); item=item.GetNext(), ++i)
{
TreeNode new_node = new TreeNode(item.GetTitle());
nodes.Add(new_node);
new_node.Tag = item;
if (item.IsOpen()) new_node.Expand();
if (item.HasChildren()) // Recursively add children sub-trees
{
BuildBookmarkTree(item.GetFirstChild(), new_node.Nodes);
}
}
}
// Handle the the layer On/OFF event
private void LayerTreeAfterCheck(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
pdftron.PDF.OCG.Context ctx = _pdfview.GetOCGContext();
if (ctx == null || e.Node.Tag == null) return;
pdftron.PDF.OCG.Group ocg = (pdftron.PDF.OCG.Group) e.Node.Tag;
ctx.SetState(ocg, e.Node.Checked);
_pdfview.Update();
}
// Populate the layer tree control with OCG (Optional Content Group) layers.
static void BuildLayerTree(Obj layer_arr, pdftron.PDF.OCG.Config init_cfg, TreeNodeCollection nodes, TreeNode parent_node)
{
if (layer_arr == null || layer_arr.IsArray() == false) return;
Obj lobj;
int sz = layer_arr.Size();
for (int i=0; i<sz; ++i)
{
lobj = layer_arr.GetAt(i);
if (lobj.IsArray() && lobj.Size()>0)
{
TreeNode new_node = new TreeNode();
nodes.Add(new_node);
new_node.Checked = true;
new_node.Expand();
// Recursively add children sub-trees
BuildLayerTree(lobj, init_cfg, new_node.Nodes, new_node);
}
else if (i==0 && lobj.IsString())
{
parent_node.Text = lobj.GetAsPDFText();
}
else
{
pdftron.PDF.OCG.Group grp = new pdftron.PDF.OCG.Group(lobj);
if (grp.IsValid())
{
TreeNode new_node = new TreeNode(grp.GetName());
nodes.Add(new_node);
new_node.Tag = grp;
new_node.Checked = grp.GetInitialState(init_cfg);
}
}
}
}
#endif
/// <summary>
/// This callback method (delegate) was registered using _pdfview.SetCurrentPageProc
/// in PDFViewCS constructor. The callback can be used to update the current page number
/// within GUI applications etc. In this case we update the status bar in the main form.
/// </summary>
public static void UpdateStatusBar(int current_page, int num_pages, Object data)
{
if (data != null)
{
MainForm main_form = (MainForm) data;
main_form.UpdateStatusBar(current_page, num_pages);
}
}
protected override void OnActivated (EventArgs e)
{
if (_pdfview != null && _pdfview.GetDoc() != null)
{
MainForm main_form = (MainForm) this.MdiParent;
main_form.UpdateStatusBar(_pdfview.GetCurrentPage(), _pdfview.GetDoc().GetPageCount());
}
}
public void SetToolMode(PDFViewCtrl.ToolMode tool_mode, MyPDFView.CustomToolMode custom_tool_mode)
{
MyPDFView._base_tool_mode = tool_mode;
MyPDFView._tool_mode = custom_tool_mode;
_pdfview.SetToolMode(tool_mode);
}
public void Export()
{
ExportDialog e = new ExportDialog(this._pdfdoc);
e.ShowDialog();
}
public void CopySelectedText()
{
_pdfview.OnTextCopy(null, null);
}
public void SelectAll(){
_pdfview.SelectAll();
}
public void DeselectAll(){
_pdfview.ClearSelection();
}
public void FindText()
{
_pdfview.Find(); // Use the build in Find text dialog.
}
public void Print()
{
try
{
#if CUSTOM_PRINT
PrintDialog print_dlg = new PrintDialog();
print_dlg.AllowSomePages = true;
print_dlg.Document = _print_doc;
if (print_dlg.ShowDialog() == DialogResult.OK)
{
_pdfdraw = new PDFDraw();
_pdfdraw.SetPrintMode(true);
_print_doc.Print();
_pdfdraw.Dispose();
_pdfdraw = null;
}
#else
_pdfview.Print(); // Use built in PDFPrint function.
#endif
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
#if CUSTOM_PRINT
// In this sample, PDFDraw object is used to implement print support.
private PDFDraw _pdfdraw = null;
private PageIterator print_page_itr;
private System.Drawing.Printing.PrintDocument _print_doc;
private void OnBeginPDFPrint(object sender, PrintEventArgs ev)
{
PDFDoc pdfdoc = GetPDFDoc();
if (pdfdoc == null)
{
MessageBox.Show("Error: Print document is not selected.");
return;
}
print_page_itr = pdfdoc.GetPageIterator();
// PDFNet includes two different rasterizer implementations.
//
// The two implementations offer a trade-off between print
// speed and accuracy/quality, as well as a trade-off between
// vector and raster output.
//
// e_GDIPlus rasterizer can be used to render the page
// using Windows GDI+, whereas e_BuiltIn rasterizer can
// be used to render bitmaps using platform-independent
// graphics engine (in this case images are always converted
// to bitmap prior to printing).
_pdfdraw.SetRasterizerType(PDFRasterizer.Type.e_GDIPlus);
// You can uncomment the following lines in order to use
// built-in, platform-independent rasterizer instead of GDI+.
// pdfdraw.SetRasterizerType(PDFRasterizer.Type.e_BuiltIn);
// pdfdraw.SetDPI(200);
}
#if NET_1_1
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
private const int PHYSICALOFFSETX = 112;
private const int PHYSICALOFFSETY = 113;
#endif
private void OnPrintPDFPage(object sender, PrintPageEventArgs ev)
{
Graphics gr = ev.Graphics;
gr.PageUnit = GraphicsUnit.Inch;
bool use_hard_margins = false;
Rectangle rectPage = ev.PageBounds; //print without margins
//Rectangle rectPage = ev.MarginBounds; //print using margins
double left, right, top, bottom;
if (use_hard_margins) // You could adjust the rectangle to account for hard and soft margins, etc.
{
#if NET_1_1
// This code is used to obtain printer hard margins when running on .NET 1.1x or below.
IntPtr hdc = new IntPtr();
hdc = ev.Graphics.GetHdc(); // Get handle to device context.
double hardMarginX = GetDeviceCaps(hdc, PHYSICALOFFSETX);
double hardMarginY = GetDeviceCaps(hdc, PHYSICALOFFSETY);
ev.Graphics.ReleaseHdc(hdc); // Release handle to device context.
#else
// If you are running on .NET Framework 2.x or above, you can directly access 'hard margin' property.
double hardMarginX = ev.PageSettings.HardMarginX;
double hardMarginY = ev.PageSettings.HardMarginY;
#endif
left = (rectPage.Left - hardMarginX) / 100.0;
right = (rectPage.Right - hardMarginX) / 100.0;
top = (rectPage.Top - hardMarginY) / 100.0;
bottom = (rectPage.Bottom - hardMarginY) / 100.0;
}
else
{
left= rectPage.Left / 100.0;
right = rectPage.Right / 100.0;
top = rectPage.Top / 100.0;
bottom= rectPage.Bottom / 100.0;
}
// The above page dimensions are in inches. We need to convert
// the page dimensions to PDF units (or points). One point is
// 1/72 of an inch.
pdftron.PDF.Rect rect = new Rect(left*72, bottom*72, right*72, top*72);
PDFDoc pdfdoc = GetPDFDoc();
if (pdfdoc == null)
{
MessageBox.Show("Error: Print document is not selected.");
return;
}
pdfdoc.Lock();
try
{
if (print_page_itr.HasNext())
{
_pdfdraw.DrawInRect(print_page_itr.Current(), gr, rect);
// Move to the next page, or finish printing
print_page_itr.Next();
ev.HasMorePages = print_page_itr.HasNext();
}
else ev.HasMorePages = false;
}
catch (Exception ex)
{
MessageBox.Show("Printing Error: " + ex.ToString());
}
pdfdoc.Unlock();
}
#endif
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PDFViewForm));
//
// PDFViewForm
//
this.BackColor = System.Drawing.SystemColors.Control;
this.Cursor = System.Windows.Forms.Cursors.Hand;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.KeyPreview = true;
this.Name = "PDFViewForm";
this.Text = "PDFViewForm";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}
}
}