Por que meus Borland C ++ Builder 5 formulários com controles direito do ancorados aparecer incorretamente no Vista?
-
22-08-2019 - |
Pergunta
Depois de ter passado uma pequena idade procurando a solução e ter agora encontrado, eu descobri que seria bom documento para Stack Overflow. Assim, a minha resposta vai seguir logo após esta questão.
Eu estava usando Borland C ++ Builder 5. Isso provavelmente também se aplica à versão equivalente do Delphi. Eu tinha um formulário com um TButton em um TPanel. O botão foi definido para Akright, akBottom. No XP e antes do Windows, tudo estava bem. No Vista, usando Aero, o botão apareceu 4 pixels muito longe para a direita. A ancoragem continuou a funcionar bem.
Outro exemplo é uma forma com uma TComboBox que tinha akTop, Akright, akLeft. A combinação apareceu 4 pixels muito grande no Vista.
Voltando ao look "clássico" no Vista fez tudo aparecem corretamente.
Solução
A primeira coisa que eu tentei não funcionou: eu imaginei que o problema tinha a ver com as bordas das janelas mais amplas sobre Vista. Imaginei UpdateAnchorRules em VCL foi de alguma forma calcular incorretamente, devido à diferença entre a largura do desenho e amplitude real da janela no Vista. Olhando para a fonte VCL, ficou claro que a mudança das âncoras causaria UpdateAnchorRules de ser chamado novamente e (espero) calcular corretamente, uma vez que agora tinha a largura real do formulário disponível.
Eu adicionei
TAnchors t = BlahBtn->Anchors;
t >> akRight;
BlahBtn->Anchors = t;
t << akRight;
BlahBtn->Anchors = t;
para o construtor da minha forma.
No alegria. O comportamento era totalmente afetado.
Eu percebi isso pode ser muito cedo no processo, tão comovido o mesmo código para o método FormShow, igualmente sem sucesso. Como uma última tentativa, I mudou o design do formulário para já não têm Akright para o botão e mudou o código para
TAnchors t = BlahBtn->Anchors;
t << akRight;
BlahBtn->Anchors = t;
... que falhou também - comportamento totalmente afetado, diferente do que eu quebrou o posicionamento do botão no XP no caso em que o tamanho salvo da forma (que eu li para fora do registro e aplicam-se a forma em FormShow) não era o padrão.
Depois de ter adicionado uma tonelada métrica de código de depuração saída a largura do formulário, largura do botão, à esquerda do botão, ClientRect da forma, etc. em vários pontos durante a vida do formulário, eu encontrei o problema. Por alguma razão (presumivelmente ainda window-fronteira relacionados com o - I não conseguiu descobrir exatamente qual foi a razão), VCL estava abrindo a janela com a largura 4 pixels abaixo do que deveria ter sido. A largura foi corrigido logo em seguida, mas por esse ponto, a ancoragem (e UpdateAnchorRules) já tinha fixado o posicionamento do botão 4 pixels muito longe para a direita.
A correção foi:
void __fastcall TFooBarDlg::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
int i = GetSystemMetrics(SM_CXSIZEFRAME);
Params.Width=Params.Width+(2*(i-4));
}
Isto corrige a largura inicial do formulário, usando o tamanho diferentes da fronteira conforme relatado pelo Vista. Isso faz com que o comportamento correto no Vista, mantendo-lo em outras versões do Windows (e Vista com look "clássico").
Espero que isso ajude alguém.