Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Os cantos arredondados são a característica mais evidente de Windows 11 Geometry. No Windows 11, o sistema arredonda automaticamente os cantos das janelas de nível superior para todos os aplicativos da caixa de entrada, incluindo todos os aplicativos UWP e a maioria dos outros aplicativos. No entanto, alguns aplicativos Win32 podem não ser arredondados. Este tópico descreve como arredondar os cantos da janela principal de uma aplicação Win32 caso o sistema não o faça automaticamente.
Observação
Por design, os aplicativos não são arredondados quando maximizados, ajustados, executados em uma máquina virtual (VM), executados em uma área de trabalho virtual do Windows (WVD) ou executados como uma janela WDAG (Windows Defender Application Guard).
Por que meu aplicativo não é arredondado?
Se a janela principal do seu aplicativo não receber arredondamento automático, é porque você personalizou seu quadro de uma forma que o impede. As aplicações dividem-se em três categorias principais do ponto de vista do Desktop Window Manager (DWM):
Aplicativos que são arredondados por padrão.
Isso inclui aplicativos que desejam um quadro completo fornecido pelo sistema e controles de legenda (botões min/max/close), como o Bloco de Notas. Ele também inclui aplicativos que fornecem informações suficientes para o sistema para que ele possa arredondar corretamente, como definir os estilos de janela WS_THICKFRAME e WS_CAPTION ou fornecer uma borda de área não cliente de 1 pixel que o sistema pode usar para arredondar os cantos.
Aplicativos que não são arredondados por política, mas podem ser arredondados.
Os aplicativos nessa categoria geralmente querem personalizar a maioria do quadro da janela, mas ainda querem a borda e a sombra desenhadas pelo sistema, como o Microsoft Office. Se a sua aplicação não estiver em conformidade com a política, isso pode ser causado por uma das seguintes razões:
- Falta de estilos de quadro
- Área não cliente vazia
- Outras personalizações, como janelas extras não filhas usadas para sombras personalizadas
Alterar uma destas coisas irá quebrar o arredondamento automático. Embora tenhamos tentado abordar o maior número possível de aplicações com as nossas heurísticas do sistema, há algumas combinações de personalizações que não conseguimos prever, por isso fornecemos uma API de opção manual para esses casos. Se resolveres esses problemas na tua aplicação ou chamares a API de adesão, descrita na secção seguinte, é possível que o sistema arredonde a janela da aplicação. No entanto, tenha em atenção que a API serve como uma indicação ao sistema e não garante o arredondamento, dependendo das customizações.
Aplicações que nunca podem ser arredondadas, mesmo que chamem a API de adesão.
Esses aplicativos não têm quadro ou bordas e, normalmente, têm uma interface do usuário altamente personalizada. Se o seu aplicativo fizer um dos seguintes procedimentos, ele não poderá ser arredondado:
- Camadas alfa por pixel
- Regiões de janela
Por exemplo, um aplicativo pode usar camadas alfa por pixel para desenhar pixels transparentes ao redor de sua janela principal para obter um efeito de sombra personalizado, o que faz com que a janela não seja mais um retângulo e, portanto, o sistema não possa arredondar isso.
Como optar por cantos arredondados
Se a sua aplicação não tiver cantos arredondados por padrão, pode, opcionalmente, usar estas APIs para permitir que a sua aplicação adote cantos arredondados. Você especifica a opção de arredondamento de canto que deseja para o seu aplicativo passando um valor da enumeração DWM_WINDOW_CORNER_PREFERENCE (mostrada na tabela a seguir) para a função DwmSetWindowAttribute.
| Valor do enum | Descrição |
|---|---|
| DWMWCP_DEFAULT | Deixe que o sistema decida se deve ou não arredondar os cantos das janelas. |
| DWMWCP_DONOTROUND | Nunca arredonde os cantos das janelas. |
| DWMWCP_ROUND | Arredondar os cantos, se for adequado. |
| DWMWCP_ROUNDSMALL | Arredonde os cantos, se apropriado, com um pequeno raio. |
Um ponteiro para o valor apropriado deste enum é passado para o terceiro parâmetro da função DwmSetWindowAttribute. Para o segundo parâmetro, que especifica qual atributo você está definindo, passe o valor DWMWA_WINDOW_CORNER_PREFERENCE definido na enumeração DWMWINDOWATTRIBUTE .
Para aplicativos C#
DwmSetWindowAttribute é uma API Win32 nativa e não é exposta diretamente ao código .NET. Você precisará usar a implementação de sua linguagem de P/Invoke para declarar a função (o código C# é dado no exemplo abaixo). Todos os aplicativos WinForms e WPF padrão são arredondados automaticamente, mas se você personalizar seu quadro de janela ou usar uma estrutura de terceiros, talvez seja necessário optar por cantos arredondados. Consulte a seção Exemplos para obter mais detalhes.
Exemplos
Os exemplos a seguir mostram como você pode chamar DwmSetWindowAttribute ou DwmGetWindowAttribute para controlar a experiência de arredondamento do seu aplicativo se ele não for arredondado por política.
Observação
O tratamento de erros foi deixado de fora destes exemplos por uma questão de brevidade e clareza.
Exemplo 1 - Arredondando a janela principal de um aplicativo em C# - WPF
Este exemplo mostra como chamar DwmSetWindowAttribute de C# usando o atributo [DllImport ]. Note que esta definição é específica para cantos arredondados; a função DwmSetWindowAttribute foi projetada para ter parâmetros diferentes, dependendo dos sinalizadores fornecidos, portanto, esta não é uma assinatura de uso geral. O exemplo também inclui cópias dos enums relevantes do arquivo de cabeçalho dwmapi.h. Como a API do Win32 usa um ponteiro para o terceiro parâmetro, certifique-se de usar a palavra-chave ref para que você possa passar o endereço de uma variável quando chamar a função. Você pode fazer isso em sua classe MainWindow no MainWindow.xaml.cs.
using System.Runtime.InteropServices;
using System.Windows.Interop;
public partial class MainWindow : Window
{
// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
// Copied from dwmapi.h
public enum DWMWINDOWATTRIBUTE
{
DWMWA_WINDOW_CORNER_PREFERENCE = 33
}
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
// Copied from dwmapi.h
public enum DWM_WINDOW_CORNER_PREFERENCE
{
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3
}
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
DWMWINDOWATTRIBUTE attribute,
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
uint cbAttribute);
// ...
// Various other definitions
// ...
}
Em seguida, no construtor MainWindow, após a chamada para InitializeComponent, crie uma nova instância da classe WindowInteropHelper para adquirir um ponteiro para o HWND subjacente (identificador de janela). Certifique-se de usar o EnsureHandle método para forçar o sistema a criar um HWND para a janela antes que ela seja mostrada, porque normalmente o sistema só faz isso depois de sair do construtor.
public MainWindow()
{
InitializeComponent();
IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
// ...
// Perform any other work necessary
// ...
}
Exemplo 2 - Arredondando a janela principal de um aplicativo em C# - WinForms
Como no WPF, para um aplicativo WinForms, você precisará primeiro importar dwmapi.dll e a assinatura da função DwmSetWindowAttribute com P/Invoke. Você pode fazer isso na sua Classe de formulário principal.
using System;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
// Copied from dwmapi.h
public enum DWMWINDOWATTRIBUTE
{
DWMWA_WINDOW_CORNER_PREFERENCE = 33
}
// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
// Copied from dwmapi.h
public enum DWM_WINDOW_CORNER_PREFERENCE
{
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3
}
// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
DWMWINDOWATTRIBUTE attribute,
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
uint cbAttribute);
// ...
// Various other definitions
// ...
}
Chamar DwmSetWindowAttribute também é o mesmo que com um aplicativo WPF, mas você não precisa usar uma classe auxiliar para obter o HWND porque é simplesmente uma propriedade do Form. Chame este método de dentro do seu construtor do formulário, após a chamada para InitializeComponent.
public Form1()
{
InitializeComponent();
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(this.Handle, attribute, ref preference, sizeof(uint));
// ...
// Perform any other work necessary
// ...
}
Exemplo 3 - Arredondando a janela principal de um aplicativo em C++
Para um aplicativo C++ nativo, você pode chamar DwmSetWindowAttribute em sua função de processamento de mensagens após a criação da janela para pedir ao sistema para arredondar você.
LRESULT ExampleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// ...
// Handle various window messages...
// ...
case WM_CREATE:
// ...
// Perform app resource initialization after window creation
// ...
if(hWnd)
{
DWM_WINDOW_CORNER_PREFERENCE preference = DWMWCP_ROUND;
DwmSetWindowAttribute(hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference));
}
break;
// ...
// Handle various other window messages...
// ...
}
return 0;
}
Exemplo 4 – Arredondar os cantos de um menu com um pequeno raio - C++
Por padrão, os menus são janelas pop-up, que não são arredondadas. Se seu aplicativo criar um menu personalizado e você quiser que ele siga a política de arredondamento de outros menus padrão, você poderá chamar a API para informar ao sistema que essa janela deve ser arredondada, mesmo que ela não pareça corresponder à política de arredondamento padrão.
HWND CreateCustomMenu()
{
// Call an app-specific helper to make the window, using traditional APIs.
HWND hWnd = CreateMenuWindowHelper();
if (hWnd)
{
// Make sure we round the window, using the small radius
// because menus are auxiliary UI.
DWM_WINDOW_CORNER_PREFERENCE preference = DWMWCP_ROUNDSMALL;
DwmSetWindowAttribute(hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference));
}
return hWnd;
}
Windows developer