Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Jerfs

[Resolvido] MDI Form

Recommended Posts

Galera estou tentando criar minha primeira aplicação usando MDI Form, mas a primeira operação já me deparei com erro :(. Acontece o seguinte:

 

1 - Criei dois formularios, um como se fosse o Pai e outro como um Child;

2 - Entrei no Project Options e deixei no autocreate somente o form pai, e movi para o avaliable form o child.

3 - Coloquei um botão no formulário pai para criar o formulário child e deixa em showmodal, então surgiu a seguinte mensagem de erro:

 

Project Teste.exe raised exception class EInvalidOperation with message 'Cannot make a visible window modal'. Process Stopped. User Step or Run to continue.

 

Alguém pode dar um help, ainda estou inseguro em relação a esse tal MDI!

 

Agradecido!

Compartilhar este post


Link para o post
Compartilhar em outros sites

O form já existe, porém não está sendo auto-criado, ele está avaliable... Quando inicio o programa, tem um formulario (fsMDIForm) sendo criado, dentro desse form existe um botão que mostrará um form (fsMDIChild).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Lembrando que inicialmente setei dentro de Project Options o Formulário Principal como o único automaticamente criado e o frmUserManagement está dentro de Available Forms.

 

Segue o código que está dando erro.

 

CODE
procedure TfrmPrincipal.Button1Click(Sender: TObject);

begin

Application.CreateForm(TfrmUserManagement, frmUserManagement);

frmUserManagement.ShowModal;

end;

Compartilhar este post


Link para o post
Compartilhar em outros sites

cara n da pra usa showmodal em mdichild, pq quando ele cria o form ele ja chama o .show, se você tentar deixa o visible do form pra false vai dar um erro, mais ou menos assim, n é possivel ocultar o formxx; se você quer o usurio n mexa em nada, desabite os controles que você quer q o usuario n mexa, pra habilita eles, so confirmando a ação, ou cancelando, isso ae ´´e um quebra galho, espero q ajude...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom shini, acho que entendi, então se eu for trabalhar com o MDI eu não consigo destruir o formulario e criar ele somente quando for usar... então terei de trabalhar com visible true/false nos forms!?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho que poderia sim, somente os forms filhos teriam de ficar em unvaliable form, e depois teria de fazer a criação:

 

Application.CreateForm(TfrmUserManagement, frmUserManagement);

E no evento OnClose poderia fazer:

 

Action:=caFree;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde a Todos.

 

Como disse o nosso amigo Shini, em sistemas MDI voce jamais poderá utilizar o método ShowModal, porém voces sabem porque ?

 

Por uma razão muito simples, o que quer dizer MDI ? Mutiple Documents Interface, ou seja, Interface de Documentos Múltiplos (Vários documentos), já SDI (Single Documents Interface) é Interface de Documento Único.

 

Ora, se o seu sistema é MDI, trabalha com vários documentos abertos na mesma Interface, ou seja, dentro do mesmo Formulário que é o MDIForm (O Form Pai), se voce abre os Forms desse sistema com ShowModal, o que vai acontecer é que o ShowModal vai travar o Foco no formulário recém aberto e não permitirá que se click fora dele, e abra outro Form, assim o sistema deixa de ser MDI para ser SDI, e por esta razão que todas as propriedades Visible dos Forms foram travadas na opção True, e isto permite tão logo voce instancie (Crie) o Form em memória, ele seja visualizado.

 

Entretanto, isto acarreta um certo problema de estética de layout dos Forms, o que tem sido algum incômodo para certos desenvolvedores, e que com certeza não vai agradar aos usuários que utilizarão o sistema, ou seja, a poluição visual do Form de abertura.

 

Afim de resolver estes problemas, devemos adotar certas medidas, medidas estas que tive oportunidade de observar e adotar, e que muito me ajudou a desenvolver sistemas MDI, que são:

 

1º) A primeira medida o nosso amigo Jerfs já adotou, que é só autocriar o Form pai (MDIForm) no momento da Inicialização do Sistemas, voce consegue ver isto indo no Menu Project -> Options e quando abrir a caixa wizard Project Options for nome do seu projeto, voce tem uma combobox MAIN que é o Form de Abertura, e duas caixas de listagens que é Auto-Create Forms e Available Forms, o que estiver em Auto-Create Forms serão os Forms que serão automaticamente criados (Instanciados) na memória no momento que inicia o executável, aconselho a deixar somente o Form Pai (MDIForm) e o DataModule se por ventura este existir. Quanto aos demais, mova-os para Available Forms com os botões ">", ">>" e etc.

 

2º) Sempre abra qualquer MDIChild (Forms Filhos) com o método Application.CreateForm(Classe do Form, Nome da Instancia), isto porque quando voce abre o Form com esse método, fará com que o proprietário do Form seja a aplicação, fazendo com que aplicação controle a visualização do mesmo, bem como a sua destruição, caso este seja destruída (fechada). Voce pode até utilizar o método Create da Classe TObject que surte o mesmo efeito, assim:

 

Form1 := TForm1.Create(Application);

Porém eu prefiro utilizar o método CreatForm da classe Application.

 

3º) Bom, mas se quando formos abrir pela primeira vez qualquer Form MDIChild, como vamos tirá-lo da tela, já que ele está instanciado e quando o tentamos fechar ele fica miminizado ? Para isso devemos configurar o Evento OnClose de cada MDIChild, para que ele seja destruído tão logo seja fechado com o seguinte Código:

 

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(Form2); // Opção mais eficiente.
  
  // ou

  Action := caFree;
end;

4º) Não sei se muitos já observaram, mas existe um outro problema dentro de sistemas MDI, voce pode abrir o mesmo Form várias vezes com a mesma instancia (variável), mas como isso é possível ? se em sistemas SDI isso gera erro, ou seja tentar instanciar a mesma variável duas vezes ? Isto ocorre porque o MDI utiliza um Array de Formulário para referenciar os seus Formulários que é o Array MDIChildren, este array é redimensionado toda vez que voce clica para abrir vários Forms e inclusive o mesmo Form. Para solucionar isto, criei um método dentro do MDIForm (Form pai) que verifica se o Form já está instanciado, se já estiver, ele apenas seta o foco no Form, se não cria o Form assim:

 

  type
	  Form1 = class(TForm)
	  .....
	  .....
	  Private
		  { Private declarations }
	  Public
		  { Public declarations }
		  procedure OpenForm(FClass: TFormClass; var Instance);
	  end;

  var
	  Form1: TForm1;

  implementation

  uses DM, Funcionario, Usuario, Login, Processos, Fase, AlteraSenha, Template;

  {$R *.dfm}

  procedure TForm1.OpenForm(FClass: TFormClass; var Instance);
  begin
	  if Assigned(TForm(Instance)) then begin
			TForm(Instance).SetFocus;
			TForm(Instance).WindowState := wsNormal;
			TForm(Instance).BringToFront;
	  end else
			Application.CreateForm(FClass, Instance);
  end;

Repare que eu declarei esse método dentro do bloco Public da Classe do Formulario, isto lhe permite utilizar este método em outros Forms, desde que voce declara a Unit do MDIForm na seção Uses dos outros Forms.

 

Assim voce pode utilizar esse método, do mesmo modo que o método CreateApplication da classe Application, só que com uma diferença, ele só vai instanciar o Form se este não estiver na memória.

 

OpenForm(TForm2, Form2);

Um abraço a todos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.