Skip to content

Commit 8a10334

Browse files
committed
Merged main into live
2 parents 331d051 + ed02fa0 commit 8a10334

25 files changed

+405
-439
lines changed

hub/apps/winui/winui3/desktop-winui3-app-with-basic-interop.md

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
---
2-
description: Build a C# .NET and C++ desktop (Win32) application with WinUI 3 and basic Win32 interop capabilities using the Platform Invocation Services, or PInvoke.
32
title: Build a C# .NET app with WinUI 3 and Win32 interop
4-
ms.date: 07/09/2024
3+
description: Build a C# .NET application with WinUI 3 and basic Win32 interop capabilities using the Platform Invocation Services, or PInvoke.
4+
ms.date: 03/04/2025
55
ms.topic: article
6-
keywords: windows 10, windows 11, uwp, COM, win32, winui, interop
6+
keywords: windows 11, windows 10, uwp, COM, win32, winui, interop
77
ms.localizationpriority: high
88
ms.custom: 19H1
99
---
1010

1111
# Build a C# .NET app with WinUI 3 and Win32 interop
1212

13-
In this article, we step through how to build a basic **C# .NET** application with WinUI 3 and Win32 interop capabilities using Platform Invocation Services ([PInvoke](https://github.com/dotnet/pinvoke)).
13+
In this topic, we step through how to build a basic **C# .NET** application with WinUI 3 and Win32 interop capabilities using Platform Invocation Services ([PInvoke](https://github.com/dotnet/pinvoke)).
1414

1515
## Prerequisites
1616

1717
1. [Start developing Windows apps](../../get-started/start-here.md)
1818

1919
## Basic managed C#/.NET app
2020

21-
For this example, we'll specify the location and size of the app window, convert and scale it for the appropriate DPI, disable the window minimize and maximize buttons, and finally query the current process to show a list of modules loaded in the current process.
21+
For this example, we'll specify the location and size of the app window, convert and scale it for the appropriate DPI, disable the window minimize and maximize buttons, and finally query the current process to show a list of the modules that are loaded into the current process.
2222

2323
We're going to build our example app from the initial template application (see [Prerequisites](#prerequisites)). Also see [WinUI 3 templates in Visual Studio](winui-project-templates-in-visual-studio.md).
2424

@@ -48,39 +48,35 @@ The following code shows the MainWindow.xaml file from the initial template app,
4848

4949
### Configuration
5050

51-
1. To call Win32 APIs exposed in User32.dll, add the open source [**PInvoke.User32** NuGet package](https://github.com/dotnet/pinvoke) to the VS project (from the Visual Studio menus, select **Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution...** and search for "Pinvoke.User32"). For more details, see [Calling Native Functions from Managed Code](/cpp/dotnet/calling-native-functions-from-managed-code).
51+
1. To call Win32 APIs exported from `User32.dll`, you can use the [**C#/Win32 P/Invoke Source Generator**](https://github.com/microsoft/CsWin32) in your Visual Studio project. Click **Tools** > **NuGet Package Manager** > **Manage NuGet Packages for Solution...**, and (on the **Browse** tab) search for *Microsoft.Windows.CsWin32*. For more details, see [Calling Native Functions from Managed Code](/cpp/dotnet/calling-native-functions-from-managed-code).
5252

53-
:::image type="content" source="images/build-basic/nuget-pkg-manager-pinvoke.png" alt-text="Screenshot of the Visual Studio NuGet Package Manager with PInvoke.User32 selected.":::<br/>*NuGet Package Manager with PInvoke.User32 selected.*
53+
You can optionally confirm that installation was successful by confirming that *Microsoft.Windows.CsWin32* is listed under the **Dependencies** > **Packages** node in Solution Explorer.
5454

55-
Confirm installation was successful by checking the **Packages** folder in the VS project.
55+
You can also optionally double-click the application project file (or right click and select **Edit project file**) to open the file in a text editor, and confirm that the project file now includes a NuGet `PackageReference` for "Microsoft.Windows.CsWin32".
5656

57-
:::image type="content" source="images/build-basic/solution-explorer-packages-pinvoke.png" alt-text="Screenshot of the Visual Studio Solution Explorer Packages with PInvoke.User32.":::<br/>*Solution Explorer Packages with PInvoke.User32.*
58-
59-
Next, double-click the application project file (or right click and select "Edit project file") to open the file in a text editor and confirm the project file now includes the NuGet `PackageReference` for "PInvoke.User32".
60-
61-
:::code language="xml" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop.csproj" highlight="17":::
57+
:::code language="xml" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop.csproj" highlight="39":::
6258

6359
### Code
6460

65-
1. In the `App.xaml.cs` code-behind file, we get a handle to the [**Window**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window) using the **WindowNative.GetWindowHandle** WinRT COM interop method (see [Retrieve a window handle (HWND)](../../develop/ui-input/retrieve-hwnd.md)).
61+
1. In the `App.xaml.cs` code-behind file, we get a handle to the [**Window**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window) by using the **WindowNative.GetWindowHandle** WinRT COM interop method (see [Retrieve a window handle (HWND)](../../develop/ui-input/retrieve-hwnd.md)).
6662

67-
This method is called from the app's [**OnLaunched**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.application.onlaunched) handler, as shown here:
63+
That method is called from the app's [**OnLaunched**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.application.onlaunched) handler, as shown here:
6864

69-
:::code language="csharp" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/app.xaml.cs" id="OnLaunched":::
65+
:::code language="csharp" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/App.xaml.cs" id="OnLaunched":::
7066

71-
1. We then call a `SetWindowDetails` method, passing the Window handle and preferred dimensions. Remember to add the `using static PInvoke.User32;` directive.
67+
1. We then call a `SetWindowDetails` method, passing the Window handle and preferred dimensions.
7268

7369
In this method:
7470

75-
- We call [GetDpiForWindow](/windows/win32/api/winuser/nf-winuser-getdpiforwindow) to get the dots per inch (dpi) value for the window (Win32 uses actual pixels while WinUI 3 uses effective pixels). This dpi value is used to calculate the scale factor and apply it to the width and height specified for the window.
71+
- We call [GetDpiForWindow](/windows/win32/api/winuser/nf-winuser-getdpiforwindow) to get the dots per inch (dpi) value for the window (Win32 uses physical pixels, while WinUI 3 uses effective pixels). This dpi value is used to calculate the scale factor, and apply it to the width and height specified for the window.
7672
- We then call [SetWindowPos](/windows/win32/api/winuser/nf-winuser-setwindowpos) to specify the desired location of the window.
7773
- Finally, we call [SetWindowLong](/windows/win32/api/winuser/nf-winuser-setwindowlongw) to disable the *Minimize* and *Maximize* buttons.
7874

79-
:::code language="csharp" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/app.xaml.cs" id="SetWindowDetails" highlight="3,8,11":::
75+
:::code language="csharp" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/App.xaml.cs" id="SetWindowDetails" highlight="3,8,18":::
8076

8177
1. In the MainWindow.xaml file, we use a [ContentDialog](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.contentdialog) with a [ScrollViewer](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.scrollviewer) to display a list of all the modules loaded for the current process.
8278

83-
:::code language="xaml" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/MainWindow.xaml" range="10-19":::
79+
:::code language="xaml" source="samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop/MainWindow.xaml" range="12-21":::
8480

8581
1. We then replace the `MyButton_Click` event handler with the following code.
8682

@@ -104,4 +100,4 @@ For a more extensive sample, see the [AppWindow gallery sample](https://github.c
104100
- [Windows App SDK](../../windows-app-sdk/index.md)
105101
- [Stable release channel for the Windows App SDK](../../windows-app-sdk/stable-channel.md)
106102
- [Manage app windows](../../windows-app-sdk/windowing/windowing-overview.md)
107-
- [Windows App SDK Samples](https://github.com/microsoft/WindowsAppSDK-Samples)
103+
- [Windows App SDK Samples](https://github.com/microsoft/WindowsAppSDK-Samples)
Binary file not shown.
Binary file not shown.
Binary file not shown.

hub/apps/winui/winui3/samples/WinUI-3-basic-win32-interop/WinUI-3-basic-win32-interop (Package)/WinUI-3-basic-win32-interop (Package).wapproj

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,43 @@
1-
2-
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.31410.223
5-
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "WinUI-3-basic-win32-interop (Package)", "WinUI-3-basic-win32-interop (Package)\WinUI-3-basic-win32-interop (Package).wapproj", "{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}"
7-
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinUI-3-basic-win32-interop", "WinUI-3-basic-win32-interop\WinUI-3-basic-win32-interop.csproj", "{1C3F631F-2170-42F5-AF4B-D61C14DAF622}"
9-
EndProject
10-
Global
11-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12-
Debug|arm64 = Debug|arm64
13-
Debug|x64 = Debug|x64
14-
Debug|x86 = Debug|x86
15-
Release|arm64 = Release|arm64
16-
Release|x64 = Release|x64
17-
Release|x86 = Release|x86
18-
EndGlobalSection
19-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|arm64.ActiveCfg = Debug|arm64
21-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|arm64.Build.0 = Debug|arm64
22-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|arm64.Deploy.0 = Debug|arm64
23-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x64.ActiveCfg = Debug|x64
24-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x64.Build.0 = Debug|x64
25-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x64.Deploy.0 = Debug|x64
26-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x86.ActiveCfg = Debug|x86
27-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x86.Build.0 = Debug|x86
28-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Debug|x86.Deploy.0 = Debug|x86
29-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|arm64.ActiveCfg = Release|arm64
30-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|arm64.Build.0 = Release|arm64
31-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|arm64.Deploy.0 = Release|arm64
32-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x64.ActiveCfg = Release|x64
33-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x64.Build.0 = Release|x64
34-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x64.Deploy.0 = Release|x64
35-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x86.ActiveCfg = Release|x86
36-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x86.Build.0 = Release|x86
37-
{B03F26CF-F060-47AF-9A9C-F687D45DCBBB}.Release|x86.Deploy.0 = Release|x86
38-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|arm64.ActiveCfg = Debug|arm64
39-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|arm64.Build.0 = Debug|arm64
40-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|x64.ActiveCfg = Debug|x64
41-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|x64.Build.0 = Debug|x64
42-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|x86.ActiveCfg = Debug|x86
43-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Debug|x86.Build.0 = Debug|x86
44-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|arm64.ActiveCfg = Release|arm64
45-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|arm64.Build.0 = Release|arm64
46-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|x64.ActiveCfg = Release|x64
47-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|x64.Build.0 = Release|x64
48-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|x86.ActiveCfg = Release|x86
49-
{1C3F631F-2170-42F5-AF4B-D61C14DAF622}.Release|x86.Build.0 = Release|x86
50-
EndGlobalSection
51-
GlobalSection(SolutionProperties) = preSolution
52-
HideSolutionNode = FALSE
53-
EndGlobalSection
54-
GlobalSection(ExtensibilityGlobals) = postSolution
55-
SolutionGuid = {E772EBBD-B652-419B-A0D2-0D5B3054CC2B}
56-
EndGlobalSection
57-
EndGlobal
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.13.35825.156 d17.13
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinUI-3-basic-win32-interop", "WinUI-3-basic-win32-interop\WinUI-3-basic-win32-interop.csproj", "{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|ARM64 = Debug|ARM64
11+
Debug|x64 = Debug|x64
12+
Debug|x86 = Debug|x86
13+
Release|ARM64 = Release|ARM64
14+
Release|x64 = Release|x64
15+
Release|x86 = Release|x86
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|ARM64.ActiveCfg = Debug|ARM64
19+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|ARM64.Build.0 = Debug|ARM64
20+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|ARM64.Deploy.0 = Debug|ARM64
21+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x64.ActiveCfg = Debug|x64
22+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x64.Build.0 = Debug|x64
23+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x64.Deploy.0 = Debug|x64
24+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x86.ActiveCfg = Debug|x86
25+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x86.Build.0 = Debug|x86
26+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Debug|x86.Deploy.0 = Debug|x86
27+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|ARM64.ActiveCfg = Release|ARM64
28+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|ARM64.Build.0 = Release|ARM64
29+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|ARM64.Deploy.0 = Release|ARM64
30+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x64.ActiveCfg = Release|x64
31+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x64.Build.0 = Release|x64
32+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x64.Deploy.0 = Release|x64
33+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x86.ActiveCfg = Release|x86
34+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x86.Build.0 = Release|x86
35+
{2BB6E320-4EA4-4EC2-A6F0-B3BE01C6AFD2}.Release|x86.Deploy.0 = Release|x86
36+
EndGlobalSection
37+
GlobalSection(SolutionProperties) = preSolution
38+
HideSolutionNode = FALSE
39+
EndGlobalSection
40+
GlobalSection(ExtensibilityGlobals) = postSolution
41+
SolutionGuid = {05B17D38-7FA9-4DA8-9BB5-1B139678B51B}
42+
EndGlobalSection
43+
EndGlobal
Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
<Application
2-
x:Class="WinUI_3_basic_win32_interop.App"
3-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5-
xmlns:local="using:WinUI_3_basic_win32_interop">
6-
<Application.Resources>
7-
<ResourceDictionary>
8-
<ResourceDictionary.MergedDictionaries>
9-
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
10-
<!-- Other merged dictionaries here -->
11-
</ResourceDictionary.MergedDictionaries>
12-
<!-- Other app resources here -->
13-
</ResourceDictionary>
14-
</Application.Resources>
15-
</Application>
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Application
3+
x:Class="WinUI_3_basic_win32_interop.App"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:local="using:WinUI_3_basic_win32_interop">
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
11+
<!-- Other merged dictionaries here -->
12+
</ResourceDictionary.MergedDictionaries>
13+
<!-- Other app resources here -->
14+
</ResourceDictionary>
15+
</Application.Resources>
16+
</Application>

0 commit comments

Comments
 (0)