'WPF에서 MFC로 메시지 보내기'에 해당되는 글 1건

  1. 2010.07.21 [ WPF ] RegisterWindowMessage 를 이용한 프로그램 간 메시지 보내기 178
Window/WPF2010. 7. 21. 21:22

서로 다른 응용 프로그램 사이에 메시지를 전달하는 방법에 대해 알아보겠습니다.

API 함수인 RegisterWindowMessage PostMessage 를 활용하면 되는데요.

 

RegisterWindowMessage 메시지를 등록하여 사용하기 때문에 서로 다른 프로그램에서 메시지를 약속하여야 합니다.

 

다음과 같은 원형을 가지고 있고 송수신 하는 프로그램에서 모두 실행하여야 합니다.

 uint RegisterWindowMessage (string lpString);

 

이 후에 PostMessage 함수를 사용하여 메시지를 보내주면 됩니다.

 bool PostMessage (IntPtr hWnd, uint Msg, uint wParam, uint lParam);

 

PostMessage 의 첫 번째 인자로 HWND_BROADCAST(0xffff) 값을 넣어주어야

다른 프로그램으로 메시지를 전송할 수 있습니다.

 

두 번째 인자로는 RegisterWindowMessage 함수를 실행한 반환 값을 넣어 주면 됩니다.

 

세 번째와 네 번째 인자를 사용하여 추가적으로 정보를 보낼 수 있습니다. (wParam : 2Byte, lParam : 4Byte)

이 방법은 4Byte 이상의 정보를 보낼 수 없다는 단점이 있습니다.

 

이 두 함수를 통해서 다른 프로그램으로 메시지를 보낼 수 있게 되었습니다.

 

그럼, 이제 메시지를 수신하는 방법을 알아보겠습니다.

윈도우 메시지를 수신해야 하는데요.

지난 번 포스팅 방법을 사용하겠습니다. ( http://shine10ee.blog.me/10089908443 )

 

다음과 같이 조건문을 거친 후 사용하시면 되겠습니다.

 void ComponentDispatcher_ThreadFilterMessage(ref MSG msg, ref bool handled)

{

    if (msg.message == 메시지 반환 값 && msg.wParam != 윈도우 핸들)

    {

       // To do ( msg.lParam 값으로 정보 확인 )

    }

}

 

이로써 WPF 에서 약속한 메시지를 수신할 수 있게 되었습니다.

 

간단한 예제로써 MFC 와 WPF 사이에 메시지를 송 수신하는 프로그램을 만들어 보았습니다.

MFC 프로그램의 코드에서도 위와 마찬가지 과정을 포함하고 있습니다.

 

소스는 다음과 같습니다.

 

[ WPF ]

 public partial class Window1 : Window

{

    private uint message;

    private IntPtr handle;

 

    public const uint HWND_BROADCAST = 0xffff;

 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]

    public static extern uint RegisterWindowMessage(string lpString);

 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]

    public static extern bool PostMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

 

    public Window1()

    {

        InitializeComponent();

    }

 

    protected override void OnSourceInitialized(EventArgs e)

    {

        base.OnSourceInitialized(e);

 

        handle = new WindowInteropHelper(this).Handle;

        message = RegisterWindowMessage("User Message");

        ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcher_ThreadFilterMessage);

    }

 

    void ComponentDispatcher_ThreadFilterMessage(ref MSG msg, ref bool handled)

    {

        if (msg.message == message && msg.wParam != handle)

        {

            MessageBox.Show("MFC Message : " + msg.lParam.ToString());

        }

    }

 

    private void Button_Click(object sender, RoutedEventArgs e)

    {

        PostMessage((IntPtr)HWND_BROADCAST, message, (uint)handle, 100);

    }

}


 

[ MFC ]

BOOL CRegisterWindowMessage_MFCDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

 

    // 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는

    //  프레임워크가 이 작업을 자동으로 수행합니다.

    SetIcon(m_hIcon, TRUE);            // 큰 아이콘을 설정합니다.

    SetIcon(m_hIcon, FALSE);        // 작은 아이콘을 설정합니다.

 

    // 메시지 등록

    message = RegisterWindowMessage(_T("User Message"));

 

    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.

}

 

void CRegisterWindowMessage_MFCDlg::OnBnClickedButton1()

{

    // 메시지 보내기

    ::PostMessage(HWND_BROADCAST, message, (WPARAM)this->GetSafeHwnd(), 200);

}

 

LRESULT CRegisterWindowMessage_MFCDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

{

    // 메시지 수신

    if(message == this->message && (HWND)wParam !=this->GetSafeHwnd())

    {

        char buf[256];

 

        sprintf_s(buf, "WPF Message : %d", lParam);

        MessageBox(buf);

    }

 

    return CDialog::WindowProc(message, wParam, lParam);

}

 

[ 실행 화면 ]

               [ WPF ]                                                       [ MFC ]

 

 

                                              [ MFC -> WPF ]

 

 

                                             [ WPF -> MFC ]

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] Custom Slider  (4) 2010.08.13
[ WPF ] ClickOnce로 배포하기  (9) 2010.08.03
[ WPF ] BackgroundWorker  (2) 2010.07.11
[ WPF ] 윈도우 이벤트  (4) 2010.07.11
[ WPF ] OpenCV로 캠 화면 띄우기  (3) 2010.06.20
Posted by 열ㅇl