Display PDF Takes Focus and Eats Hot Key

2.3k Views Asked by At

Used code I found on SO to use the COM based Acrobat Reader to display PDF via hosting in a WindowsFormsHost.

It displays the PDF fine. Two problems:

  • When I load the PDF the control AxAcroPDFLib.AxAcroPDF takes focus

    I want focus to remain on the prior

  • When AxAcroPDFLib.AxAcroPDF has focus it eats the Hot Key (N)

    The ALT key does not even underline the N. Even if the user selects the AxAcroPDFLib.AxAcroPDF I would like the Hot Keys to work.

I understand this is COM and Adobe in WPF and there may not be an answer. If there is a free or cheap WPF control to view PDF I would be happy to go down that path. This is for a commercial application so it has to be free (or cheap) for commercial use.

 <Button  Click="Button_Click">_Next</Button>     

 <WindowsFormsHost Name="windowsFormsHost1"  Margin="1" />
 UserControl1 UC = new UserControl1(@"C:\temp\1000001.pdf");
 this.windowsFormsHost1.Child = UC;


 public UserControl1(string filename)
 {
     InitializeComponent();
     this.axAcroPDF1.LoadFile(filename);
 }

This does display PDF. In the production application I display various PDFs based on used actions.

5

There are 5 best solutions below

0
On BEST ANSWER

What Hans said. Acrobat appears to be eating key strokes and there is nothing I can do about it.

0
On

I freaked out finding this neat code which works great with the TimeSpan adjusted a bit!

bertvansteen/AxAcroPDFFocusExtensions.cs

https://gist.github.com/bertvansteen/ec180b645fd6bcfd179e/04647563701764d498f77022b6f2b77b04ca18cb

/// <summary>
/// Extensions for the Acrobat ActiveX control
/// /* Copyright (c) 2014 Bert Van Steen */
/// <example>
///    axAcroPDF1.SuspendStealFocus(TimeSpan.FromMilliseconds(300));
///    axAcroPDF1.LoadFile(scanFilename);
/// </example>
/// </summary>
static class AxAcroPDFFocusExtensions
{
   struct TimerTag
   {
      public TimerTag(AxAcroPDF control, object controlTag)
      {
         Control = control;
         ControlTag = controlTag;
      }

      public object ControlTag;
      public AxAcroPDF Control;
   }

   /// <summary>
   /// Prevent Adobe AxAcroPDF from stealing focus when you change the src. 
   /// The control will be disabled for 250 ms
   /// /// <param name="pdfControl">The acrobat ActiveX control</param>
   /// </summary>
   public static void SuspendStealFocus(this AxAcroPDF pdfControl)
   {
      SuspendStealFocus(pdfControl, 250);
   }

   /// <summary>
   /// Prevent Adobe AxAcroPDF from stealing focus when you change the src. 
   /// </summary>
   /// <param name="pdfControl">The acrobat ActiveX control</param>
   /// <param name="timeSpan">Time the ActiveX will be inaccessible (and 
       not grabbing focus)</param>
   public static void SuspendStealFocus(this AxAcroPDF pdfControl, TimeSpan 
   timeSpan)
   {
      SuspendStealFocus(pdfControl, (int)timeSpan.TotalMilliseconds);
   }

   /// <summary>
   /// Prevent Adobe AxAcroPDF from stealing focus when you change the src. 
   /// </summary>
   /// <param name="pdfControl">The acrobat ActiveX control</param>
   //// <param name="timeoutInMilliSeconds">Number of milliseconds the 
     ActiveX will be inaccessible (and not grabbing focus)</param>
   public static void SuspendStealFocus(this AxAcroPDF pdfControl, int 
    timeoutInMilliSeconds)
   {
      pdfControl.Enabled = false;
   
      Timer t = new Timer();
      t.Interval = timeoutInMilliSeconds;
      t.Tick += t_Tick;
      t.Start();

      pdfControl.Tag = Guid.NewGuid();
      t.Tag = new TimerTag(pdfControl, pdfControl.Tag);
   }
  
   static void t_Tick(object sender, EventArgs e)
   {
      var timer = (Timer)sender;
      timer.Stop();
      timer.Dispose();

      TimerTag t = (TimerTag) timer.Tag;
      if (ReferenceEquals(t.Control.Tag, t.ControlTag))
      {
         t.Control.Enabled = true;
      }
   }
}
0
On

This works for me:

Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    If Me.AxAcroPDF1.ContainsFocus = True Then
      Me.TextBox1.Focus()
    End If
End Sub

Basically '.ContainsFocus' becomes True once the PDF document is loaded. Monitor this value in a quick timer (~200ms), and reFocus to another control if needed. Not Ideal, but it works reliably.

0
On

my hacked solution for dealing with this is add a delay before enabling the panel. Obviously you want to add the minimum delay possible but too little and with the wrong file it will nick the focus again.

    System.Threading.Thread.Sleep(300)
    Panel1.Enabled = True
0
On

No idea if it fits the needs of anyone reading this: I just found a way around my version of this problem (got a textbox for inputs and want it to regain focus after loading a pdf with AxAcroPDFLib.AxAcroPDF).

My solution was this:

        private void returnFocus(object sender, EventArgs e)
    {
        textBox.Focus();
    }

        this.textBox.LostFocus += new System.EventHandler(this.returnFocus);

Works for me!