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.
O Windows suporta temas claros e temas escuros como uma opção de personalização nas definições do Windows. O Windows usa o modo Claro por padrão, mas os usuários podem escolher o modo Escuro, que altera grande parte da interface do usuário para uma cor escura. Os usuários podem preferir essa configuração porque é mais fácil para os olhos em ambientes com pouca luz, ou podem simplesmente preferir uma interface mais escura em geral. Além disso, cores mais escuras da interface do usuário podem reduzir o uso da bateria em alguns tipos de monitores de computador, como telas OLED.
Estamos a trabalhar arduamente para alargar o suporte para o modo Escuro sem quebrar as aplicações existentes e, para esse efeito, estamos a fornecer orientação técnica para atualizar uma aplicação Win32 para ambiente de trabalho do Windows para suportar os modos Claro e Escuro.
Modo escuro vs. modo claro
O Modo de Cor nas configurações (que inclui os modos Claro e Escuro) é uma configuração que define a geral de
| Modo | Descrição | Exemplo |
|---|---|---|
| Luz | Um fundo claro com um primeiro plano escuro contrastante. No Modo de Luz, você geralmente verá texto preto ou escuro em fundos brancos ou claros. |
|
| Escuro | Um fundo escuro com um primeiro plano claro contrastante. No modo escuro, você geralmente verá texto branco ou claro em fundos pretos ou escuros. |
|
Observação
A razão pela qual usamos "preto ou escuro" e "branco ou claro" é porque existem cores adicionais, como a cor Accent, que podem tingir várias cores de primeiro plano e fundo. Assim, poderás, de fato, ver texto azul claro em um fundo azul escuro em algumas partes da interface, e isso ainda seria considerado aceitável no modo escuro da interface.
Devido à grande diversidade da interface do usuário em diferentes aplicativos, o modo de cores e as cores de primeiro plano e plano de fundo são mais uma diretriz direcional do que uma regra rígida:
- Os elementos de primeiro plano, os realces e o texto devem estar mais próximos da cor de primeiro plano do que da cor de plano de fundo.
- Áreas de fundo grandes e sólidas e fundos de texto geralmente devem estar mais próximos da cor do plano de fundo do que da cor de primeiro plano.
Na prática, isso significa que, no modo escuro, a maior parte da interface do usuário será escura e, no modo claro, a maior parte da interface do usuário será clara. O conceito de um plano de fundo no Windows é a grande área de cores em um aplicativo ou a cor da página. O conceito de primeiro plano no Windows é a cor do texto.
Sugestão
Se achar confuso que a cor de primeiro plano seja clara no modo escuro e escura no modo claro, pode ser útil pensar na cor de primeiro plano como "a cor de texto padrão".
Ativar o suporte para alternar modos de cor
Há muitas abordagens para implementar o suporte ao modo escuro em um aplicativo. Alguns aplicativos contêm dois conjuntos de interfaces do usuário (um com uma cor clara e outro com uma cor escura). Algumas estruturas da interface do usuário do Windows, como a WinUI 3, detetam automaticamente o tema de um sistema e ajustam a interface do usuário para seguir o tema do sistema. Para suportar totalmente o modo escuro, a totalidade da superfície de um aplicativo deve seguir o tema escuro.
Há duas coisas principais que você pode fazer em seu aplicativo Win32 para suportar temas de luz e escuridão.
Saiba quando o modo escuro está ativado
Saber quando o modo escuro está ativado nas configurações do sistema pode ajudá-lo a saber quando alternar a interface do usuário do aplicativo para uma interface do usuário com tema do modo escuro.
Ativar uma barra de título de modo escuro para aplicativos Win32
Nem todas as aplicações Win32 suportam o modo escuro, pelo que o Windows dá às aplicações Win32 uma barra de título clara por predefinição. Se estiver preparado para suportar o modo escuro, pode pedir ao Windows para exibir, em vez disso, a barra de título escura quando o modo escuro estiver ativado.
Observação
Este artigo fornece exemplos de maneiras de detetar alterações no tema do sistema e solicitar uma barra de título clara ou escura para a janela do aplicativo Win32. Não cobre detalhes sobre como repintar e renderizar a interface da aplicação usando um conjunto de cores do modo escuro.
Saiba quando o modo escuro está ativado
O primeiro passo é acompanhar a configuração do modo de cor em si. Isso permitirá que você ajuste o código de pintura e renderização do seu aplicativo para usar um conjunto de cores no modo escuro. Isso requer que o aplicativo leia a configuração de cor na inicialização e saiba quando a configuração de cor muda durante uma sessão de aplicativo.
Para fazer isso em um aplicativo Win32, use Windows::UI::Color e detete se uma cor pode ser classificada como clara ou escura. Para usar Windows::UI::Color, você precisa importar (em pch.h) o cabeçalho Windows.UI.ViewManagement do winrt.
#include <winrt/Windows.UI.ViewManagement.h>
Inclua também esse namespace no main.cpp.
using namespace Windows::UI::ViewManagement;
No main.cpp, use esta função para determinar se uma cor pode ser classificada como clara.
inline bool IsColorLight(Windows::UI::Color& clr)
{
return (((5 * clr.G) + (2 * clr.R) + clr.B) > (8 * 128));
}
Esta função executa um cálculo rápido do brilho percebido de uma cor, e leva em consideração maneiras que diferentes canais em um valor de cor RGB contribuem para o quão brilhante parece para o olho humano. Ele utiliza cálculos inteiros para otimizar a velocidade em CPUs típicas.
Observação
Este não é um modelo para análise real do brilho da cor. É bom para cálculos rápidos que exigem que determines se uma cor pode ser classificada como clara ou escura. As cores do tema podem muitas vezes ser claras, mas não brancas puras, ou escuras, mas não pretas puras.
Agora que você tem uma função para verificar se uma cor é clara, você pode usar essa função para detetar se o modo escuro está ativado.
O modo escuro é definido como um fundo escuro com um primeiro plano claro contrastante. Como IsColorLight verifica se uma cor é considerada clara, você pode usar essa função para ver se o primeiro plano é claro. Se o primeiro plano for claro, o modo escuro estará ativado.
Para fazer isso, você precisa obter o tipo de cor da interface do usuário do primeiro plano nas configurações do sistema. Use este código em main.cpp.
auto settings = UISettings();
auto foreground = settings.GetColorValue(UIColorType::Foreground);
UISettings obtém todas as configurações da interface do usuário, incluindo cores. Chame UISettings.GetColorValue(UIColorType::Foreground) para obter o valor da cor de primeiro plano das configurações da interface do usuário.
Agora você pode executar uma verificação para ver se o primeiro plano é considerado leve (em main.cpp).
bool isDarkMode = static_cast<bool>(IsColorLight(foreground));
wprintf(L"\nisDarkMode: %u\n", isDarkMode);
- Se o primeiro plano for claro, então
isDarkModeavaliará para 1 (true), o que significa que o modo escuro está ativado. - Se o primeiro plano estiver escuro,
isDarkModeserá avaliado como 0, o que significa que o modo escuro não está ativado.
Para controlar automaticamente quando a configuração Modo escuro muda durante uma sessão do aplicativo, você pode encapsular suas verificações desta forma.
auto revoker = settings.ColorValuesChanged([settings](auto&&...)
{
auto foregroundRevoker = settings.GetColorValue(UIColorType::Foreground);
bool isDarkModeRevoker = static_cast<bool>(IsColorLight(foregroundRevoker));
wprintf(L"isDarkModeRevoker: %d\n", isDarkModeRevoker);
});
Seu código completo deve ter esta aparência.
inline bool IsColorLight(Windows::UI::Color& clr)
{
return (((5 * clr.G) + (2 * clr.R) + clr.B) > (8 * 128));
}
int main()
{
init_apartment();
auto settings = UISettings();
auto foreground = settings.GetColorValue(UIColorType::Foreground);
bool isDarkMode = static_cast<bool>(IsColorLight(foreground));
wprintf(L"\nisDarkMode: %u\n", isDarkMode);
auto revoker = settings.ColorValuesChanged([settings](auto&&...)
{
auto foregroundRevoker = settings.GetColorValue(UIColorType::Foreground);
bool isDarkModeRevoker = static_cast<bool>(IsColorLight(foregroundRevoker));
wprintf(L"isDarkModeRevoker: %d\n", isDarkModeRevoker);
});
static bool s_go = true;
while (s_go)
{
Sleep(50);
}
}
Quando este código é executado:
Se o modo escuro estiver ativado, isDarkMode avaliará a 1.
Alterar a configuração do modo escuro para o modo claro fará com que isDarkModeRevoker seja avaliado como 0.
Ativar uma barra de título de modo escuro para aplicativos Win32
O Windows não sabe se uma aplicação pode suportar o modo escuro, por isso assume que não pode por razões de compatibilidade com versões anteriores. Algumas estruturas de desenvolvimento do Windows, como o Windows App SDK, suportam o modo escuro nativamente e alteram determinados elementos da interface do usuário sem qualquer código adicional. As aplicações Win32 muitas vezes não suportam o modo escuro, pelo que o Windows atribui às aplicações Win32 uma barra de título clara por predefinição.
No entanto, para qualquer aplicativo que use a barra de título padrão do Windows, você pode habilitar a versão escura da barra de título quando o sistema estiver no modo escuro. Para ativar a barra de título escura, chame uma função DWM (Desktop Windows Manager ) chamada DwmSetWindowAttribute na janela de nível superior, usando o atributo window DWMWA_USE_IMMERSIVE_DARK_MODE. (O DWM renderiza atributos para uma janela.)
Os exemplos a seguir pressupõem que você tenha uma janela com uma barra de título padrão, como a criada por esse código.
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
Primeiro, você precisa importar a API DWM, desta forma.
#include <dwmapi.h>
Em seguida, defina as macros acima da sua função DWMWA_USE_IMMERSIVE_DARK_MODE.
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
…
Finalmente, você pode usar a API DWM para definir a barra de título para usar uma cor escura. Aqui, você cria uma BOOL chamada value e a define como TRUE. Esse BOOL é usado para disparar essa configuração de atributo do Windows. Em seguida, você usa DwmSetWindowAttribute para alterar o atributo de janela para usar cores de modo escuro.
BOOL value = TRUE;
::DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
Aqui está mais explicação sobre o que esta chamada faz.
O bloco de sintaxe para DwmSetWindowAttribute tem esta aparência.
HRESULT DwmSetWindowAttribute(
HWND hwnd,
DWORD dwAttribute,
[in] LPCVOID pvAttribute,
DWORD cbAttribute
);
Depois de passar hWnd (a alça para a janela que você deseja alterar) como seu primeiro parâmetro, você precisa passar DWMWA_USE_IMMERSIVE_DARK_MODE como o parâmetro dwAttribute. Essa é uma constante na API DWM que permite que o quadro do Windows seja desenhado nas cores do modo escuro quando a configuração do sistema do modo escuro está ativada. Se você mudar para o modo Luz, você terá que mudar DWMWA_USE_IMMERSIVE_DARK_MODE de 20 para 0 para que a barra de título seja desenhada em cores do modo claro.
O parâmetro pvAttribute aponta para um valor do tipo BOOL (e é por isso que fizeste anteriormente o valor BOOL). Você precisa que pvAttribute esteja TRUE para adaptar o modo de tema escuro para a janela. Se pvAttribute estiver FALSE, a janela usará o Modo Claro.
Por fim, cbAttribute precisa ter o tamanho do atributo que está sendo definido em pvAttribute. Para fazer isso facilmente, passamos em sizeof(value).
Seu código para desenhar uma barra de título escura do Windows deve ter esta aparência.
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
BOOL value = TRUE;
::DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
Quando esse código é executado, a barra de título do aplicativo deve estar escura:
Ver também
Windows developer