본문 바로가기

망각/Windows Shell

IDeskBand 구현시 IInputObject 인터페이스 의문점

데스크밴드를 구현중에 사용자 입력을 받기 위해 IInputObject 인터페이스를 함께 구현하였고, 이와 관련하여 문제가 있어 며칠동안 테스트와 검색으로 삽질을 했다. MSDN포럼에도 글을 올려보았지만 스스로 내용정리도 안되었고 허접한 영어실력 때문인지 3일이 지난 지금까지 리플을 달리지 않고 있다. 

아무튼 블로그 개장 기념으로 글 하나는 올려야 될 것 같아. 좀 더(한글로-ㅅ-) 정리를 해보자 한다.

여기서 내가 말하는 데스크밴드는 태스크바(작업표시줄)에 표시되는 빠른실행과 알송리모컨같은 밴드를 말하고, IInputObject 인터페이스의 메서드는 다음과 같다.
HasFocusIO Determines if one of the object's windows has the keyboard focus.
TranslateAcceleratorIO Enables the object to process keyboard accelerators.
UIActivateIO UI-activates or deactivates the object.

데스크밴드에서 IInputObject 인터페이스를 구현하고 메서드들이 호출되는 내용은 이렇다.
  1. UIActivateIO는 포커스를 얻거나 잃을 때 각각 TRUE/FALSE 매개변수값으로 한번씩 호출된다.
  2. TranslateAcceleratorIO는 밴드가 현재 포커스를 가지고 있는 상태에서 Tab키가 눌렸을 경우에만 호출된다.
  3. HasFocusIO는 전혀 호출되지 않는다.
  4. IInputObjectSite::OnFocusChangeIS 호출은 E_NOINTERFACE를 리턴한다. UIActivateIO와 TranslateAcceleratorIO가 어쨋든 호출되는 것을 보니 IInputObject 객체 설정등의 기능은 하긴 하는 것 같다.

내가 하려던 것은 IShellView::TranslateAccelerator()를 호출해 엑셀레이터들을 사용하기 위함이었는데 이런저런 테스트로도 반응은 그대로였고, 구글링으로도 별다른 것을 건질 수 없었다. 며칠이 지난 건가?

레지스트리를 추가 등록 해 윈도우 탐색기와 인터넷 익스플로어의 툴바가 가능하게 했다. 탐색기와 브라우저에서 테스트한 결과와 또 다른 문제점이다.(타자의 귀차니즘으로 인해 영어에 대한 압박에도 불구하고 MSDN에 올린 글을 붙이겠다)


지금까지 개인적으로 내린 결론은(원래 이런 건지 내 실력의 한계인지는 확실치않다. 물론 개인적으로 후자라 생각한다)
  • 밴드에 포함된 자식 윈도우 일 경우(예> 에디트, 버튼):
    • 윈도우 탐색기와 인터넷 익스플로어는 키 입력시 TranslateAcceleratorIO를 호출
  • 밴드에서 자식 윈도우[각주:1]가 WS_POPUP으로 생성된 경우:
    • 탐색기는 키 입력시 TranslateAcceleratorIO를 호출
    • IE의 경우 플랫폼마다 차이를 보임:
      • XP 32bits, IE6에서 키 입력시 TranslateAcceleratorIO를 호출
      • XP 64bits, IE8에서 반응 없음
      • Vista 32bits, IE8에서 반응 없음
  • 두 경우 모두:
    • 데스크밴드는 IInputObject 객체가 탭키에만 반응(TranslateAcceleratorIO 호출)
    • IInputObjectSite::OnFocusChangeIS는 항상 E_NOINTERFACE를 리턴

이것들이고, 문제는 WS_POPUP으로 생성된 자식 윈도우[각주:2]였다. 데스크밴드는 팝업이든 아니든 아예 안된다고 쳐도, 탐색기는 되는데 IE는 안되는 이유는 뭘까? 내가 뭘 놓치고 있는걸까?
  1. 따지자면 WS_POPUP 플래그는 WS_CHILD와 같이 사용될수없다(MSDN참조). 하지만 CreateWindow() 호출시 부모 핸들을 지정할 수는 있다. [본문으로]
  2. 따지자면 WS_POPUP 플래그는 WS_CHILD와 같이 사용될수없다(MSDN참조). 하지만 CreateWindow() 호출시 부모 핸들을 지정할 수는 있다. [본문으로]