MDI - Centralizar MDI Filho

Delphi

19/11/2004

Pessoal, minha dúvida apesar de ser simples aparentemente, vem me causando um certo incômodo.

Quando crio um projeto MDI, e consequentemente os forms MDI filhos, em geral coloco a propriedade Position = poMainFormCenter. Porém, ao abrir o form filho nunca ele aparece posicionado exatamente no centro do form principal. Sempre aparece posicionado um pouco para baixo do centro. Já tentei colocar a propriedade Position em todas as outras opções de ´center´, mas sempre o form abre decentralizado.

Quando os forms são pequenos não tem problema, mas quando ocupam a maior parte da dimensão vertical da tela, eles aparecem cortado embaixo. Ou melhor, uma faixa da parte de baixo fica escondida.

Alguém sabe como resolver isso?

wbb


Wbb

Wbb

Curtidas 0

Respostas

Massuda

Massuda

19/11/2004

O posicionamento da sua janela MDI child é centrado na área cliente do form principal.

Esse posicionamento é feito em TCustomForm.CMShowingChanged na unit Forms... para modificar isso, você pode declarar sua própria versão desse tratador de mensagem em seu form MDI child. Como esse tratador é relativamente complexo, acho que o mais fácil é copiar todo o tratador original para a sua versão e modificar o par de linhas que interessa.


GOSTEI 0
Wbb

Wbb

19/11/2004

Valeu Massuda, mas mesmo assim não sei como fazer. Se puder me dar uma orientação mais aprofundada eu agradeceria.

T+
wbb


GOSTEI 0
Massuda

Massuda

19/11/2004

:oops: Falar é muito mais fácil do que fazer... Isso aqui é mais complicado do que parecia... vou te dar retorno sobre isso, mas não agora.


GOSTEI 0
Godzilla_xf

Godzilla_xf

19/11/2004

Olá, para ser bem franco eu nunca passei por isso, todos os forms MDI que uso eu só modifico a propriedade [b:fce901f272]Position[/b:fce901f272] para [b:fce901f272]poScreenCenter[/b:fce901f272], e eles sempre ficam centralizados no form Principal da aplicação o [b:fce901f272]fsMDIForm[/b:fce901f272], vc esta usando outros atributos neste form que não centraliza??.
Alinhamento ou algo assim...
Tentou com outros form´s MDi??...

espero ter ajudado....
falow


GOSTEI 0
Massuda

Massuda

19/11/2004

[b:08264bbf84]GodZilla_XF[/b:08264bbf84]: o problema do [b:08264bbf84]wbb[/b:08264bbf84] é que o form filho não aparece centrado no meio do form pai... ele sempre aparece um pouco abaixo do esperado. Isso acontece porque o form filho é centrado na área cliente do form pai.

[b:08264bbf84]wbb[/b:08264bbf84]: a solução era mais simples :) Na classe que implementa o form filho, inclua a procedure SetBounds()...


type
  TFormFilho = class(TForm)
  public
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  end;

...

procedure TFormFilho.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
    Rect: TRect;
    Origem: TPoint;
begin
    if Showing then begin

      // Obtem o retângulo da área cliente MDI
      Windows.GetWindowRect(Application.MainForm.ClientHandle, Rect);

      // Calcula a origem da área cliente MDI no form pai
      Origem := Rect.TopLeft;
      Dec(Origem.x, Application.MainForm.Left);
      Dec(Origem.y, Application.MainForm.Top);

      // Calcula nossa nova posição
      ALeft := (Application.MainForm.Width - Width) div 2  - Origem.x;
      ATop := (Application.MainForm.Height - Height) div 2  - Origem.y;
    end;

    inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;



Se você fizer Position = poDefault ou poDesigned no form MDI filho, ele não será centrado no form pai (como era de se esperar).


GOSTEI 0
Massuda

Massuda

19/11/2004

Mais um detalhe... se quiser o form filho centrado corretamente na área cliente do form pai...
procedure TFormFilho.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
  Rect: TRect;
  OurWidth: Integer;
  OurHeight: Integer;
begin
  if Showing then begin

    // Obtem o retângulo da área cliente MDI
    Windows.GetWindowRect(Application.MainForm.ClientHandle, Rect);

    // Calcular largura e altura da área cliente
    OurWidth := Rect.Right - Rect.Left;
    OurHeight := Rect.Bottom - Rect.Top;

    // Calcula a nova posição
    ALeft := (OurWidth - Width) div 2;
    ATop := (OurHeight - Height) div 2;
  end;

  inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;



GOSTEI 0
Diogoalles

Diogoalles

19/11/2004

Como faço para utilizar essa função em todos meus forms ?
existe alguma maneira que não seja colocar a função em todos os forms ?

obrigado
Diogo


GOSTEI 0
Diogoalles

Diogoalles

19/11/2004

além da pergunta acima,
gostaria de saber como utilizar ou adaptar essa função para alinhar forms do tip fsNormal ?


abraço
Diogo


GOSTEI 0
Massuda

Massuda

19/11/2004

Como faço para utilizar essa função em todos meus forms ?
Use herança. Crie um form com estilo fsMDIChild com o codigo mostrado e derive seus forms a partir desse form (use [b:6444a88e05]File|New[/b:6444a88e05], clique na aba com o nome do seu projeto, selecione o form e clique OK).


GOSTEI 0
Diogoalles

Diogoalles

19/11/2004

Blz Massuda.. isso mesmo !

gostaria de saber como utilizar ou adaptar essa função para alinhar forms do tip fsNormal ?


abraço
Diogo


GOSTEI 0
Massuda

Massuda

19/11/2004

...como utilizar ou adaptar essa função para alinhar forms do tip fsNormal ?
A idéia original era centrar forms MDIChild. Para forms normais, acho que seria mais simples usar as opções da propriedade TForm.Position...[list:16f8d80a6e][*:16f8d80a6e]poDesktop: centrar na área de trabalho do Windows[*:16f8d80a6e]poScreenCenter: centrar na tela[*:16f8d80a6e]poMainFormCenter: centrar no form principal[*:16f8d80a6e]poOwnerFormCenter: centrar no form que é Owner do form que está sendo exibido (Owner é o parâmetro passado no Create do form)[/list:u:16f8d80a6e]


GOSTEI 0
POSTAR