2013-10-08 3 views
2

VB.NET 2010에서 WinForms UserControl을 기반으로하는 ActiveX 컨트롤을 구현했습니다. COM Interop을 통해 VBA UserForms에 사용됩니다. 모든 것은 괜찮습니다 - 단 한가지 만 빼고요. 입력 포커스가 ActiveX에서 사용자 정의 폼의 다른 VBA 네이티브 컨트롤 (예 : 명령 단추라고도 함)으로 이동하면이 항목을 감지 할 수 없습니다. 이러한 표준 WinForms 컨트롤 이벤트 (예 : Leave 또는 Validating)는이 경우 트리거되지 않습니다.COM Interop를 통해 MS Office VBA에서 호스팅되는 WinForms UserControl에 대한 LostFocus 이벤트 필요

어떻게 추적합니까 (WinAPI 트릭없이 "관리되는"방법을 사용하는 것이 더 좋음)?

우리 UserControl에는 버튼이나 텍스트 상자와 같은 다른 WinForms 컨트롤이 포함되어 있으므로 구성 요소 부분이 무엇이든 관계없이 ActiveX로 노출 된 전체 컨트롤에 대해 LostFocus 이벤트가 필요합니다.

답변

1

관리 API를 사용하여이 문제를 해결할 수 있다고 생각하지 않습니다. P/invoke가 괜찮 으면 SetWindowsHookEx/WH_CBT/HCBT_SETFOCUS이 될 것입니다.

아마도 당신이 겪을 수있는 다른 단점이 있습니다. 텍스트 커서 (캐럿)를 관리되는 컨트롤 내의 편집 가능한 필드에 넣은 다음 Alt-Tab을 사용하여 다른 앱으로 전환하십시오. 그런 다음 Alt-Tab을 사용하여 앱으로 돌아갑니다. 커서가 제자리에 있습니까? 아니면 사라 졌습니까? 후자의 경우에는 HCBT_ACTIVATE이됩니다.

ActiveX 컨트롤의 .NET Framework 구현 UserControl의 COM 인터페이스는 ActiveX 호스트의 일부 프로토콜 호출을 필요로합니다. 예를 들어 UserControl 외부의 다른 위치로 포커스가 이동할 때 IOleInPlaceObject::UIDeactivate이 호출되거나 사용자가 다른 앱으로 전환했기 때문에 호스트의 프레임 창이 호출 될 때 IOleInPlaceActiveObject::OnFrameWindowActivate method이 호출되지 않을 것으로 예상됩니다. 자세한 내용은 the Framework source code을 참조하십시오.

불행히도 모든 ActiveX 컨테이너가이 프로토콜을 엄격하게 준수하지는 않습니다. 분명히 VBA는 그렇지 않습니다. 궁극적 인 해결책은 VBA 호스트에 대한 ActiveX 컨트롤과 관리되는 .NET 컨트롤에 대한 ActiveX 컨테이너 역할을하는 중간 계층 (C++/ATL로)을 구현하는 것입니다. 할 수 있지만 아주 지루합니다.