Mensagem WM_DPICHANGED

Enviado quando os pontos por polegada (dpi) efetivos de uma janela são alterados. O DPI é o fator de escala de uma janela. Há vários eventos que podem fazer com que o DPI seja alterado. A lista a seguir indica as possíveis causas da alteração no DPI.

  • A janela é movida para um novo monitor que tem um DPI diferente.
  • O DPI do monitor que hospeda a janela é alterado.

O DPI atual de uma janela é sempre igual ao último DPI enviado por WM_DPICHANGED. Esse é o fator de escala para o qual a janela deve ser dimensionada para threads que estejam cientes das alterações de DPI.

#define WM_DPICHANGED       0x02E0

Parâmetros

wParam

A HIWORD do wParam contém o valor do eixo Y do novo dpi da janela. A LOWORD do wParam contém o valor do eixo X do novo DPI da janela. Por exemplo, 96, 120, 144 ou 192. Os valores do eixo X e do eixo Y são idênticos para aplicativos Windows.

lParam

Um ponteiro para uma estrutura RECT que fornece uma sugestão de tamanho e posição da janela atual dimensionada para o novo DPI. A expectativa é que os aplicativos reposicionem e redimensionem as janelas com base nas sugestões fornecidas por lParam ao lidar com essa mensagem.

Valor retornado

Se um aplicativo processar essa mensagem, ela deverá retornar zero.

Comentários

Essa mensagem é relevante apenas para aplicativos PROCESS_PER_MONITOR_DPI_AWARE ou threads DPI_AWARENESS_PER_MONITOR_AWARE. Ela poderá ser recebida em determinadas alterações de DPI se a janela ou o processo de nível superior estiver sendo executado como sem reconhecimento de DPI ou c reconhecimento de DPI, mas nessas situações ela pode ser ignorada com segurança. Para obter mais informações sobre os diferentes tipos de conscientização, confira PROCESS_DPI_AWARENESS e DPI_AWARENESS. As versões mais antigas do Windows exigiam que o reconhecimento de DPI fosse vinculado ao nível de um aplicativo. Esses aplicativos usam PROCESS_DPI_AWARENESS. Atualmente, o reconhecimento de DPI está vinculado a threads e janelas individuais, e não a todo o aplicativo. Esses aplicativos usam DPI_AWARENESS.

Você só precisa usar o valor do eixo X ou do eixo Y ao escalar o aplicativo, pois eles são os mesmos.

Para tratar essa mensagem corretamente, você precisará redimensionar e reposicionar a janela com base nas sugestões fornecidas por lParam e usando SetWindowPos. Se isso não for feito, suas janelas crescerão ou encolherão em relação a todo o resto no novo monitor. Por exemplo, se um usuário estiver usando vários monitores e arrastar sua janela de um monitor de 96 DPI para um monitor de 192 DPI, sua janela parecerá ter a metade do tamanho em relação a outros itens no monitor de 192 DPI.

O valor base do DPI é definido como USER_DEFAULT_SCREEN_DPI, que é definido como 96. Para determinar o fator de escala de um monitor, pegue o valor de DPI e divida por USER_DEFAULT_SCREEN_DPI. A tabela a seguir fornece alguns exemplos de valores de DPI e fatores de escala associados.

Valor de DPI Percentual de escala
96 100%
120 125%
144 150%
192 200%

O exemplo a seguir fornece um exemplo de manipulador de alteração de DPI.

    case WM_DPICHANGED:
    {
        g_dpi = HIWORD(wParam);
        UpdateDpiDependentFontsAndResources();

        RECT* const prcNewWindow = (RECT*)lParam;
        SetWindowPos(hWnd,
            NULL,
            prcNewWindow ->left,
            prcNewWindow ->top,
            prcNewWindow->right - prcNewWindow->left,
            prcNewWindow->bottom - prcNewWindow->top,
            SWP_NOZORDER | SWP_NOACTIVATE);
        break;
    }

O código a seguir escala linearmente um valor de 100% (96 DPI) para um DPI arbitrário definido por g_dpi.

    INT iBorderWidth100 = 5;
    iBorderWidth = MulDiv(iBorderWidth100, g_dpi, USER_DEFAULT_SCREEN_DPI);

Uma maneira alternativa de dimensionar um valor é converter o valor de DPI em um fator de escala e usá-lo.

    INT iBorderWidth100 = 5;
    FLOAT fscale = (float) g_dpi / USER_DEFAULT_SCREEN_DPI;
    iBorderWidth = iBorderWidth100 * fscale;

Requisitos

Requisito Valor
Cliente mínimo com suporte
Windows 8.1 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte
Windows Server 2012 R2 [somente aplicativos da área de trabalho]
Cabeçalho
WinUser.h

Confira também

DPI_AWARENESS

PROCESS_DPI_AWARENESS