AxAcroPDF глотает ключи, как заставить его остановиться? - PullRequest
3 голосов
/ 19 июня 2010

AxAcroPDF глотает все связанные с ключами события, как только он получает фокус, включая ярлыки, нажатия клавиш и т. Д. Я добавил фильтр сообщений, и он также не получает сообщений, связанных с ключами.Это COM-компонент, это может быть уместно?

Есть ли способ поймать их до того, как элемент управления начнет их проглатывать?

Ответы [ 4 ]

4 голосов
/ 05 октября 2011

Ганс правильный, Acrobat Reader порождает два дочерних процесса AcroRd32, к которым у вас нет прямого доступа из вашего управляемого кода.

Я экспериментировал с этим, и у вас есть три жизнеспособных варианта:

  1. Вы можете создать глобальную системную перехват , а затем искать и отфильтровывать / отвечать на сообщения WM_SETFOCUS, отправленные в ваши дочерние окна AcroRd32. Вы можете сделать это из C # с помощью библиотеки-оболочки, например, здесь: http://www.codeproject.com/KB/system/WilsonSystemGlobalHooks.aspx

    Вам также необходимо определить правильные процессы, так как может быть более одного экземпляра вашего приложения или других экземпляров AcroRd32. Это наиболее детерминированное решение, но поскольку ваше приложение теперь будет фильтровать сообщения, отправляемые в каждое существующее окно, я обычно не рекомендую такой подход, поскольку тогда ваша программа может отрицательно повлиять на стабильность системы.

  2. Найти альтернативный элемент управления просмотром PDF . Посмотрите этот ответ для нескольких коммерческих компонентов: .net PDF Viewer control , или сверните свой собственный: http://www.codeproject.com/KB/applications/PDFViewerControl.aspx

  3. Найдите приемлемый хак . В зависимости от того, насколько надежным должно быть ваше приложение, может подойти такой код, как приведенный ниже (он подходит для моего случая):

    DateTime _lastRenav = DateTime.MinValue;
    
    public Form1()
    {
        InitializeComponent();
    
        listBox1.LostFocus += new EventHandler(listBox1_LostFocus);
    }
    
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        axAcroPDF1.src = "sample.pdf";  //this will cause adobe to take away the focus
        _lastRenav = DateTime.Now;
    }
    
    void listBox1_LostFocus(object sender, EventArgs e)
    {
        //restores focus if it were the result of a listbox navigation
        if ((DateTime.Now - _lastRenav).TotalSeconds < 1)
            listBox1.Focus();
    }
    
4 голосов
/ 16 января 2014

Я мог бы наконец получить смехотворно простой ответ.До сих пор в тестировании это работало.

Пострадали от этой проблемы в течение достаточно долгого времени и построили сложную систему для каждой записи пользовательского элемента управления, какая из них имела последний фокус, и использовала таймер для переключения фокуса назад (когдаacropdf схватил его) Я снова рассмотрел эту проблему и прочитал множество ответов (в поисках последних решений).Полученная информация помогла мне с идеей.

Идея состоит в том, чтобы отключить элемент управления (acropdf) во время загрузки, как показано в следующем примере (код сокращен для ясности)

AxAcroPDF_this.Enabled = False AxAcroPDF_this.src = m_src

Затем по таймеру, скажем, через 1 секунду.

AxAcroPDF_this.Enabled = False

По сути, идея состоит в том, чтобы запретить пользователям использовать acropdf.контроль, пока не разрешено, поэтому просим Windows не допустить фокусировки (потому что пользователям там не разрешено).

Пока это задерживается, я отредактирую это, если что-то изменится.Если это не работает полностью для вас, то, возможно, идея указывает на полезное направление.

2 голосов
/ 19 июня 2010

Это COM-компонент вне процесса, вот в чем проблема.Полностью нарушает требования Windows SDK, изложенные в SetParent ().Как только его окно получает фокус, цикл сообщений в процессе acroread.exe получает все сообщения, ваш фильтр сообщений больше не видит никаких сообщений.

Технически это можно исправить с помощью SetWindowsHookEx () для вставки DLL вобрабатывать и контролировать сообщения с WH_GETMESSAGE.Но вы не можете написать такую ​​DLL на языке C #.

Major suck, я знаю.Кажется, в этой программе никогда не было недостатка.

1 голос
/ 05 августа 2014

По какой-то причине ответ Тима, напрямую отключив элемент управления AxAcroPDF, в моем случае не сработал.Событие Leave в ранее выбранном текстовом поле также никогда не сработает.

Что работает, так это размещение элемента управления AxAcroPDF внутри отключенного GroupBox.Поскольку пользователям моего приложения нужно только просматривать PDF-файл, а не взаимодействовать с ним, свойство Enabled GroupBox в конструкторе имеет значение False.

...