Jerfs 1 Denunciar post Postado Julho 16, 2008 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
marcio.theis 3 Denunciar post Postado Julho 16, 2008 Como fez para criar o form ? Tenta fazer somente a criação: Form2:=TForm2.Create(Application); Compartilhar este post Link para o post Compartilhar em outros sites
Jerfs 1 Denunciar post Postado Julho 16, 2008 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
marcio.theis 3 Denunciar post Postado Julho 16, 2008 Coloca o fonte que usa no botão... Compartilhar este post Link para o post Compartilhar em outros sites
Jerfs 1 Denunciar post Postado Julho 16, 2008 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
shini 318 Denunciar post Postado Julho 16, 2008 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
Jerfs 1 Denunciar post Postado Julho 16, 2008 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
marcio.theis 3 Denunciar post Postado Julho 16, 2008 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
Discorpio 1 Denunciar post Postado Julho 17, 2008 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