Escala incorreta em PCs coreanos

9

A situação

Estamos vendendo um aplicativo Windows Forms para clientes em todo o mundo. Nós instalamos em vários países da Europa e América. Sem problemas. Na semana passada, instalamos nosso software na Coréia do Sul e reconhecemos um comportamento estranho ...

O problema ocorre apenas nos PCs do escritório do cliente, mas em todos eles. Alguns têm o Windows 7 Professional K, alguns têm o Windows XP.

O cliente comprou um novo PC com um Windows 7 Ultimate instalado. Neste PC, não há problema.

A função

Todos os elementos da nossa aplicação são derivados de um "pai-usuário-controle" que oferece funções especiais. Uma dessas funções é "autosizing e posicionamento". Quando o pai muda de tamanho, essa função de todos os filhos é chamada.

Quando nosso aplicativo é iniciado, nós armazenamos o "ClientSize":

InitializeComponent();
this.m_actSize = this.ClientSize;

Sempre que o tamanho do aplicativo é alterado, calculamos o fator de escala e criamos um evento com ele:

void myFormSizeChanged(object sender, EventArgs e)
{
    this.m_xFactor = (float)this.ClientSize.Width / (float)this.m_actSize.Width;
    this.m_yFactor = (float)this.ClientSize.Height / (float)this.m_actSize.Height;
    if (this.m_MyOnResize != null)
        this.m_MyOnResize(this.m_xFactor, this.m_yFactor);
}

Agora, cada criança inscrita, executa o redimensionamento e o posicionamento automáticos:

void MyParentUserControl_MyOnResize(float v_xFactor, float v_yFactor)

    {
        this.Location = new Point((int)(this.m_actLocation.X * v_xFactor), (int)(this.m_actLocation.Y * v_yFactor));
        this.Size = new Size((int)(this.m_actSize.Width * v_xFactor), (int)(this.m_actSize.Height * v_yFactor));
    }

O problema

Quando a nossa aplicação começa nos PCs dos clientes na Coreia do Sul, a largura é de cerca de 20% para os pequenos. Isso significa que, do lado direito, há uma área onde há apenas um fundo cinza. A altura é de cerca de 10% a alta. Isso significa que os itens localizados na parte inferior da nossa aplicação estão fora da tela.

Acorreção

Primeiro,pensamosqueoproblemavemdaconfiguraçãodeDPIdoWindows.Quandoeucoloqueimeulaptoppara125%,elepareciasemelhante.MasosPCsdosclientesestãoprontospara100%...

Depoispensamosnaresoluçãodatela.Todostêmdiferentes,algunsomesmoqueomeuLaptop...

Todostêmdiferentesadaptadoresgráficos...

Todostêmo.NET4.5.1...

Oúnicojeito,queresolveuoproblema,foiestranho:

this.AutoScaleDimensions=newSystem.Drawing.SizeF(6F,13F);this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;this.BackColor=System.Drawing.SystemColors.ScrollBar;this.ClientSize=newSystem.Drawing.Size(1016,734);

Noarquivo"Designer", altere manualmente o ClientSize de (1016, 734) para cerca de (900, 800). Isso fez com que parecesse bom na maioria dos PCs dos clientes. Mas não em todos.

A questão

Qual pode ser a solução real para esse problema? De onde pode vir?

    
por d.wing 14.11.2014 в 08:32
fonte

1 resposta

2

Você tem os mesmos problemas nos mesmos computadores se usar AutoScaleMode.Dpi ou AutoScaleMode.None em vez de AutoScaleMode.Font em cada controle de contenção?

Se isso resolver o seu problema, eis o motivo pelo qual seu problema pode estar relacionado ao uso de AutoScaleMode.Font

Em um nível alto, de acordo com o MSDN , o efeito de AutoScaleMode.Font é que o controle será "dimensionado em relação às dimensões da fonte que as classes estão usando, que normalmente é a fonte do sistema ." (Ênfase minha).

Eu procurei o System.Windows.Forms.ContainerControl código fonte um pouco. O método PerformAutoScale é chamado automaticamente durante o evento OnLayout de um controle. Se AutoScaleMode estiver definido como Font , GetFontAutoScaleDimensions será chamado indiretamente por OnLayout . Os comentários em GetFontAutoScaleDimensions explicam como AutoScaleMode.Font é implementado:

// We clone the Windows scaling function here as closely as
// possible.  They use textmetric for height, and textmetric
// for width of fixed width fonts.  For variable width fonts
// they use GetTextExtentPoint32 and pass in a long a-Z string.
// We must do the same here if our dialogs are to scale in a
// similar fashion.

Assim, o método pega uma string "longa", a envia para o GDI e pergunta "quais são as dimensões dessa string?" Notavelmente, esse método leva em consideração a fonte do controle "que normalmente é a fonte do sistema".

Você sabia que o alfabeto coreano (Hangul) não está representado no Arial ? (Eu não fiz até que eu pesquisei essa resposta!) Faz todo o sentido que a fonte do seu sistema (algo como Tahoe ou Arial) é diferente da dos seus clientes na Coreia do Sul. Também faz sentido que duas fontes diferentes exibam a mesma sequência de caracteres com altura e largura diferentes. Portanto, aposto que os problemas em questão ocorrem em estações de trabalho com uma fonte de sistema diferente da fonte do seu sistema.

Então, se você fizer algum teste e descobrir que AutoScaleMode.Font é realmente o culpado, então você tem algumas opções:

  1. Não use AutoScaleMode.Font .

  2. Defina explicitamente a fonte de todos os controles que contêm explicitamente. Isso garantirá que a fonte do ContainerControl não padroniza a fonte do sistema do computador.

Não importa o que você faça, certifique-se de que todos os seus contêineres usem a mesma configuração de AutoScaleMode . Misturar e combinar levará a dores de cabeça.

Boa sorte!

    
por Mike 16.11.2014 / 10:54
fonte