2011-08-09 2 views
6

EZShellExtensions.NET을 사용하여 C#에서 Windows 셸 확장을 쓰고 있습니다.부모를 닫을 때 자식 대화 상자 닫기

대화 상자를 표시하는 컨텍스트 메뉴에 제공됩니다.

탐색기 창 (A)을 표시한다고 가정합니다. 그런 다음 컨텍스트 메뉴를 사용하여 모달이 아닌 창 (B)을 표시합니다.

Windows XP 및 Windows Vista에서 A를 닫으면 B가 닫힙니다 (이 동작이 필요함). 그러나 Windows 7에서 A를 닫으면 B는 닫히지 않지만 이벤트에는 응답하지 않습니다. 내 질문 :

  • Windows 7에서 표시된 양식을 하위 양식으로 관리하는 이유를 알고 있습니까?
  • A를 닫으면 메시지 루프를 유지할 수 있습니까?

EDIT : 내가 A를 닫으면 A를 B의 소유자로 설정하면 B도 닫힙니다. 그러나 new issue이 생성됩니다. B는 항상 A 이상입니다.

답변

0

마지막으로 다음과 같이 구현했습니다. 대화 상자는 ShowDialog()을 사용하여 표시되지만 실행되며 스레드에서 생성됩니다. ShowDialog()은 자체 메시지 루프를 구현하므로 양식이 스레드에서 시작되고 기본 양식이 이벤트에 응답하며 기본 양식을 닫고 하위 양식이 이벤트에 계속 응답 할 수 있습니다. 이것은 ShellExtension 응용 프로그램에 매우 유용합니다.

스레드를 해제하고 쉘 확장 스레드 (각 셸 확장 창과 자식은 스레드에서 실행 됨)를 해제하려면 모두 폼에 저장해야합니다.

protected virtual void SetupViewControl() 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(DoSetupViewControl)); 

     while (!mViewControlCreated) 
     { 
      // wait for view control created 
      Thread.Sleep(100); 
     } 
    } 

    private bool mViewControlCreated = false; 

    protected virtual void DoSetupViewControl(object state) 
    { 
     mViewControl = ViewControlFactory.CreateViewControl(); 

     mViewControl.Dock = DockStyle.Fill; 
     mViewControl.Initialize(); 

     this.Controls.Clear(); 
     this.Controls.Add(mViewControl); 

     IntPtr wHnd = GetActiveWindow(); 
     IWin32Window owner = GetOwner(wHnd); 

     mViewControlCreated = true; 

     ShowDialog(owner); 

     this.Dispose(); 
    } 

    private IWin32Window GetOwner(IntPtr wHnd) 
    { 
     if (wHnd == IntPtr.Zero) return null; 

     return new WindowWrapper(wHnd); 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    private static extern IntPtr GetActiveWindow(); 

    private class WindowWrapper : IWin32Window 
    { 
     private IntPtr mHwnd; 

     public WindowWrapper(IntPtr handle) 
     { 
      mHwnd = handle; 
     } 

     public IntPtr Handle 
     { 
      get { return mHwnd; } 
     } 
    } 
:

다음 코드는 내 문제를 해결