.NET PDF view example

You need a PDF Viewer for your DotNET application?

WPViewPDF can be easily integrated into .NET application for Windows. This is a screenshot of our sample application which main form which has just about 335 lines of code – most of it displayed on this page. But this does not mean you cannot change anything. To the contrary, since the GUI is created in generic code, you can with just a few changes update the entire look and the user experience.

This is a screenshot of the demo:

PDF_edit_in_dotnet

The initialization of the form is done here

        public Form1()
        {
            InitializeComponent();


            // Set some properties
            pdfViewer1.ViewerStart("xxx", "yyy", 0);

            pdfViewer1.ViewOptions = eViewOptions.wpExpandAllBookmarks |
                   eViewOptions.wpExpandAllBookmarks |
                   eViewOptions.wpSelectPage |
                   eViewOptions.wpShowPageSelection;

            pdfViewer1.ViewControls =
                  eViewControls.wpHorzScrollBar |
                  eViewControls.wpNavigationPanel |
                  eViewControls.wpPropertyPanel |
                  eViewControls.wpVertScrollBar |
                  eViewControls.wpViewPanel;


            pdfViewer1.AllowMovePages = true;


             // Make sure the annotations work interactively!
            pdfViewer1.Command(commands.COMPDF_ACRO_MAKEDRAWOBJ, "", 8192);  

             // enlarge the zoom buttons
             pdfViewer1.Command(commands.COMPDF_SETBUTTONHEIGHT, 32 );

             // Standard Action Mode 'Click + Pan'
             pdfViewer1.Command(commands.COMPDF_SetActionMode,"",1);

             // ENABLE saving of annotations
             pdfViewer1.Command(commands.COMPDF_Ann_SetAnnotSaveMode, 1);

             // Load the menu from the embedded actions
             pdfViewer1.InitMainMenu(menuStrip1, doExecuteWPViewAction, fileToolStripMenuItem, infoToolStripMenuItem);

             // Initialize the toolbar
             InitToolbar(toolStrip1, _ActionButtons );     

        }

The code calls a function to initialize the toolbar – InitToolbar.

It uses a string array to list all action names which should be used. The names are also used to load the PNG images from the resources to be displayed on the buttons.

        private string[] _ActionButtons = new string[23] {
                  "FileOpen", "FileAppend", "FileSaveAsPDF", "SelectStd", "SelectObjects", 
                  "ZoomToRect", "SelectText", "SelectFillForm", "DrawFieldEdit", "DrawFieldCheck", 
                  "DrawAnnotFrame",  "DrawAnnotHighlight", "DrawAnnotFreetext", "DrawAnnotSymbol", "DrawAnnotSquiggly", 
                  "DrawAnnotHighlightText", "DrawAnnotBlackText", "DrawTextline", "DrawRect", "DrawImage", 
                  "DrawHighlight", "DrawCircle", "About" };

        private void InitToolbar( ToolStrip toolStrip, string[] Actions )
        {
            toolStrip.Height = 40;
            bool highdpi;

            // Enable the large buttons if >120dpi!
            Graphics g = Graphics.FromHwnd(new IntPtr(0));
            highdpi = (g.DpiX>120);

            // Create the toolbar
            for (int i = 0; i < Actions.Length; i++)
            {
                string pngname =
                      "PDFViewNET.Resources." + Actions[i] + ((highdpi) ?  "@2x.png" : ".png");
                
                System.Reflection.Assembly thisExe;

                // use this to check resource names in debugger!
                // string[] db = GetType().Assembly.GetManifestResourceNames();

                thisExe = System.Reflection.Assembly.GetExecutingAssembly();
                System.IO.Stream imagestream =  thisExe.GetManifestResourceStream(pngname);
                // If you get an exception here
                // a) check name of resource
                // b) check if resource Buildmoude was set to "Embedded"

                Image img = Image.FromStream(imagestream);                
                   
                // Create a new button
                ToolStripButton ActionBtn = new ToolStripButton("", img, null, "");
                ActionBtn.ImageScaling = ToolStripItemImageScaling.None;


                // and get the correct id
                ActionBtn.Tag = pdfViewer1.CommandStr( commands.COMPDF_ACTION_READ, "?" + Actions[i] );
                ActionBtn.Click += new System.EventHandler(doExecuteWPViewAction);
                
                toolStrip.Items.Add(ActionBtn);
            }
        }

To update the button state a generic method can be used. It simply enumerates all buttons, reads the action id which has been stored in “Tag” and ask the WPViewPDF engine about the current state of this action.

        // This method is used to update the Enabled state of the menu and toolitems
        private void UpdateGUI()
        {
            for (int i = 0; i < toolStrip1.Items.Count; i++)
            if ( toolStrip1.Items[i] is ToolStripButton )
            {
                ToolStripButton btn = toolStrip1.Items[i] as ToolStripButton;
                int ac = (int)btn.Tag; 
                if (ac > 0 )
                {
                    int state = pdfViewer1.Command(commands.COMPDF_ACTION_READSTATE, ac);
                      // 1=Checked, 2=Disabled
                      btn.Enabled = (state & 2)==0 ;
                      btn.CheckState = ((state & 1) == 1) ? CheckState.Checked : CheckState.Unchecked;
                }

            }
        }

This method is executed by an event of WPViewPDF – it can be used to update the GUI.

private void pdfViewer1_OnViewerMessage(object Sender, ref int ID, int param)
        {
            switch (ID)
            {
                case commands.MSGPDF_NEEDPASSWORD:
                    {
                        break;
                    }


                case commands.MSGPDF_CHANGESELPAGE: // Moved to different page (=wparam)
                    {
                        break;
                    }

                case commands.MSGPDF_CHANGEVIEWPAGE: // Moved to different page (=wparam)
                    // MSGPDF_CHANGEVIEWPAGE is also triggered if the action mode was changed. This makes MSGPDF_CHANGEVIEWPAGE
                    // to update GUI elements, such a buttons
                    {
                        UpdateGUI();
                        break;
                    }

                case commands.MSGPDF_CHANGEANNOT: // WPViewPDF 4 only: The annot have been moved, created or deleted.
                    {
                        break;
                    }

                case commands.MSGPDF_CHANGESELOBJECT: // A Draw object has been selected or deselected
                    {
                        break;
                    }
            }
        }

This is the most important function. It is executed by any click on the toolbar on the menu. You can copy&paste it to your application and use it with only few changes since it uses flags to determine, i.e if an open file or a save dialog has to be displayed. Also here, the action id is read from the “Tag” of the sender control.

private void doExecuteWPViewAction(object sender, EventArgs e)
        {
            int param, paramkind, res;
            string actionname, actionparam;
            int ac = 0;

            if (sender is System.Windows.Forms.ToolStripMenuItem)
                ac = (int)(sender as System.Windows.Forms.ToolStripMenuItem).Tag;
            else if (sender is System.Windows.Forms.ToolStripButton)
                ac = (int)(sender as System.Windows.Forms.ToolStripButton).Tag;             
            
            param     = pdfViewer1.Command(commands.COMPDF_ACTION_READ, "param", ac );
            paramkind = pdfViewer1.Command(commands.COMPDF_ACTION_READ, "paramkind", ac );
            actionname= pdfViewer1.CommandGetStr(commands.COMPDF_ACTION_READ, "name", ac );
            actionparam="";
            
            if (paramkind==50)
            {
                  string s = pdfViewer1.CommandGetStr(commands.COMPDF_ACTION_READ, "hint", ac )+"?";
                  if(MessageBox.Show(s,"",MessageBoxButtons.OKCancel)==DialogResult.Cancel) return;
            }

            // Bit 2 is set, we need a string parameter!
            if ((param & 2) == 2)
            {
                /*     // 0: Pagenr as Int or string
                       // 1: Fontname as string
                       // 2: Color as Int or string
                       // 3: PDF filename as string OPEN
                       // 4: PDF filename as string SAVE
                       // 5: text filename as string OPEN
                       // 6: text filename as string SAVE
                       // 7: image file name as string  OPEN
                       // 8: JPEG file name as string   SAVE
                       // 9: type @ options_comma_list
                       // 10: options_comma_list
                       // 11: options_for_DrawObjects
                       // 12: Zoom Value as Int
                       // 13: JPEG image file name as string to OPEN passed as "file=...",... + other params
                       // 14: some text as string  passed as "contents=...",... + other params
                       // 15: some multiline text as string  passed as "contents=...",... + other params
                       // 16: Boolean  on/off 1/0

                       // 50: Ask $hint$ yes/now
                 */

                if ( (paramkind == 3) || (paramkind == 5) || (paramkind == 6) || (paramkind == 13) )
                    {
                      if (paramkind==3)   openFileDialog1.Filter = "PDF Files (*.PDF)|*.PDF";
                      else if (paramkind==5)  openFileDialog1.Filter = "Text Files (*.TXT)|*.TXT,*.*";
                      else if ((paramkind==3) || (paramkind==13))   openFileDialog1.Filter = "Image Files (*.JPG)|*.JPG;*.JPEG";

                      if (openFileDialog1.ShowDialog()==DialogResult.Cancel) return;
                      else actionparam = openFileDialog1.FileName;

                      // This parameter is used for JPEG Draw Objects
                      if (paramkind==13) 
                         actionparam = "\"file=" + actionparam + "\""; // + Color params   color= background-color

                    }
                    else if ( (paramkind == 4) || (paramkind == 6) || (paramkind == 8)  )
                    {
                      if (paramkind == 4) saveFileDialog1.Filter = "PDF Files (*.PDF)|*.PDF";
                      else if (paramkind == 6)  saveFileDialog1.Filter = "Text Files (*.TXT)|*.TXT,*.*";
                      else if ((paramkind == 8) || (paramkind==13)) saveFileDialog1.Filter = "Image Files (*.JPG)|*.JPG;*.JPEG";
                      if (saveFileDialog1.ShowDialog() == DialogResult.Cancel) return;
                      else actionparam = saveFileDialog1.FileName;
                    }
                   else if ((paramkind == 14)||(paramkind == 0))   // A string
                    {
                        InputForm dlg = new InputForm();
                        dlg.label1.Text = pdfViewer1.CommandGetStr(commands.COMPDF_ACTION_READ, "hint", ac );
                        if (dlg.ShowDialog(this)==DialogResult.Cancel) return;

                        actionparam = (paramkind == 0) ? dlg.textBox1.Text :
                                        "\"contents=" + dlg.textBox1.Text + "\""; 
                        dlg.Dispose();
                    }
                    else if (paramkind == 15)   // A multiline string
                    {
                        InputForm dlg = new InputForm();
                        dlg.label1.Text = pdfViewer1.CommandGetStr(commands.COMPDF_ACTION_READ, "hint", ac);
                        dlg.textBox1.Multiline = true;
                        dlg.Height = dlg.Height * 2;
                        if (dlg.ShowDialog(this) == DialogResult.Cancel) return;
                        actionparam = "\"contents=" +  dlg.textBox1.Text + "\"";
                        dlg.Dispose();
                    }

            }

            pdfViewer1.CommandStrEx(commands.COMPDF_ACTIONNR, actionparam, ac);
         }