2012-02-23 3 views
0

기존 MFC 응용 프로그램과 새 WPF usercontrol을 사용하여 WPF usercontrol의 단추 누르기를 기반으로 대화 상자 창을 닫으려고합니다. 본질적으로, 나는 MFC 반환의 DoModal() 기능을 얻을 수있는 방법에 대한 몇 가지 팁을 원합니다.MFC에서 호스팅하는 WPF usercontrol 단추 누르기에서 부모 창을 닫는 방법

여러 가지 이유로 대화 상자는 DoModal을 통해 시작되는 MFC CDialog이며, 하나의 WPF 구성 요소 만 호스팅하며 그 밖의 것은 없습니다. 이 구성 요소에는 다양한 작업을 수행 한 후 CDialog을 닫아야하는 버튼이 있습니다. 이 응용 프로그램은 기존의 사례입니다. 제어 흐름을 추적하는 것이 어렵고이 메시지를 보내는 실제 메시지 펌프가있는 곳입니다. 또한 으로 가득차있어서 모든 것을 두 배나 힘들게 만듭니다. I 생각해 보면 메시지 펌프를 식별 했으므로 WPF 컨트롤에서 그 메시지를 얻을 수 있다면 뭔가를 삽입 할 수 있다고 생각합니다.

usercontrol에서 호스트로 Windows 메시지를 보내거나 호스트의 HWND을 usercontrol에서 가져 오는 방법을 모르겠습니다. 나는 그것을 얻을 수있는 방법, 또는 더 좋은 의사 소통 방법이있을 것이라고 확신합니까?

WM_CLOSE 메시지를 부모에게 전송하는 올바른 방법은 HWND입니까? 아니면 WM_USER을 대화 펌프에 보내고 거기에서 실제 처리를 처리 할 수 ​​있습니까?

답변

4

시도해보십시오. 모든 WPF 요소 (Visual의 경우), HWND가 포함되어 있는지 확인하고 루트 부모를 찾을 때까지 HWND 트리를 추적 한 다음 WM_CLOSE 메시지를 보내야합니다.

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    private static extern IntPtr GetParent(IntPtr hWnd); 

    //I'd double check this constant, just in case 
    static uint WM_CLOSE = 0x10; 

    private void CloseContainingWindow(Visual visual) 
    { 
     // Find the containing HWND for the Visual in question 
     HwndSource wpfHandle = PresentationSource.FromVisual(this) as HwndSource; 
     if (wpfHandle == null) 
     { 
      throw new Exception("Could not find Window handle"); 
     } 

     // Trace up the window chain, to find the ultimate parent 
     IntPtr hWindow = wpfHandle.Handle; 
     while (true) 
     { 
      IntPtr parentHWindow = GetParent(hWindow); 
      if (parentHWindow == (IntPtr)0) break; 
      hWindow = parentHWindow; 
     } 

     // Now send the containing window a close message 
     SendMessage(hWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 
    } 
+0

좋아요. 확실하게 테스트 해 보겠습니다. 이 프로젝트 만이 미친 컴파일 시간을 특징으로하지 않았다면 ... – Dervall

+0

'WM_CLOSE'는 무엇을받을 것입니까? 기본 창 또는 대화 창입니까? 대화 상자가 아니라 주 창을 닫는 것처럼 보입니다.이 진흙 공이 저와 충돌합니다 :) – Dervall

+0

아마도 대화 상자 창을 닫을 것이고 주 창을 닫을 것입니다. 그래도 테스트를해야 할 것입니다. 불행히도 나는 이것을 C++/MFC 환경에서 조작하지 않았지만 위의 코드를 WPF를 호스팅하는 Windows Forms에서 테스트했으며 동작은 대화 상자 창을 닫는 것이 었습니다. –

0

WM_CLOSE가 작동해야하지만 시도해야합니다. 또 다른 방법은 WM_COMMAND 메시지를 부모 대화 상자에 게시하는 것입니다. WM_USER 보내기가 너무 복잡해 보입니다.

2

컨트롤에서 닫기 이벤트를 선언하십시오. 닫기 버튼이 닫히면 이벤트를 발생시킵니다.

CDialog 파생 클래스에서 이벤트를 구독 한 다음 이벤트 처리기에서 EngDialog를 호출하십시오.

+0

이것은 좋은 생각 일 수 있습니다. 그러나 WPF 이벤트와 MFC 처리기 사이의 interop 처리 방법에 대해서는 매우 분실했습니다. 특별한 치료가 필요한 다른 버튼을 시도해 볼 수 있는지 알아 보겠습니다. – Dervall

+0

좋아, 나도 잘 했어! 'CDialog'가 관리되는 클래스가 아니기 때문에이 작업을 수행하는 것은 까다로운 작업이었습니다. 나는 제대로 작동하기 위해 이벤트 처리를위한 래퍼 (wrapper)를 작성하는 일을 끝냈다 - http : // binarysculpting뿐 아니라 블로그 게시물을 보증 할만큼 충분히 멋지게 끝냈다.com/2012/02/24/how-to-handle-wpf-events-in-native-mfc-code / – Dervall