일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- subpixel
- Gradient
- compare
- stream
- Class
- sensor
- c++
- SERIAL
- atmega328
- Filtering
- Encapusulation
- Binary
- flutter
- Android
- file access
- parameter
- public
- APP
- Read
- Unity
- Gaussian
- Contour
- Pointer
- UNO
- memory
- wpf
- digitalRead
- aduino
- mfc
- edge
- Today
- Total
폴크(FOLC)
VS2022 MFC U/I - WPF U/I 붙이기 - 2 본문
MFC 프로젝트에 WPF UI(UserControl)를 삽입하고 이벤트를 처리하는 전체 예제를 아래와 같이 구성해드릴게요. 이 프로젝트는 다음과 같은 3개의 서브 프로젝트로 나뉩니다:
프로젝트 구성
- WpfControlLibrary
→ WPF UserControl을 정의 (예: 버튼 클릭 이벤트 포함) - WpfHostBridge (C++/CLI Class Library)
→ WPF를 호스트하고 MFC에서 사용할 수 있도록 핸들 노출 - MfcHostApp (MFC Application)
→ 실제 실행 앱. C++/CLI DLL을 통해 WPF UI 삽입 및 이벤트 처리
[WPF UserControl 프로젝트 - WpfControlLibrary]
1-1. UserControl 생성: MyWpfControl.xaml
xml 파일
<UserControl x:Class="WpfControlLibrary.MyWpfControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="300">
<Grid>
<Button Name="btnClick" Content="Click Me!" Width="100" Height="30" Click="btnClick_Click"/>
</Grid>
</UserControl>
1-2. Code-behind: MyWpfControl.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfControlLibrary
{
public partial class MyWpfControl : UserControl
{
public event EventHandler Clicked;
public MyWpfControl()
{
InitializeComponent();
}
private void btnClick_Click(object sender, RoutedEventArgs e)
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
}
[C++/CLI Wrapper 프로젝트 - WpfHostBridge]
2-1. 프로젝트 속성
- C++/CLI Class Library
- 참조 추가: WpfControlLibrary.dll
2-2. 헤더: WpfWrapper.h
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;
namespace WpfHostBridge {
public delegate void ButtonClickedHandler();
public ref class WpfHostControl : HwndHost
{
private:
HwndSource^ _source;
WpfControlLibrary::MyWpfControl^ _control;
public:
event ButtonClickedHandler^ OnButtonClicked;
WpfHostControl() {}
protected:
virtual IntPtr BuildWindowCore(HandleRef hwndParent) override
{
_control = gcnew WpfControlLibrary::MyWpfControl();
_control->Clicked += gcnew EventHandler(this, &WpfHostControl::HandleClick);
_source = gcnew HwndSource(0, 0, 0, 0, 0,
"WPFHost", hwndParent.Handle);
_source->RootVisual = _control;
return (IntPtr)_source->Handle;
}
virtual void DestroyWindowCore(HandleRef hwnd) override
{
_source->Dispose();
}
private:
void HandleClick(Object^ sender, EventArgs^ e)
{
OnButtonClicked?.Invoke();
}
};
}
[MFC 애플리케이션 - MfcHostApp]
3-1. 준비
- DLL 참조: WpfHostBridge.dll, WpfControlLibrary.dll
- 프로젝트 속성:
- /clr 설정
- Common Language Runtime 지원
3-2. 메시지 정의
#define WM_WPF_BUTTON_CLICKED (WM_USER + 100)
3-3. View 클래스에서 WPF 컨트롤 호스팅
// View 헤더 파일
gcroot<WpfHostBridge::WpfHostControl^> m_wpfControl;
HWND m_hWpf;
// 초기화 예제 (OnInitialUpdate 또는 OnCreate 등)
void CMyView::OnInitialUpdate()
{
CView::OnInitialUpdate();
m_wpfControl = gcnew WpfHostBridge::WpfHostControl();
m_wpfControl->OnButtonClicked += gcnew WpfHostBridge::ButtonClickedHandler(this, &CMyView::OnWpfButtonClicked);
m_wpfControl->CreateHandle();
m_hWpf = (HWND)m_wpfControl->Handle.ToPointer();
::SetParent(m_hWpf, this->m_hWnd);
::MoveWindow(m_hWpf, 10, 10, 300, 200, TRUE);
}
// 이벤트 핸들러 (버튼 클릭)
void CMyView::OnWpfButtonClicked()
{
AfxMessageBox(_T("WPF 버튼이 클릭되었습니다!"));
}
빌드 순서
- WpfControlLibrary (빌드 후 WpfControlLibrary.dll 생성)
- WpfHostBridge (위 DLL을 참조)
- MfcHostApp (C++/CLI DLL을 사용하여 WPF 포함)