Por que alguns programas se comportam mal em telas diferentes, mas outros não
Os aplicativos modernos do Windows devem incluir um manifesto , que é um documento XML que geralmente é incorporado no arquivo EXE principal. Manifestos declaram várias coisas importantes, incluindo se o programa pedirá para ser elevado ao UAC e, mais relevante, o nível de reconhecimento de DPI. Se um programa entender como se redesenhar para diferentes configurações de pontos por polegada, ele estará ciente do DPI.
Este artigo do Old New Thing menciona os três níveis de percepção de DPI disponíveis em Windows 8.1 e superior: sem reconhecimento (em cujo caso o sistema aumentará o programa, produzindo desfoque), reconhecimento de DPI do sistema e reconhecimento de DPI por monitor. A diferença entre os dois últimos é que os programas que reconhecem os DPIs por monitores precisam se redesenhar, dependendo de qual monitor eles estão, já que monitores diferentes podem ter DPIs diferentes. Os programas de reconhecimento de sistema escalonam-se para o monitor com DPI mais alto e, em seguida, o sistema os dimensiona conforme apropriado.
Eu inspecionei os manifestos dos programas que você mencionou pesquisando com um editor hexadecimal a string <dpiAware
. Estes são meus resultados:
- Internet Explorer 11:
True/PM
(por monitor ciente) - Microsoft Word 2016:
True
(ciente do sistema) - Adobe Reader XI:
True/PM
O Word, portanto, é parcialmente manipulado pelo sistema, o que explica por que ele funciona conforme o esperado. Os outros programas devem lidar com eles mesmos, mas evidentemente eles estragaram tudo. Os programas com reconhecimento por monitor de monitoração recebem informações sobre uma alteração de monitor pelo WM_DPICHANGED
mensagem de janela, mas aparentemente eles não fazem a coisa certa em resposta a isso.
Outras leituras: Escrevendo aplicativos com área de trabalho sensível ao DPI e aplicativos Win32
Como corrigir isso
É possível possível usar a infra-estrutura de compatibilidade para forçar a falta de nitidez (ou seja, tornar os programas sem a percepção de DPI), mas parece que você deseja tornar esses programas apenas parcialmente compatíveis com DPI (ou seja, usar o nível do sistema). A única maneira que eu posso pensar em fazer isso é bater o EXE com um editor hexadecimal e mudar o manifesto. Eu gosto XVI32 , nenhuma afiliação.
Execute o editor hexadecimal como administrador e abra o arquivo de programa que você deseja alterar. Pesquise <dpiAware
e, em seguida, leia um pouco até encontrar True/PM
(ou uma capitalização diferente da mesma). Provavelmente é seguido imediatamente pela tag de fechamento </dpiAware>
, então vamos escrever assim:
Old: True/PM</dpiAware>
New: True</dpiAware>
Assegure-se de sobrescrever o espaço extra ( re>
) com espaços. Você pode ter que mexer nas permissões do arquivo antes de salvar. Depois que o arquivo for alterado, ele será apenas um programa com reconhecimento de DPI do sistema.
Parece que a versão do Internet Explorer que acompanha o Windows 10 usa SetProcessDpiAwareness
em vez de um manifesto para definir o reconhecimento de DPI. Portanto, precisamos ficar um pouco mais sérios com a edição hexadecimal. Pesquise windowsSettings
e mova o cursor para imediatamente após o colchete de fechamento da tag application
anterior. Substituir com tudo isso:
<windowsSettings><dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware></windowsSettings></application><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><!--
Quando terminar, ele deverá ficar assim (destaquei a nova parte em vermelho e coloquei o cursor azul no início da parte alterada):
Isso aproveita os espaços extras e comentários no manifesto padrão para inserir nossa nova configuração e mover um pouco o elemento compatibility
. Quando dpiAwareness
é definido no manifesto, a função SetProcessDpiAwareness
não terá efeito.
Há uma chance de o Windows Resource Protection reverter as alterações, portanto, se o programa for revertido automaticamente, talvez seja necessário configurar um script para recopiar a nova versão.
Cuidado! É muito importante que você substitua, em vez de inserir ou excluir caracteres. Inserir ou excluir deslocará o restante dos dados executáveis, quebrando muitas coisas. Se você cometer um erro de transcrição, não pressione Backspace nem Delete. Em vez disso, mova o cursor para trás e sobrescreva seu erro com o (s) caractere (s) correto (s). Se você não usou um editor hexadecimal antes, você deve fazer um backup do arquivo EXE antes de modificá-lo.