C++ 데스크톱(Win32) 앱의 XAML Islands에 대한 고급 시나리오

중요

이 토픽에서는 CommunityToolkit/Microsoft.Toolkit.Win32 GitHub 리포지토리의 형식을 사용하거나 다룹니다. XAML Islands 지원에 대한 중요한 정보는 해당 리포지토리의 XAML Islands 알림을 참조하세요.

표준 UWP 컨트롤 호스트사용자 지정 UWP 컨트롤 호스트 문서에서 C++ 데스크톱(Win32) 앱에서 XAML Islands를 호스트하기 위한 지침과 예제를 제공합니다. 그러나 이 문서의 코드 예제로 데스크톱 애플리케이션에서 원활한 사용자 환경을 제공하기 위해 처리해야 할 수 있는 많은 고급 시나리오를 처리할 수 있는 것은 아닙니다. 이 문서에서는 이러한 시나리오에 대한 지침과 관련 코드 샘플의 핵심 사항을 제공합니다.

키보드 입력

각 XAML Island에 대한 키보드 입력을 올바르게 처리하려면 특정 메시지가 올바르게 처리될 수 있도록 애플리케이션에서 모든 Windows 메시지를 UWP XAML 프레임워크로 전달해야 합니다. 이렇게 하려면 메시지 루프에 액세스할 수 있는 애플리케이션의 일부에서 각 XAML Island에 대한 DesktopWindowXamlSource 개체를 IDesktopWindowXamlSourceNative2 COM 인터페이스로 캐스트합니다. 그런 다음 이 인터페이스의 PreTranslateMessage 메서드를 호출하고 현재 메시지를 전달합니다.

키보드 포커스 탐색

사용자가 키보드를 사용하여 애플리케이션의 UI 요소를 탐색하는 경우(예를 들어 Tab 또는 방향/화살표 키를 누름) 프로그래밍 방식으로 DesktopWindowXamlSource 개체로 또는 개체 외부로 포커스를 이동해야 합니다. 사용자의 키보드 탐색이 DesktopWindowXamlSource에 도달 하면 UI의 탐색 순서에서 첫 번째 Windows.UI.Xaml.UIElement 개체에 포커스를 이동하고, 사용자가 요소를 순환할 때 다음 Windows.UI.Xaml.UIElement 개체로 포커스를 계속 이동한 후 DesktopWindowXamlSource 외부에서 부모 UI 요소로 다시 포커스를 이동합니다.

UWP XAML 호스팅 API는 이러한 작업을 수행하는 데 도움이 되는 몇 가지 형식 및 멤버를 제공합니다.

  • 키보드 탐색이 DesktopWindowXamlSource로 이동하는 경우, GotFocus 이벤트가 발생합니다. 이 이벤트를 처리하고 나면 NavigateFocus 메서드로 프로그래밍 방식으로 호스팅된 첫 번째 Windows.UI.Xaml.UIElement로 포커스를 이동합니다.

  • 사용자가 DesktopWindowXamlSource의 포커스 가능한 마지막 요소에 있는 경우 Tab 키 또는 화살표 키를 누르면 TakeFocusRequested 이벤트가 발생합니다. 이 이벤트를 처리하고 프로그래밍 방식으로 호스트 애플리케이션의 포커스 가능한 다음 요소로 포커스를 이동합니다. 예를 들어 DesktopWindowXamlSourceSystem.windows.interop.hwndhost>에서 호스트되는 WPF 애플리케이션에서 MoveFocus 메서드를 사용하여 호스트 애플리케이션에서 포커스 가능한 다음 요소로 포커스를 이동할 수 있습니다.

작업 중인 샘플 애플리케이션의 컨텍스트에서 이 작업을 수행하는 방법을 보여 주는 예제를 확인하려면 다음 코드 파일을 참조하세요.

레이아웃 변경 처리

사용자가 상위 UI 요소의 크기를 변경하는 경우 UWP 컨트롤이 원하는 대로 표시되도록 필요한 레이아웃 변경 내용을 처리해야 합니다. 고려해야 할 중요한 몇 가지 시나리오는 다음과 같습니다.

  • C++ 데스크톱 애플리케이션에서 애플리케이션이 WM_SIZE 메시지를 처리할 때 SetWindowPos 함수를 사용하여 호스트된 XAML Island의 위치를 변경할 수 있습니다. 예제에 대해서는 SampleApp.cpp 코드 파일을 참조하세요.

  • 상위 부분의 UI 요소가 DesktopWindowXamlSource에서 호스트하는 Windows.UI.Xaml.UIElement를 맞추는 데 필요한 사각형 영역의 크기를 가져와야 하는 경우 Windows.UI.Xaml.UIElementMeasure 메서드를 호출합니다. 예:

    • WPF 애플리케이션에서 DesktopWindowXamlSource를 호스트하는 HwndHostMeasureOverride 메서드에서 이 작업을 수행할 수 있습니다. 예제는 Windows 커뮤니티 도구 키트의 WindowsXamlHostBase.Layout.cs 파일을 참조하세요.

    • Windows Forms 애플리케이션에서 DesktopWindowXamlSource를 호스트하는 ControlGetPreferredSize 메서드에서 이 작업을 수행할 수 있습니다. 예제는 Windows 커뮤니티 도구 키트의 WindowsXamlHostBase.Layout.cs 파일을 참조하세요.

  • 상위 부분 UI 요소의 크기가 변경되면 DesktopWindowXamlSource에서 호스트하는 루트 Windows.UI.Xaml.UIElementArrange 메서드를 호출합니다. 예:

    • WPF 애플리케이션에서 DesktopWindowXamlSource를 호스트하는 HwndHost 개체의 ArrangeOverride 메서드에서 이 작업을 수행할 수 있습니다. 예제는 Windows 커뮤니티 도구 키트의 WindowsXamlHost.Layout.cs 파일을 참조하세요.

    • Windows Forms 애플리케이션에서 DesktopWindowXamlSource를 호스트하는 ControlSizeChanged 이벤트에 대한 처리기에서 이 작업을 수행할 수 있습니다. 예제는 Windows 커뮤니티 도구 키트의 WindowsXamlHost.Layout.cs 파일을 참조하세요.

DPI 변경 내용 처리

UWP XAML 프레임워크는 호스트된 UWP 컨트롤에 대한 DPI 변경을 자동으로 처리합니다(예: 사용자가 다른 화면 DPI를 사용하는 모니터 사이에서 창을 끌 때). 최상의 환경을 위해 Windows Forms, WPF 또는 C++ 데스크톱 애플리케이션이 모니터별 DPI를 인식하도록 구성하는 것이 좋습니다.

애플리케이션을 모니터별 DPI를 인식하도록 구성하려면 side-by-side 어셈블리 매니페스트를 프로젝트에 추가하고 <dpiAwareness> 요소를 PerMonitorV2로 설정합니다. 이 값에 대한 자세한 내용은 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2에 대한 설명을 참조하세요.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
        </windowsSettings>
    </application>
</assembly>