Skip to content

Commit ccc6b12

Browse files
Merge pull request #3753 from ptorr-msft/patch-6
Update apply-rounded-corners.md
2 parents a309932 + 2b17d82 commit ccc6b12

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

hub/apps/desktop/modernize/apply-rounded-corners.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ If your app's main window doesn't receive automatic rounding, it's because you'v
3232
- Empty non-client area
3333
- Other customizations, such as extra non-child windows used for custom shadows
3434

35-
Changing one of these things will break automatic rounding. Although we did try to round as many apps as possible with our system heuristics, there are some combinations of customizations that we can't predict so we provided a manual opt-in API for those cases. If you address these issues in your app or call the opt-in API, described in the following section, then it's possible for the system to round you. Note, however, that the API is a hint to the system and does not guarantee rounding, depending on the customizations.
35+
Changing one of these things will break automatic rounding. Although we did try to round as many apps as possible with our system heuristics, there are some combinations of customizations that we can't predict so we provided a manual opt-in API for those cases. If you address these issues in your app or call the opt-in API, described in the following section, then it's possible for the system to round your app's window. Note, however, that the API is a hint to the system and does not guarantee rounding, depending on the customizations.
3636
1. Apps that cannot ever be rounded, even if they call the opt-in API.
3737

3838
These apps have no frame or borders, and typically have heavily customized UI. If your app does one of the following, it cannot be rounded:
@@ -59,7 +59,7 @@ A pointer to the appropriate value from this enum is passed to the third paramet
5959

6060
### For C# apps
6161

62-
DwmSetWindowAttribute is a native C++ API. If your app is based on .NET and uses C#, you'll need to use [P/Invoke](/dotnet/standard/native-interop/pinvoke) to import dwmapi.dll and the DwmSetWindowAttribute function signature. All standard WinForms and WPF apps are rounded automatically like any other app, but if you customize your window frame or use a third party framework, you might need to opt-in to rounded corners if doing so results in losing the default rounding. See the Examples section for further details.
62+
DwmSetWindowAttribute is a native Win32 API and is not exposed directly to .NET code. You'll need to use your language's implementation of P/Invoke to declare the function (C# code is given in the example below). All standard WinForms and WPF apps are rounded automatically, but if you customize your window frame or use a third party framework, you might need to opt-in to rounded corners. See the Examples section for further details.
6363

6464
## Examples
6565

@@ -70,7 +70,7 @@ The following examples show how you can call [**DwmSetWindowAttribute**](/window
7070
7171
### Example 1 - Rounding an app's main window in C# - WPF
7272

73-
To call DwmSetWindowAttribute in a C# WPF desktop app, you'll need to import dwmapi.dll and the DwmSetWindowAttribute function signature with [P/Invoke](/dotnet/standard/native-interop/pinvoke). First you'll need to redefine the required enum values from the native dwmapi.h header, then declare the function using C# types equivalent to the original native function. Because the original takes a pointer for the third parameter, make sure to use the *ref* keyword so you can pass the address of a variable when you call the function. You can do this in your MainWindow class in MainWindow.xaml.cs.
73+
This example shows how to call DwmSetWindowAttribute from C# by using the **[DllImport]** attribute. Note that this definition is specific to rounded corners; the DwmSetWindowAttribute function is designed to take different parameters depending on the flags provided, so this is not a general-purpose signature. The example also includes copies of the relevant enums from the dwmapi.h header file. Because the Win32 API takes a pointer for the third parameter, make sure to use the *ref* keyword so you can pass the address of a variable when you call the function. You can do this in your MainWindow class in MainWindow.xaml.cs.
7474

7575
```CSharp
7676
using System.Runtime.InteropServices;
@@ -79,13 +79,15 @@ using System.Windows.Interop;
7979
public partial class MainWindow : Window
8080
{
8181
// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
82+
// Copied from dwmapi.h
8283
public enum DWMWINDOWATTRIBUTE
8384
{
8485
DWMWA_WINDOW_CORNER_PREFERENCE = 33
8586
}
8687

8788
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
8889
// what value of the enum to set.
90+
// Copied from dwmapi.h
8991
public enum DWM_WINDOW_CORNER_PREFERENCE
9092
{
9193
DWMWCP_DEFAULT = 0,
@@ -95,12 +97,11 @@ public partial class MainWindow : Window
9597
}
9698

9799
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
98-
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
99-
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
100+
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
101+
internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
100102
DWMWINDOWATTRIBUTE attribute,
101103
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
102104
uint cbAttribute);
103-
104105
// ...
105106
// Various other definitions
106107
// ...
@@ -127,7 +128,7 @@ public MainWindow()
127128

128129
### Example 2 - Rounding an app's main window in C# - WinForms
129130

130-
Like with WPF, for a WinForms app you'll first need to import dwmapi.dll and the DwmSetWindowAttribute function signature with [P/Invoke](/dotnet/standard/native-interop/pinvoke). You can do this in your primary Form class.
131+
Like with WPF, for a WinForms app you'll first need to import dwmapi.dll and the DwmSetWindowAttribute function signature with P/Invoke. You can do this in your primary Form class.
131132

132133
```Csharp
133134
using System;
@@ -136,24 +137,26 @@ using System.Runtime.InteropServices;
136137
public partial class Form1 : Form
137138
{
138139
// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
140+
// Copied from dwmapi.h
139141
public enum DWMWINDOWATTRIBUTE
140142
{
141143
DWMWA_WINDOW_CORNER_PREFERENCE = 33
142-
}
144+
}
143145

144146
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
145147
// what value of the enum to set.
148+
// Copied from dwmapi.h
146149
public enum DWM_WINDOW_CORNER_PREFERENCE
147150
{
148151
DWMWCP_DEFAULT = 0,
149152
DWMWCP_DONOTROUND = 1,
150153
DWMWCP_ROUND = 2,
151154
DWMWCP_ROUNDSMALL = 3
152-
}
155+
}
153156

154157
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
155-
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
156-
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
158+
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
159+
internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
157160
DWMWINDOWATTRIBUTE attribute,
158161
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
159162
uint cbAttribute);

0 commit comments

Comments
 (0)