Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu konu başlığında, Platform Çağırma Hizmetleri'ni (PInvoke) kullanarak WinUI ve Win32 birlikte çalışma özellikleriyle temel bir C# .NET uygulaması oluşturma adımlarını atacağız.
Prerequisites
Temel yönetilen C#/.NET uygulaması
Bu örnekte, uygulama penceresinin konumunu ve boyutunu belirleyecek, uygun DPI için dönüştürüp ölçeklendirecek, pencerenin simge durumuna küçültme ve ekranı kaplama düğmelerini devre dışı bırakacağız ve son olarak, geçerli işleme yüklenen modüllerin listesini göstermek amacıyla geçerli işlemi sorgulayacağız.
Örnek uygulamamızı ilk şablon uygulamasından oluşturacağız (bkz . Önkoşullar). Ayrıca bkz. WinUI şablonları Visual Studio.
MainWindow.xaml dosyası
WinUI ile XAML işaretlemesinde Window sınıfının örneklerini oluşturabilirsiniz.
XAML Penceresi sınıfı, masaüstü pencerelerini destekleyecek şekilde genişletilerek UWP ve masaüstü uygulaması modelleri tarafından kullanılan alt düzey pencere uygulamalarının her birinin özetine dönüştürülmüştür. Özellikle, UWP için CoreWindow ve Win32 için pencere tutamaçları (veya HWND'ler).
Aşağıdaki kod, uygulamanın kök öğesi olarak Window sınıfını kullanan ilk şablon uygulamasındaki MainWindow.xaml dosyasını gösterir.
<Window
x:Class="WinUI_3_basic_win32_interop.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI_3_basic_win32_interop"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
</StackPanel>
</Window>
Configuration
User32.dll'dan dışarı aktarılan Win32 API'lerini çağırmak için Visual Studio project C#/Win32 P/Invoke Source Generator kullanabilirsiniz. Tools>NuGet Package Manager> Çözüm için NuGet Paketlerini Yönet... öğesine tıklayın. ve (Browse sekmesinde) Microsoft.Windows.CsWin32 araması yapın. Diğer ayrıntılar için bkz. Yönetilen Koddan Yerel İşlevleri Çağırma.İsteğe bağlı olarak Microsoft.Windows.CsWin32Dependencies>Packages Solution Explorer düğümü altında listelendiğini onaylayarak yüklemenin başarılı olduğunu doğrulayabilirsiniz.
Ayrıca, isteğe bağlı olarak uygulama project dosyasına çift tıklayabilir (veya sağ tıklayıp project Dosyayı düzenle) dosyayı bir metin düzenleyicisinde açmak ve project dosyasının artık "Microsoft.Windows.CsWin32" için bir NuGet
PackageReferenceiçerdiğini onaylayabilirsiniz.<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <RootNamespace>WinUI_3_basic_win32_interop</RootNamespace> <ApplicationManifest>app.manifest</ApplicationManifest> <Platforms>x86;x64;ARM64</Platforms> <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers> <PublishProfile>win-$(Platform).pubxml</PublishProfile> <UseWinUI>true</UseWinUI> <EnableMsixTooling>true</EnableMsixTooling> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <Content Include="Assets\SplashScreen.scale-200.png" /> <Content Include="Assets\LockScreenLogo.scale-200.png" /> <Content Include="Assets\Square150x150Logo.scale-200.png" /> <Content Include="Assets\Square44x44Logo.scale-200.png" /> <Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" /> <Content Include="Assets\StoreLogo.png" /> <Content Include="Assets\Wide310x150Logo.scale-200.png" /> </ItemGroup> <ItemGroup> <Manifest Include="$(ApplicationManifest)" /> </ItemGroup> <!-- Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging Tools extension to be activated for this project even if the Windows App SDK Nuget package has not yet been restored. --> <ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'"> <ProjectCapability Include="Msix" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250205002" /> </ItemGroup> <!-- Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution Explorer "Package and Publish" context menu entry to be enabled for this project even if the Windows App SDK Nuget package has not yet been restored. --> <PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'"> <HasPackageAndPublishMenu>true</HasPackageAndPublishMenu> </PropertyGroup> <!-- Publish Properties --> <PropertyGroup> <PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun> <PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun> <PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed> <PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed> </PropertyGroup> </Project>Projenize bir metin dosyası ekleyin ve adını
NativeMethods.txtverin. Bu dosyanın içeriği C#/Win32 P/Invoke Kaynak Oluşturucu'ya P/Invoke kaynak kodunun oluşturulmasını istediğiniz işlevleri ve türleri bildirir. Başka bir deyişle, C# kodunuzda hangi işlevleri ve türleri çağırıp kullanacaksınız?GetDpiForWindow GetWindowLong SetWindowPos SetWindowLong HWND_TOP WINDOW_STYLE
Code
App.xaml.csArka plan kod dosyasında, WindowNative.GetWindowHandle WinRT COM birlikte çalışma yöntemini kullanarak Window'a bir tanıtıcı elde ederiz (bkz. Bir pencere tutamacını alma (HWND)).Bu yöntem, burada gösterildiği gibi uygulamanın OnLaunched işleyicisinden çağrılır :
/// <summary> /// Invoked when the application is launched. /// </summary> /// <param name="args">Details about the launch request and process.</param> protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { m_window = new MainWindow(); var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(m_window); SetWindowDetails(hwnd, 800, 600); m_window.Activate(); }Ardından Window tutamacını ve tercih edilen boyutları geçirerek bir
SetWindowDetailsyöntemi çağırırız.Bu yöntemde:
- Pencere için inç başına nokta (dpi) değerini almak için GetDpiForWindow'u çağırırız (Win32 fiziksel pikselleri, WinUI ise etkin pikselleri kullanır). Bu dpi değeri ölçek faktörünü hesaplamak ve pencere için belirtilen genişlik ve yüksekliğe uygulamak için kullanılır.
- Ardından, pencerenin istenen konumunu belirtmek için SetWindowPos'u çağırırız.
- Son olarak, SetWindowLong çağrısı yaparak Küçült ve Büyüt düğmelerini devre dışı bırakırız.
private static void SetWindowDetails(IntPtr hwnd, int width, int height) { var dpi = Windows.Win32.PInvoke.GetDpiForWindow((Windows.Win32.Foundation.HWND)hwnd); float scalingFactor = (float)dpi / 96; width = (int)(width * scalingFactor); height = (int)(height * scalingFactor); _ = Windows.Win32.PInvoke.SetWindowPos((Windows.Win32.Foundation.HWND)hwnd, Windows.Win32.Foundation.HWND.HWND_TOP, 0, 0, width, height, Windows.Win32.UI.WindowsAndMessaging.SET_WINDOW_POS_FLAGS.SWP_NOMOVE); var nIndex = Windows.Win32.PInvoke.GetWindowLong((Windows.Win32.Foundation.HWND)hwnd, Windows.Win32.UI.WindowsAndMessaging.WINDOW_LONG_PTR_INDEX.GWL_STYLE) & ~(int)Windows.Win32.UI.WindowsAndMessaging.WINDOW_STYLE.WS_MINIMIZEBOX & ~(int)Windows.Win32.UI.WindowsAndMessaging.WINDOW_STYLE.WS_MAXIMIZEBOX; _ = Windows.Win32.PInvoke.SetWindowLong((Windows.Win32.Foundation.HWND)hwnd, Windows.Win32.UI.WindowsAndMessaging.WINDOW_LONG_PTR_INDEX.GWL_STYLE, nIndex); }MainWindow.xaml dosyasında, geçerli işlem için yüklenen tüm modüllerin listesini görüntülemek için ScrollViewer içeren bir ContentDialog kullanırız.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button x:Name="myButton" Click="myButton_Click">Display loaded modules</Button> <ContentDialog x:Name="contentDialog" CloseButtonText="Close"> <ScrollViewer> <TextBlock x:Name="cdTextBlock" TextWrapping="Wrap" /> </ScrollViewer> </ContentDialog> </StackPanel>Ardından olay işleyicisini
MyButton_Clickaşağıdaki kodla değiştiririz.Burada GetCurrentProcess çağrısı yapılarak geçerli işleme bir referans elde edilir. Ardından Modüller koleksiyonu üzerinde yineleriz ve her bir ProcessModule dosya adını görüntü dizimize ekleriz.
private async void myButton_Click(object sender, RoutedEventArgs e) { myButton.Content = "Clicked"; var description = new System.Text.StringBuilder(); var process = System.Diagnostics.Process.GetCurrentProcess(); foreach (System.Diagnostics.ProcessModule module in process.Modules) { description.AppendLine(module.FileName); } cdTextBlock.Text = description.ToString(); await contentDialog.ShowAsync(); }Uygulamayı derleyin ve çalıştırın.
Pencere göründükten sonra "Yüklenen modülleri görüntüle" düğmesini seçin.
Bu konuda açıklanan temel Win32 birlikte çalışma uygulaması.
Summary
Bu konu başlığında, temel pencere uygulamasına (bu örnekte Win32 ve HWND'ler) erişmeyi ve WinRT API'leriyle birlikte Win32 API'lerini kullanmayı ele aldık. Bu, yeni WinUI masaüstü uygulamaları oluştururken mevcut masaüstü uygulama kodunu nasıl kullanabileceğinizi gösterir.
Daha kapsamlı bir örnek için Windows App SDK Samples GitHub deposundaki AppWindow galeri örneğine bakın.
Pencere başlık çubuğunu özelleştirmek için bir örnek
Bu ikinci örnekte, pencerenin başlık çubuğunu ve içeriğini özelleştirmeyi göstereceğiz. Onunla birlikte takip etmeden önce şu konuları gözden geçirin:
- Windows App SDK için araçları yükleyin.
- İlk WinUI project oluşturma.
Yeni project oluşturma
- Visual Studio'da, WinUI Boş Uygulaması (Paketlenmiş) proje şablonundan yeni bir C# veya C++/WinRT projesi oluşturun.
Configuration
Yine ilk örnekte yaptığımız gibi Microsoft.Windows.CsWin32 NuGet paketine başvurun.
Projenize bir
NativeMethods.txtmetin dosyası ekleyin.LoadImage SendMessage SetWindowText WM_SETICON
MainWindow.xaml
Note
Bu kılavuzla kullanmak için bir simge dosyası gerekiyorsa computer.ico örnek uygulamasından dosyası indirebilirsiniz. Bu dosyayı Assets klasörünüze yerleştirin ve dosyayı içerik olarak projeye ekleyin. Ardından url'sini Assets/computer.icokullanarak dosyaya başvurabileceksiniz.
Aksi takdirde, zaten sahip olduğunuz bir simge dosyasını kullanmaktan çekinmeyin ve aşağıdaki kod listelerinde bu dosyaya yapılan iki başvuruyu değiştirin.
- Aşağıdaki kod listesinde, iki düğme eklediğimiz ve her biri için
MainWindow.xamlişleyicileri belirttiğimizi göreceksiniz. İlk düğmenin tıklama işleyicisinde (basicButton_Click), başlık çubuğu simgesini ve metnini ayarlarız. İkincisinde (customButton_Click), başlık çubuğunu customTitleBarPanel adlı StackPanel içeriğiyle değiştirerek daha önemli özelleştirmeler gösteriyoruz.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="window_titlebar.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:window_titlebar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Basic WinUI 3 Window title bar sample">
<Grid x:Name="rootElement" RowDefinitions="100, *, 100, *">
<StackPanel x:Name="customTitleBarPanel" Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Top" Visibility="Collapsed">
<Image Source="Images/windowIcon.gif" />
<TextBlock VerticalAlignment="Center" Text="Full customization of title bar"/>
</StackPanel>
<StackPanel x:Name="buttonPanel" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="basicButton" Click="basicButton_Click" Margin="25">Set the Window title and icon</Button>
<Button x:Name="customButton" Click="customButton_Click" Margin="25">Customize the window title bar</Button>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs/cpp
-
basicButton_Click işleyicisinin aşağıdaki kod listesinde (özel başlık çubuğunu gizli tutmak için) customTitleBarPanelStackPanel'i daraltıyor ve ExtendsContentIntoTitleBar özelliğini olarak
falseayarlıyoruz. - Ardından, ana pencerenin pencere tutamacını (HWND) almak için IWindowNative::get_WindowHandle (C# için, birlikte çalışma yardımcı yöntemi GetWindowHandle kullanarak) çağırırız.
- Ardından, LoadImage ve SendMessage işlevlerini çağırarak uygulama simgesini (PInvoke.User32 NuGet paketini kullanarak C# için) ayarlayacağız.
- Son olarak, başlık çubuğu dizesini güncelleştirmek için SetWindowText'i çağırırız.
private void basicButton_Click(object sender, RoutedEventArgs e)
{
// Ensure the custom title bar content is not displayed.
customTitleBarPanel.Visibility = Visibility.Collapsed;
// Disable custom title bar content.
ExtendsContentIntoTitleBar = false;
//Get the Window's HWND
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
var hIcon = Windows.Win32.PInvoke.LoadImage(
null,
"Images/windowIcon.ico",
Windows.Win32.UI.WindowsAndMessaging.GDI_IMAGE_TYPE.IMAGE_ICON,
20, 20,
Windows.Win32.UI.WindowsAndMessaging.IMAGE_FLAGS.LR_LOADFROMFILE);
Windows.Win32.PInvoke.SendMessage(
(Windows.Win32.Foundation.HWND)hwnd,
Windows.Win32.PInvoke.WM_SETICON,
(Windows.Win32.Foundation.WPARAM)0,
(Windows.Win32.Foundation.LPARAM)hIcon.DangerousGetHandle());
Windows.Win32.PInvoke.SetWindowText((Windows.Win32.Foundation.HWND)hwnd, "Basic customization of title bar");
}
// pch.h
...
#include <microsoft.ui.xaml.window.h>
...
// MainWindow.xaml.h
...
void basicButton_Click(Windows::Foundation::IInspectable const& sender, Microsoft::UI::Xaml::RoutedEventArgs const& args);
...
// MainWindow.xaml.cpp
void MainWindow::basicButton_Click(IInspectable const&, RoutedEventArgs const&)
{
// Ensure the that custom title bar content is not displayed.
customTitleBarPanel().Visibility(Visibility::Collapsed);
// Disable custom title bar content.
ExtendsContentIntoTitleBar(false);
// Get the window's HWND
auto windowNative{ this->m_inner.as<::IWindowNative>() };
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
HICON icon{ reinterpret_cast<HICON>(::LoadImage(nullptr, L"Assets/computer.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE)) };
::SendMessage(hWnd, WM_SETICON, 0, (LPARAM)icon);
this->Title(L"Basic customization of title bar");
}
- customButton_Click işleyicisinde customTitleBarPanelStackPanel görünürlüğünü Visible olarak ayarladık.
- Ardından ExtendsContentIntoTitleBar özelliğini olarak
trueayarlayıp SetTitleBar'ı çağırarak customTitleBarPanelStackPanel'i özel başlık çubuğumuz olarak görüntüleriz.
private void customButton_Click(object sender, RoutedEventArgs e)
{
customTitleBarPanel.Visibility = Visibility.Visible;
// Enable custom title bar content.
ExtendsContentIntoTitleBar = true;
// Set the content of the custom title bar.
SetTitleBar(customTitleBarPanel);
}
// MainWindow.xaml.h
...
void customButton_Click(Windows::Foundation::IInspectable const& sender, Microsoft::UI::Xaml::RoutedEventArgs const& args);
...
// MainWindow.xaml.cpp
void MainWindow::customButton_Click(IInspectable const&, RoutedEventArgs const&)
{
customTitleBarPanel().Visibility(Visibility::Visible);
// Enable custom title bar content.
ExtendsContentIntoTitleBar(true);
// Set the content of the custom title bar.
SetTitleBar(customTitleBarPanel());
}
App.xaml
- Dosya
App.xaml'da, bu açıklamadan<!-- Other app resources here -->hemen sonra, aşağıda gösterildiği üzere başlık çubuğuna bazı özel renkli fırçalar ekledik.
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="window_titlebar.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:window_titlebar">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
<SolidColorBrush x:Key="WindowCaptionBackground">Green</SolidColorBrush>
<SolidColorBrush x:Key="WindowCaptionBackgroundDisabled">LightGreen</SolidColorBrush>
<SolidColorBrush x:Key="WindowCaptionForeground">Red</SolidColorBrush>
<SolidColorBrush x:Key="WindowCaptionForegroundDisabled">Pink</SolidColorBrush>
</ResourceDictionary>
</Application.Resources>
</Application>
Kendi uygulamanızda bu adımları takip ediyorsanız, şimdi project oluşturabilir ve uygulamayı çalıştırabilirsiniz. Aşağıdakine benzer bir uygulama penceresi görürsünüz (özel uygulama simgesiyle):
Şablon uygulaması.
Temel özel başlık çubuğu aşağıdadır:
Özel uygulama simgesine sahip şablon uygulaması.Tamamen özel başlık çubuğu aşağıdadır:
Özel başlık çubuğuna sahip şablon uygulaması.
Ayrıca bakınız
Windows developer