> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/get-started/samples/pdfviewform.md).

# PDF Viewer Component in C#, VB- PDFView

Sample C#, VB code for using Apryse 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 cu

Sample C#, VB (.NET) code for using Apryse 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](/core/get-started/samples/pdfviewsimpletest.md).

Learn more about our [Server SDK for .NET](/core/get-started/frameworks/dotnet.md) and [PDF Viewer SDK](/core/viewer/viewer.md).

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
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;
      }
   }
}
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Printing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports pdftron
Imports pdftron.PDF
Imports pdftron.Common
Imports System.Windows.Forms.VisualStyles.VisualStyleElement

Public Class PDFViewForm

   Inherits System.Windows.Forms.Form

   ' <summary>
   ' Required designer variable.
   ' </summary>
   Private components As System.ComponentModel.Container = Nothing

#If CUSTOM_NAV Then

   'The following variables are used for custom page navigation pane...
   Private _pdfdoc_tab As System.Windows.Forms.TabControl
   Private _bookmarks_tab As System.Windows.Forms.TabPage
   Private _pages_tab As System.Windows.Forms.TabPage
   Private _layers_tab As System.Windows.Forms.TabPage
   Private bookmark_tree As System.Windows.Forms.TreeView
   Private layer_tree As System.Windows.Forms.TreeView 
   Private splitter1 As System.Windows.Forms.Splitter
   Private _thumbview As ThumbView  = Nothing 'Custom thumbnail view.

#End If

   Private _pdfdoc As PDFDoc = Nothing ' Currently open PDF document.
   Private _pdfview As MyPDFView = Nothing ' Main PDF view.

   Public Sub New(ByVal main_form As MainForm)

      Me.MdiParent = main_form

      ' Create the main PDFViewCtrl control (we do it here manually for greater control)
      _pdfview = New MyPDFView(Me)
      _pdfview.Location = New System.Drawing.Point(0, 0) 'Added 'System.Drawing' to distinguish from PDF.Point to resolve compilaiton error
      _pdfview.Dock = System.Windows.Forms.DockStyle.Fill

      'Optional: Set the error and current page delegates...
      _pdfview.SetErrorReportHandler(AddressOf ErrorMsg, Nothing)
      _pdfview.SetCurrentPageHandler(AddressOf UpdateStatusBar, main_form)
      Controls.Add(_pdfview)

      ' Create other controls created using Windows Form Designer
      InitializeComponent()

   End Sub

   Public Function OpenPDF(ByVal filename As String) As Boolean
      Try
         Try
            ' Try to open as a PDF document
            _pdfdoc = New PDFDoc(filename)
         Catch ex As Exception
            ' Try to open as a PNG, JPEG, TIF, BMP, GIF, etc.
            _pdfdoc = OpenImage(filename)

            If _pdfdoc Is Nothing Then

               ' rethrow the original exception
               Throw ex
            End If
         End Try

         If Not _pdfdoc.InitSecurityHandler Then ' In case _pdfdoc is encrypted
            MessageBox.Show("Document authentication error", "PDFViewCtrl Error")
            Return False
         End If

#If CUSTOM_NAV Then

            ' Populates a custom bookmark tree control with bookmark nodes (if any). 
            Dim root As Bookmark = _pdfdoc.GetFirstBookmark()
            If root.IsValid Then
                bookmark_tree.BeginUpdate()
                FillBookmarkTree(root, bookmark_tree.Nodes)
                bookmark_tree.EndUpdate()
            Else
                ' Optional: Uncomment the following line to hide the bookmark 
                ' tab if the document does not contain bookmarks?:
                ' _pdfdoc_tab.Hide()
            End If

#End If

         ' Optional: Set page view and page presentation mode.
         ' _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page)
         ' _pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_page)

         If _pdfdoc.GetPageCount() > 2000 Then

            ' If the document has many pages use single page mode to seed up initial rendering.
            _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page)

         End If

         _pdfview.SetDoc(_pdfdoc)

#If CUSTOM_NAV Then

            _thumbview.SetDoc(_pdfdoc, _pdfview)

#End If

         SetToolMode(MyPDFView._base_tool_mode, MyPDFView._tool_mode)
      Catch ex As PDFNetException

         MessageBox.Show(ex.Message)
         Return False

      Catch ex As Exception

         MessageBox.Show(ex.ToString)
         Return False

      End Try

      Me.Text = filename ' Set the title

      Return True

   End Function

   '  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 Function OpenImage(ByVal filename As String) As PDFDoc

      Try
         Dim pdfDoc As PDFDoc = New PDFDoc ' create new document 
         Dim f As ElementBuilder = New ElementBuilder
         Dim writer As ElementWriter = New ElementWriter
         Dim page As Page = pdfDoc.PageCreate ' Add a blank page 
         writer.Begin(page)

         ' Add image to the document. 
         Dim img As pdftron.PDF.Image = pdftron.PDF.Image.Create(pdfDoc.GetSDFDoc(), filename)

         ' get image rectangle 
         Dim imgBox As Rect = New Rect(0, 0, img.GetImageWidth, img.GetImageHeight)
         Dim scaledBox As Rect = New Rect
         Dim scaleFactor As Double
         If imgBox.Height / imgBox.Width > 792 / 612 Then
            scaleFactor = imgBox.Height / 792
         Else
            scaleFactor = imgBox.Width / 612
         End If

         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
         Dim width As Integer = CType(scaledBox.Width, Integer)
         Dim height As Integer = CType(scaledBox.Height, Integer)
         Dim offsetX As Integer = 0
         Dim offsetY As Integer = 0
         Dim element As 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 ex As Exception

         ' MessageBox.Show(ex.ToString)
         Return Nothing
      End Try

   End Function

   Public Function GetPDFDoc() As PDFDoc
      If _pdfview Is Nothing Then
         Return Nothing
      Else
         Return _pdfview.GetDoc
      End If
   End Function
   Public Sub FitPage()
      _pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_page)
   End Sub

   Public Sub FitWidth()
      _pdfview.SetPageViewMode(PDFViewCtrl.PageViewMode.e_fit_width)
   End Sub

   Public Sub ZoomIn()
      _pdfview.SetZoom(_pdfview.GetZoom * 2)
   End Sub

   Public Sub ZoomOut()
      _pdfview.SetZoom(_pdfview.GetZoom / 2)
   End Sub

   Public Sub FirstPage()
      _pdfview.GotoFirstPage()
   End Sub

   Public Sub PrevPage()
      _pdfview.GotoPreviousPage()
   End Sub

   Public Sub NextPage()
      _pdfview.GotoNextPage()
   End Sub

   Public Sub LastPage()
      _pdfview.GotoLastPage()
   End Sub

   Public Sub PageSingle()
      _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_page)
   End Sub
   Public Sub PageSingleContinuous()
      _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_single_continuous)
   End Sub

   Public Sub PageFacingContinuous()
      _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_facing_continuous)
   End Sub

   Public Sub PageFacing()
      _pdfview.SetPagePresentationMode(PDFViewCtrl.PagePresentationMode.e_facing)
   End Sub

   Public Sub RotateClockwise()
      _pdfview.RotateClockwise()
   End Sub

   Public Sub RotateCounterClockwise()
      _pdfview.RotateCounterClockwise()
   End Sub
   Public Sub SetAntiAliasing(ByVal anti_alias As Boolean)
      _pdfview.SetAntiAliasing(anti_alias)
      _pdfview.Update()
   End Sub

   Public Sub SetRasterizer(ByVal built_in As Boolean)
      If built_in Then
         _pdfview.SetRasterizerType(PDFRasterizer.Type.e_BuiltIn)
      Else
         _pdfview.SetRasterizerType(PDFRasterizer.Type.e_GDIPlus)
      End If

      _pdfview.Update()
   End Sub

   Public Sub SetSmoothImages(ByVal smooth_images As Boolean)
      _pdfview.SetImageSmoothing(smooth_images)
      _pdfview.Update()
   End Sub

   Public Sub Save(ByVal filename As String)
      If _pdfdoc Is Nothing Then
         Return
      End If

      _pdfdoc.Lock()

      Try
         If Not (_pdfview Is Nothing) Then
            ' Check if there are any annotations that need to 
            ' be merged with the document.
            If Not (_pdfview._freehand_markup Is Nothing) Then
               For Each itr As DictionaryEntry In _pdfview._freehand_markup
                  Dim annot_page_num As Integer = CType(itr.Key, Integer)
                  Dim pg As Page = _pdfdoc.GetPage(annot_page_num)
                  If Not pg Is Nothing Then
                     Dim annot As FreeHandAnnot = CType(itr.Value, FreeHandAnnot)
                     annot.DrawAnnots(pg, Pens.Red)
                  End If
               Next

               _pdfview._freehand_markup = Nothing
               _pdfview.Invalidate()
               _pdfview.Update()
            End If
         End If

         _pdfdoc.Save(filename, pdftron.SDF.SDFDoc.SaveOptions.e_remove_unused)

      Catch ex As Exception
         MessageBox.Show(ex.ToString(), "Error during the Save")
      End Try

      _pdfdoc.Unlock()

   End Sub

   Public Sub SaveAs()
      If Not (_pdfdoc Is Nothing) AndAlso Not (_pdfview Is Nothing) Then

         'opens a save dialog
         Dim dlg As SaveFileDialog = New SaveFileDialog
         dlg.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*"
         dlg.DefaultExt = ".pdf"
         dlg.FileName = Text
         Dim res As DialogResult = dlg.ShowDialog
         If res = DialogResult.OK Then
            'saves the file
            Me.Save(dlg.FileName)
         End If
      End If
   End Sub

   Protected Overloads Overrides Sub OnClosing(ByVal e As CancelEventArgs)

      'called when user closes a document
      If Not (_pdfdoc Is Nothing) AndAlso Not (_pdfview Is Nothing) AndAlso (_pdfdoc.IsModified OrElse Not (_pdfview._freehand_markup Is Nothing)) Then

         'if the document exists and is modified then ask the user
         'whether or not to save it
         Dim save As DialogResult = MessageBox.Show("Would you like to save the changes to the document?", "PDFViewCtrl", MessageBoxButtons.YesNoCancel)

         If save = DialogResult.Yes Then
            'opens a save dialog
            Dim dlg As SaveFileDialog = New SaveFileDialog
            dlg.Filter = "PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*"
            dlg.DefaultExt = ".pdf"
            dlg.FileName = Text
            Dim res As DialogResult = dlg.ShowDialog
            If res = DialogResult.OK Then
               'saves the file
               Me.Save(dlg.FileName)
            Else
               If res = DialogResult.Cancel Then
                  e.Cancel = True
               End If
            End If
         Else
            If save = DialogResult.Cancel Then
               e.Cancel = True
            End If
         End If

         MyBase.OnClosing(e)
      End If
   End Sub

   ' <summary>
   ' Clean up any resources being used.
   ' </summary>
   Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      If disposing Then

#If CUSTOM_NAV Then

            _thumbview.Dispose()  ' Close the thumbnail view.

#End If

         _pdfview.Dispose()    ' Close the open PDF document in the view.
         _pdfdoc.Dispose()     ' Close the PDF document.
         If Not (components Is Nothing) Then
            components.Dispose()
         End If
      End If

      MyBase.Dispose(disposing)
   End Sub

   ' <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 Shared Sub ErrorMsg(ByVal message As String, ByVal obj As Object)
      MessageBox.Show(message, "PDFViewCtrl Error")
   End Sub

#If CUSTOM_NAV Then '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 Sub BookmarkTreeAfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles bookmark_tree.AfterSelect
      _pdfdoc.Lock()
      Dim item As Bookmark = CType(e.Node.Tag, Bookmark)
      Dim action As Action = item.GetAction
      If action.IsValid Then    ' Handle goto actions.
         ' Other types of actions can be handled in similar way.
         If action.GetType = action.Type.e_GoTo Then
            Dim dest As Destination = action.GetDest
            If dest.IsValid() Then
            Dim page As Page = dest.GetPage
               If Not page Is Nothing Then
                  _pdfview.SetCurrentPage(page.GetIndex)
               End If
            End If
         End If
      End If

      _pdfdoc.Unlock()
    End Sub

   ' Populate the tree control with bookmark items.
   Shared Sub FillBookmarkTree(ByVal item As Bookmark, ByVal nodes As TreeNodeCollection)
       Dim i As Integer = 0
       While item.IsValid
           Dim new_node As TreeNode = New TreeNode(item.GetTitle)
           nodes.Add(new_node)
           new_node.Tag = item
           If item.IsOpen Then
               new_node.Expand()
           End If
           If item.HasChildren Then    ' Recursively add children sub-trees
               FillBookmarkTree(item.GetFirstChild, new_node.Nodes)
           End If
           item = item.GetNext
           i = i + 1
       End While
   End Sub

#End If

   ' <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 Shared Sub UpdateStatusBar(ByVal current_page As Integer, ByVal num_pages As Integer, ByVal data As Object)
      If Not (data Is Nothing) Then
         Dim main_form As MainForm = CType(data, MainForm)
         main_form._current_page = current_page
         main_form._num_pages = num_pages
         main_form.UpdateStatusBar(current_page, num_pages)
      End If
   End Sub

   Public Sub SetToolMode(ByVal tool_mode As MyPDFView.CustomToolMode, ByVal custom_tool_mode As MyPDFView.CustomToolMode)
      ' Set the custom tool mode.
      MyPDFView._base_tool_mode = tool_mode
      MyPDFView._tool_mode = custom_tool_mode
      'Chaged by Kay April1------------------------
      'Set built-in tool mode (pan, text select, or custom)
      'Dim tm As PDFViewCtrl.ToolMode
      'If (tool_mode = MyPDFView.CustomToolMode.e_pan) Then
      '    tm = PDFViewCtrl.ToolMode.e_pan
      'ElseIf (tool_mode = MyPDFView.CustomToolMode.e_text_struct_select) Then
      '    tm = PDFViewCtrl.ToolMode.e_text_struct_select
      'ElseIf (tool_mode = MyPDFView.CustomToolMode.e_text_rect_select) Then
      '    tm = PDFViewCtrl.ToolMode.e_text_rect_select
      'Else
      '    tm = PDFViewCtrl.ToolMode.e_custom
      'End If
      'Chaged by Kay April1------------------------
      _pdfview.SetToolMode(tool_mode)
   End Sub

   Protected Overloads Overrides Sub OnActivated(ByVal e As EventArgs)
      If Not (_pdfview Is Nothing) Then
         Dim main_form As MainForm = CType(Me.MdiParent, MainForm)
         main_form._current_page = _pdfview.GetCurrentPage
         main_form._num_pages = _pdfview.GetDoc.GetPageCount
         main_form.UpdateStatusBar(_pdfview.GetCurrentPage(), _pdfview.GetDoc().GetPageCount())
      End If
   End Sub

   Private Sub InitializeComponent()
      Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(PDFViewForm))
      'PDFViewForm
      '
      Me.BackColor = System.Drawing.SystemColors.Control
      Me.Cursor = System.Windows.Forms.Cursors.Hand
      Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
      Me.KeyPreview = True
      Me.Name = "PDFViewForm"
      Me.Text = "PDFViewForm"
      Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
   End Sub

   Public Sub Export()
      Dim temp As ExportDialog = New ExportDialog(Me._pdfdoc)
   End Sub

   Public Sub CopySelectedText()
      _pdfview.OnTextCopy(Nothing, Nothing)
   End Sub

   Public Sub SelectAll()
      _pdfview.SelectAll()
   End Sub

   Public Sub DeselectAll()
      _pdfview.ClearSelection()
   End Sub

   Public Sub FindText()
      _pdfview.Find() 'Use the build in Find text dialog.
   End Sub

   ' Private members used for print support -------------------------
   ' In this sample, PDFDraw object is used to implement print support.
   Private pdfdraw As PDFDraw = Nothing
   Private print_page_itr As PageIterator

   Public Sub Print()
      Try

#If CUSTOM_PRINT Then

            Dim print_dlg As PrintDialog = New PrintDialog
            print_dlg.AllowSomePages = True
            print_dlg.Document = print_doc
            If (print_dlg.ShowDialog() = DialogResult.OK) Then
               pdfdraw = new PDFDraw
               pdfdraw.SetPrintMode(True)
               _print_doc.Print()
               pdfdraw.Dispose()
               pdfdraw = Nothing
            End If

#Else

         _pdfview.Print()

#End If

      Catch ex As Exception
         MessageBox.Show(ex.ToString())
      End Try
   End Sub

   '  Me.print_doc.BeginPrint += New System.Drawing.Printing.PrintEventHandler(this.OnBeginPDFPrint)
   '  Me.print_doc.PrintPage += New System.Drawing.Printing.PrintPageEventHandler(this.OnPrintPDFPage)

#If CUSTOM_PRINT Then

    Private Sub OnBeginPDFPrint(ByVal sender As System.Object, ByVal ev As System.Drawing.Printing.PrintEventArgs) Handles print_doc.BeginPrint
        Dim doc As PDFDoc = GetPDFDoc()
        If doc Is Nothing Then
            MessageBox.Show("Error: Print document is not selected.")
            Return
        End If
        print_page_itr = doc.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)
    End Sub

#if NET_1_1

    <System.Runtime.InteropServices.DllImport("gdi32.dll")> Private Shared Function GetDeviceCaps(ByVal hdc As IntPtr, ByVal nIndex As Integer) As Integer
    End Function

    Private Const PHYSICALOFFSETX As Integer = 112
    Private Const PHYSICALOFFSETY As Integer = 113

    #endif

   Private Sub OnPrintPDFPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)'Handles print_doc.PrintPage
      Dim gr As Graphics = ev.Graphics
      gr.PageUnit = GraphicsUnit.Inch
      Dim use_hard_margins As Boolean =False
      Dim rectPage As Rectangle=ev.PageBounds 'print without margins
      Dim left As Double
      Dim right As Double
      Dim top As Double
      Dim bottom As Double
      If use_hard_margins Is True Then

#if NET_1_1

      ' This code is used to obtain printer hard margins when running on .NET 1.1x or below. 
      Dim hdc As IntPtr = new IntPtr
      hdc = ev.Graphics.GetHdc(); 'Get handle to device context.
      Dim hardMarginX As Double = GetDeviceCaps(hdc, PHYSICALOFFSETX)
      Dim hardMarginY As Double = 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.
            Dim hardMarginX As Double = ev.PageSettings.HardMarginX
            Dim hardMarginY As Double = 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;
         End If

         '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.
         Dim rect As pdftron.PDF.Rect = new Rect(left*72, bottom*72, right*72, top*72)
         Dime pdfdoc As PDFDoc = GetPDFDoc()
         pdfdoc.Lock()

         Try
            If print_page_itr.HasNext() Then 
               _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 ex As Exception
            MessageBox.Show("Printing Error: " + ex.ToString)
         End Try
         pdfdoc.Unlock() 
   End Sub

#End If

End Class
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/get-started/samples/pdfviewform.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
