2013-10-08 96 views
2

我們在VB.NET 2010中基於WinForms UserControl實現了一個ActiveX控件。它通過COM Interop在VBA UserForms上使用。一切正常 - 除了一件事。當輸入焦點從ActiveX移動到用戶窗體上的另一個VBA本地控件(如說命令按鈕)時,我們無法檢測到此事。在這種情況下,不會觸發像Leave或Validating這樣的標準WinForms控件事件。需要通過COM Interop在MS Office VBA中託管的WinForms UserControl的LostFocus事件

如何跟蹤它(更好地使用「託管」方式,沒有WinAPI技巧)?

請注意,我們的UserControl包含其他WinForms控件,如按鈕或文本框,所以我們需要一個LostFocus事件作爲ActiveX公開的整個控件,無論選擇哪個組成部分。

回答

1

我不認爲你可以通過託管API修復這個問題。如果你確定P/invoke,SetWindowsHookEx/WH_CBT/HCBT_SETFOCUS將是要走的路。

您可能會遇到另一個怪癖。嘗試將文本光標(插入符號)放入托管控件中的任何可編輯字段,然後使用Alt-Tab切換到另一個應用程序。然後用Alt-Tab回到你的應用程序。光標是否仍然存在或已經消失?在後一種情況下,您在HCBT_ACTIVATE之後。

對於UserControl,ActiveX控件COM接口的.NET Framework實現需要來自ActiveX主機的一些協議調用。例如,當焦點移動到UserControlIOleInPlaceActiveObject::OnFrameWindowActivate method之外的另一個位置時,當主機的窗口窗口變爲非活動狀態時,由於用戶已切換到另一個應用程序,因此它期望IOleInPlaceObject::UIDeactivate被調用。你可以學習the Framework source code瞭解更多詳情。

不幸的是,並非所有的ActiveX容器都遵循這個協議;顯然,VBA沒有。最終的解決方案是實現一箇中間層(最好在C++/ATL中),它可以作爲VBA主機的ActiveX控件,也可以作爲託管.NET控件的ActiveX容器,修復所有這些之間的怪癖。這是可行的,但很乏味。

相關問題