Windows 앱 SDK는 HWND의 상위 수준 추상화를 나타내는 Microsoft.UI.Windowing.AppWindow 클래스를 제공합니다. 앱에서는 AppWindow와 최상위 HWND 간에 1:1 매핑됩니다. AppWindow 및 관련 클래스는 HWND에 직접 액세스할 필요 없이 앱 최상위 창의 여러 측면을 관리할 수 있는 API를 제공합니다.
Note
이 문서에서는 앱에서 API를 사용하는 AppWindow 방법을 보여 줍니다. 필수 조건으로 AppWindow의 정보를 읽고 이해하는 것이 좋습니다. 이 정보는 WinUI 또는 다른 UI 프레임워크를 사용하는지 여부에 관계없이 적용됩니다.
- 중요 API: AppWindow 클래스, OverlappedPresenter 클래스
WinUI 3 갤러리 앱에는 대부분의 WinUI 3 컨트롤, 특징, 기능의 대화형 예제가 포함되어 있습니다. Microsoft Store에서 앱을 다운로드하거나 GitHub에서 소스 코드를 가져오세요.
Windows 앱 SDK에서 지원하는 모든 UI 프레임워크(WinUI 3, WPF, WinForms 또는 Win32)에서 API를 사용할 AppWindow 수 있습니다. AppWindow API는 프레임워크별 창 API와 함께 작동합니다.
일반적으로 AppWindow API를 사용하여 다음을 수행합니다.
앱 창의 크기와 위치를 관리합니다.
창 제목, 아이콘 및 제목 표시줄 색을 관리합니다. 또는 AppWindowTitleBar API를 사용하여 완전히 사용자 지정 제목 표시줄을 만듭니다.
자세한 정보 및 예제는 제목 표시줄 사용자 지정 을 참조하세요.
AppWindowPresenter 파생 API를 사용하여 창의 모양과 동작을 관리합니다.
변경 사항에 대응 AppWindow
변경 사항에 응답하려면 단일 AppWindow 이벤트를 처리하고 이벤트 인수(AppWindowChangedEventArgs)를 확인하여 어떤 종류의 변경이 발생했는지 판단합니다. 관심 있는 변경이 발생한 경우 이에 응답할 수 있습니다. 잠재적인 변경 사항에는 위치, 크기, 발표자, 표시 유형 및 z 순서가 포함됩니다.
여기 AppWindow.Changed 이벤트 처리기의 예가 있습니다.
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
// ConfigText and SizeText are TextBox controls defined in XAML for the page.
if (args.DidPresenterChange == true)
{
ConfigText.Text = sender.Presenter.Kind.ToString();
}
if (args.DidSizeChange == true)
{
SizeText.Text = sender.Size.Width.ToString() + ", " + sender.Size.Height.ToString();
}
}
Window 크기 및 배치
클래스 AppWindow 에는 창의 크기와 배치를 관리하는 데 사용할 수 있는 몇 가지 속성과 메서드가 있습니다.
Category | Properties |
---|---|
읽기 전용 속성 | 위치, 크기, ClientSize |
Events | 변경됨 (DidPositionChange, DidSizeChange) |
크기 및 위치 메서드 | Move, Resize, ResizeClient, MoveAndResize |
Z 순서 메소드 | MoveInZOrderAtBottom, MoveInZOrderAtTop, MoveInZOrderBelow |
크기 조정을 호출하여 새 창 크기를 지정합니다.
이 예제에서는 코드가 MainWindow.xaml.cs
있으므로 .Window 속성을 사용하여AppWindow 인스턴스를 AppWindow 가져올 수 있습니다.
public MainWindow()
{
InitializeComponent();
AppWindow.Resize(new Windows.Graphics.SizeInt32(1200, 800));
}
Move 메서드를 호출하여 창의 위치를 변경합니다.
다음은 사용자가 단추를 클릭할 때 화면을 가운데로 이동하도록 창을 이동하는 예제입니다.
이는 Page 클래스의 코드 파일에서 발생하기 때문에 자동으로 Window 개체나 AppWindow 개체에 액세스할 수 없습니다. 당신은 AppWindow를 얻는 방법에는 몇 가지 옵션이 있습니다.
- Window나 현재 창 추적 또는 트랙 인스턴스 Window에 설명된 대로 참조를 유지하면, Window를 가져온 후 AppWindow 속성에서 Window를 가져올 수 있습니다.
- 또는 정적 AppWindow을 호출할 수 있습니다. GetFromWindowId 메서드는 여기에 표시된 대로 인스턴스를 AppWindow 가져옵니다. ( 시각적 요소를 호스팅하는 창 확인 참조)
private void MoveWindowButton_Click(object sender, RoutedEventArgs e)
{
AppWindow appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
RectInt32? area = DisplayArea.GetFromWindowId(appWindow.Id, DisplayAreaFallback.Nearest)?.WorkArea;
if (area == null) return;
appWindow.Move(new PointInt32((area.Value.Width - appWindow.Size.Width) / 2, (area.Value.Height - appWindow.Size.Height) / 2));
}
AppWindowPresenter 클래스 및 하위 클래스
각각 AppWindow 에는 AppWindowPresenter (발표자)가 적용됩니다. 시스템에서 발표자가 생성되어 AppWindow에 생성 시 적용됩니다. AppWindowPresenter의 각 하위 클래스는 창의 용도에 적합한 미리 정의된 구성을 제공합니다. 이러한 AppWindowPresenter 파생 발표자가 제공되며 지원되는 모든 OS 버전에서 사용할 수 있습니다.
-
항상 위에 고정된 창을 16:9 화면 비율의 고정된 크기로 설정하여 화면 속 화면과 같은 경험을 제공합니다. 기본적으로 InitialSize 는 CompactOverlaySize.Small이지만 변경할
Medium
Large
수 있습니다. 를 호출 AppWindow할 수도 있습니다. 크기를 조정 하여 16:9 가로 세로 비율을 재정의하고 창을 원하는 크기로 만듭니다. -
비디오를 시청하는 데 적합한 전체 화면 환경을 제공하도록 창을 구성합니다. 창에 테두리나 제목 표시줄이 없으며 시스템 작업 표시줄을 숨깁니다.
-
기본적으로 크기 조정 핸들이 있는 테두리와 최소화/최대화/복원 단추가 있는 제목 표시줄을 제공하는 표준 창 구성입니다.
Note
Win32 애플리케이션 모델의 새로운 개념인 발표자는 창 상태와 스타일의 조합과 유사하지만 동일하지는 않습니다. 일부 발표자에는 클래식 창 상태 및 스타일 속성(예: 자동 숨기기 제목 표시줄)에서 검사할 수 없는 동작이 정의되어 있습니다.
기본 발표자
기본 발표자는 AppWindow이 생성될 때 적용되는 기본 속성 설정이 있는 OverlappedPresenter의 인스턴스입니다. 다른 발표자를 적용한 후 창의 기본 발표자로 돌아가기 위해 참조를 유지할 필요가 없습니다. 시스템이 생성된 AppWindow의 수명 동안 이 프레젠터의 동일한 인스턴스를 유지하기 때문에, AppWindow.SetPresenter 메서드를 AppWindowPresenterKind.Default를 매개 변수로 사용하여 호출하면 다시 적용할 수 있습니다.
Important
호출 SetPresenter(AppWindowPresenterKind.Default)
은 AppWindow로 생성한 기본 프레젠터 인스턴스를 항상 다시 적용합니다. 다른 발표자를 만들고 적용하고 나중에 다시 적용하려면 발표자에 대한 참조를 유지해야 합니다.
기본 발표자 인스턴스에 대한 참조를 가져와서 수정할 수도 있습니다. 새 발표자를 적용한 경우 먼저 다음과 같이 기본 발표자가 적용되었는지 확인합니다.
appWindow.SetPresenter(AppWindowPresenterKind.Default);
OverlappedPresenter defaultPresenter = (OverlappedPresenter)appWindow.Presenter;
defaultPresenter.IsMaximizable = false;
defaultPresenter.IsMinimizable = false;
OverlappedPresenter를 수정하기
OverlappedPresenter는 다양한 방법으로 구성할 수 있는 유연한 발표자입니다.
Create
* 메서드를 사용하면 기본 속성 설정을 사용하여 겹치는 발표자를 만들거나 특정 용도로 속성 설정이 미리 구성된 발표자를 만들 수 있습니다.
이 표에서는 각 메서드에서 OverlappedPresenter 개체를 만들 때 구성 속성이 설정되는 방법을 보여줍니다.
Property | Create | CreateForContextMenu | CreateForDialog | CreateForToolWindow |
---|---|---|---|---|
HasBorder | true |
true |
true |
true |
HasTitleBar | true |
false |
true |
true |
IsAlwaysOnTop | false |
false |
false |
false |
최대화 가능 여부 | true |
false |
false |
true |
IsMinimizable | true |
false |
false |
true |
IsModal | false |
false |
false |
false |
IsResizable | true |
false |
false |
true |
응용 발표자는 라이브 오브젝트입니다. AppWindow.Presenter 개체의 속성 변경은 즉시 적용됩니다. 이러한 변경 내용을 알리는 이벤트는 없지만 언제든지 현재 값의 속성을 확인할 수 있습니다.
HasBorder 및 HasTitleBar 속성은 읽기 전용입니다.
SetBorderAndTitleBar 메서드(SetBorderAndTitleBar(bool hasBorder, bool hasTitleBar)
)를 호출하여 이러한 값을 설정할 수 있습니다.
OverlappedPresenter에는 테두리가 없는 제목 표시줄이 있을 수 없습니다. 즉, hasTitleBar
매개 변수가 true
라면, hasBorder
매개 변수도 true
이어야 합니다. 그렇지 않으면 이 메시지와 함께 예외가 발생합니다.
The parameter is incorrect.
Invalid combination: Border=false, TitleBar=true.
도구 모음에서 최대화 단추를 숨기도록 을 설정합니다. 이 작업을 수행하는 것이 좋습니다. PreferredMaximumHeight
나 PreferredMaximumWidth
속성을 설정하면 이러한 속성이 최대화된 상태에서도 창 크기를 제한하기 때문입니다. 이는 Maximize 메서드 호출에 영향을 주지 않습니다.
도구 모음에서 최소화 단추를 숨기도록 을 설정합니다. 이는 Minimize 메서드 호출에 영향을 주지 않습니다.
크기 조정 컨트롤을 숨기고 사용자가 창 크기를 조정하지 못하도록 하려면 을 설정합니다. 이는 AppWindow.Resize 메서드에 대한 호출에 영향을 주지 않습니다.
다른 창 위에 이 창을 유지하려면 을 설정합니다. 메서드를 AppWindow.MoveInZOrder*
호출하면 이 속성이 true
일 경우에도 창의 z 순서가 변경됩니다.
PreferredMaximumHeight 및 PreferredMaximumWidth를 설정하여 사용자가 창을 확장할 수 있는 최대 크기를 제한합니다. 이러한 속성은 최대화된 상태에서도 창 크기를 제한하므로 최대 크기 속성을 설정하는 경우 설정하는 IsMaximizable
false
것이 좋습니다. 이러한 속성은 에 대한 호출에도 영향을 미칩니다AppWindow. 크기 조정; 창의 크기는 지정된 최대 높이 및 너비보다 크지 않습니다.
PreferredMinimumHeight 및 PreferredMinimumWidth를 설정하여 사용자가 창을 축소할 수 있는 최소 크기를 설정합니다. 이러한 속성은 에 대한 호출에도 영향을 미칩니다AppWindow. 크기 조정; 창의 크기는 지정된 최소 높이 및 너비보다 작지 않습니다.
모달 창
IsModal을 true
로 설정하여 모달 창을 만들 수 있습니다. 모달 창은 닫을 때까지 소유자 창 과의 상호 작용을 차단하는 별도의 창입니다. 그러나 모달 창을 만들려면 소유자 창도 설정해야 합니다. 그렇지 않으면 다음 메시지와 함께 예외가 throw됩니다.
The parameter is incorrect.
The window should have an owner when IsModal=true.
WinUI 앱에서 소유자 창을 설정하려면 Win32 interop가 필요합니다. 자세한 내용 및 예제 코드는 AppWindow WinUI 갤러리 샘플 앱의 페이지를 참조하세요.
발표자 지정
발표자는 한 번에 하나의 창에만 적용할 수 있습니다. 동일한 발표자를 두 번째 창에 적용하려고 하면 예외가 발생합니다. 즉, 창이 여러 개 있고 각 창을 특정 프레젠테이션 모드로 전환하려면 동일한 종류의 여러 발표자를 만든 다음 각각을 자체 창에 적용해야 합니다.
새 발표자가 적용될 때(AppWindow. 발표자 속성이 변경되면) 앱에는 영향을 받는 AppWindow의 .Changed 이벤트와 함께 알림이 제공되며, 이때 AppWindow.AppWindowChangedEventArgs.DidPresenterChange 속성이 설정됩니다.
Tip
수정된 발표자를 적용하고 발표자 간에 변경을 허용하는 경우 수정된 발표자에 대한 참조를 유지하여 다시 적용 AppWindow할 수 있도록 해야 합니다.
이 예제에서는 다음을 수행하는 방법을 보여줍니다.
- AppWindow.Presenter 속성을 사용하여 현재의 발표자를 가져옵니다.
- AppWindowPresenter.Kind 속성을 사용하여 현재 적용된 구성 종류를 확인합니다.
SetPresenter 를 호출하여 현재 구성을 변경합니다.
여기서 발표자는 창의 생성자에 생성, 수정 및 적용됩니다.
OverlappedPresenter presenter = OverlappedPresenter.Create();
presenter.PreferredMinimumWidth = 420;
presenter.PreferredMinimumHeight = 550;
AppWindow.SetPresenter(presenter);
창의 콘텐츠인 페이지에서AppWindow에 대한 참조와 적용된 발표자를 가져올 수 있습니다.
AppWindow appWindow;
OverlappedPresenter modifiedPresenter;
private void AppWindowPage_Loaded(object sender, RoutedEventArgs e)
{
appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
modifiedPresenter = (OverlappedPresenter)appWindow.Presenter;
appWindow.Changed += AppWindow_Changed;
}
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
if (args.DidPresenterChange)
{
// ConfigText is a TextBox control defined in XAML for the page.
ConfigText.Text = appWindow.Presenter.Kind.ToString();
}
}
private void CompactOverlayButton_Click(object sender, RoutedEventArgs e)
{
if (appWindow.Presenter.Kind != AppWindowPresenterKind.CompactOverlay)
{
appWindow.SetPresenter(CompactOverlayPresenter.Create());
fullScreenButton.IsChecked = false;
}
else
{
appWindow.SetPresenter(modifiedPresenter);
}
}
private void FullScreenButton_Click(object sender, RoutedEventArgs e)
{
if (appWindow.Presenter.Kind != AppWindowPresenterKind.FullScreen)
{
appWindow.SetPresenter(FullScreenPresenter.Create());
compactOverlayButton.IsChecked = false;
}
else
{
appWindow.SetPresenter(modifiedPresenter);
}
}
UI 프레임워크 및 HWND 상호 운용성
AppWindow 클래스는 앱의 어떤 최상위 HWND에도 사용할 수 있습니다. 즉, 데스크톱 UI 프레임워크(WinUI 3 포함)로 작업할 때 해당 프레임워크의 진입점을 계속 사용하여 창을 만들고 콘텐츠를 연결할 수 있습니다. 해당 UI 프레임워크를 사용하여 창을 만든 후에는 Windows 앱 SDK에 제공된 창 interop 함수(아래 참조)를 사용하여 해당 AppWindow 및 해당 메서드, 속성 및 이벤트에 액세스할 수 있습니다.
UI 프레임워크를 사용하는 경우에도 사용 AppWindow 의 이점 중 일부는 다음과 같습니다.
- 쉬운 제목 표시줄 사용자 정의; 기본적으로 Windows 11 UI(둥근 모서리, 스냅 그룹 플라이아웃)를 유지합니다.
- 시스템에서 제공하는 전체 화면 및 소형 오버레이(화면 속 화면) 기능.
- 핵심 Win32 창 개념 중 일부에 대한 WinRT(Windows 런타임) API 화면입니다.
AppWindow 1.3 이전 버전의 Windows 앱 SDK(또는 다른 데스크톱 앱 프레임워크) 가져오기
.WindowAppWindow 속성은 Windows 앱 SDK 버전 1.3 이상에서 사용할 수 있습니다. 이전 버전의 경우 이 섹션에서 기능적으로 동등한 코드 예제를 사용할 수 있습니다.
C#. 창 interop 함수에 대한 .NET 래퍼는 Microsoft.UI.Win32Interop 클래스의 메서드로 구현됩니다. 또한 .NET 앱에서 interop API 호출 을 참조하세요.
C++. Interop 함수는 winrt/Microsoft.ui.interop.h 헤더 파일에 정의 되어 있습니다.
아래 코드 예제 섹션에는 실제 소스 코드가 표시됩니다. 하지만 기존 창이 지정된 경우 개체를 AppWindow 검색하는 방법은 다음과 같습니다.
- 아직 없는 경우 기존 창 개체(UI 프레임워크용)에 대한 HWND를 검색합니다.
- 해당 HWND를 GetWindowIdFromWindow interop 함수에 전달하여 WindowId를 검색합니다.
- 해당 WindowId를 정적 AppWindow.GetFromWindowId 메서드에 전달하여 AppWindow를 검색합니다.
// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
// Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
var hWnd =
WinRT.Interop.WindowNative.GetWindowHandle(this);
// Retrieve the WindowId that corresponds to hWnd.
Microsoft.UI.WindowId windowId =
Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
// Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
Microsoft.UI.Windowing.AppWindow appWindow =
Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
if (appWindow != null)
{
// You now have an AppWindow object, and you can call its methods to manipulate the window.
// As an example, let's change the title text of the window.
appWindow.Title = "Title text updated via AppWindow!";
}
}
// pch.h
#include "microsoft.ui.xaml.window.h" // For the IWindowNative interface.
#include <winrt/Microsoft.UI.Interop.h> // For the WindowId struct and the GetWindowIdFromWindow function.
#include <winrt/Microsoft.UI.Windowing.h> // For the AppWindow class.
// mainwindow.xaml.cpp
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
// Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
auto windowNative{ this->m_inner.as<::IWindowNative>() };
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
// Retrieve the WindowId that corresponds to hWnd.
Microsoft::UI::WindowId windowId =
Microsoft::UI::GetWindowIdFromWindow(hWnd);
// Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
Microsoft::UI::Windowing::AppWindow appWindow =
Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId);
if (appWindow)
{
// You now have an AppWindow object, and you can call its methods to manipulate the window.
// As an example, let's change the title text of the window.
appWindow.Title(L"Title text updated via AppWindow!");
}
}
작업하는 데 AppWindow 대한 추가 예제를 보시려면 Windowing 갤러리 샘플을 참조해 보세요.
Limitations
Windows 앱 SDK는 현재 UI 프레임워크 콘텐츠를 AppWindow에 연결하는 방법을 제공하지 않습니다.
관련 항목
Windows developer