2010-06-19 53 views
3

AxAcroPDF一獲得焦點就會吞下所有與鍵相關的事件,包括快捷鍵,按鍵等。我添加了一個消息過濾器,並且它也沒有得到任何與鍵相關的消息。這是一個COM組件,這可能是相關的嗎?AxAcroPDF吞嚥按鍵,如何讓它停止?

在控制開始吞嚥它們之前,有什麼辦法可以抓住這些嗎?

回答

4

Hans是正確的,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(); 
    } 
    
+0

+1簡潔的回覆,雖然特定的可接受的黑客沒有爲我工作(離開事件+文本框,而不是ListBox的LostFocus事件) - 我嘗試了其他建議的解決方案,在答覆axAcroPDF +重點問題圍繞Web - 使用Timer並在調用AxAcroPDF.LoadFile後立即激活它,將焦點重新設置回Tick事件處理程序中的窗體,並在此後立即停用計時器 – 2012-03-26 09:50:50

2

這是一個進程外COM組件,這就是問題所在。完全違反SetParent()中規定的Windows SDK要求。一旦窗口獲得焦點,acroread.exe進程中的消息循環將獲取所有消息,消息篩選器不會再看到任何消息。

從技術上講,它可以通過使用SetWindowsHookEx()將DLL注入進程並使用WH_GETMESSAGE監視消息來解決。但是你不能用C#語言編寫這樣的DLL。

重大吸吮,我知道。這個程序似乎從來沒有缺少過。

+0

Adob​​e違反SDK要求?說它不是這樣! 該修復聽起來似乎比我目前能夠證明我的需求更加努力,但在未來發生變化的情況下很好知道。 – 2010-06-19 10:12:49

4

我可能終於有一個可笑的簡單的答案。到目前爲止在測試這是工作。

經歷了這個問題相當長的一段時間,並建立了一個複雜的系統,每個自定義控制記錄他們上次聚焦並使用定時器將焦點向後翻轉(當acropdf抓住它時),我重新訪問這個問題並閱讀很多答案(尋找最近的解決方案)。收集到的信息幫助我實現了這個想法。

的想法是禁用(acropdf)控制,同時它加載如在下面的例子中(代碼減少爲清楚起見)

AxAcroPDF_this。Enabled = False AxAcroPDF_this.src = m_src

然後在一個計時器上,比如說1秒後。

AxAcroPDF_this.Enabled =假

基本想法是告訴Windows不要讓用戶使用acropdf控制,直到允許的,所以要求Windows以防止它獲得焦點(因爲用戶不會在那裏允許) 。

到目前爲止,這是舉動,如果有任何變化,我會編輯這個。如果它不能完全爲你工作,那麼也許這個想法指向一個有用的方向。

+0

我爲此創建了一個擴展方法(僅適用於Windows窗體):https: //gist.github.com/bertvansteen/ec180b645fd6bcfd179e – bvs 2014-05-28 10:36:47

1

由於某些原因,Tim的答案,直接禁用AxAcroPDF控件,在我的情況下不起作用。先前選擇的文本框上的離開事件也不會觸發。

正在工作的是在禁用的GroupBox中嵌套AxAcroPDF控件。由於我的應用程序的用戶只需要看到PDF,而不與其進行交互,GroupBox的Enabled屬性在設計器中設置爲False。