Fórum Executar procedure através de uma string #241127

02/07/2004

0

Na verdade são 2 perguntas que eu quero fazer.

1º Tem como eu executar uma procedure através de uma string, tipo.

procedure mensagem;
begin
  showmessage(´Teste´);
end;

form1.button1click(sender:tobject);
begin
  [b]execute[/b](´mensagem´);
end;


2º Tem como criar uma procedure em tempo de execução onde o código da mesma estará em um arquivo externo.[/code]


Jprogramador

Jprogramador

Responder

Posts

02/07/2004

Sandra

1º Tem como eu executar uma procedure através de uma string, tipo.
procedure mensagem;
begin
  showmessage(´Teste´);
end;

form1.button1click(sender:tobject);
begin
  [b]execute[/b](´mensagem´);
end;


JProgramador,

Se eu entendi seu propósito, a 1ª procedure está correta; a 2ª, altere para:
form1.button1click(sender:tobject);
begin
  mensagem;
end;

Cada vez que clicar no button1, automaticamente, está chamando a procedure [b:2eae37bff7]mensagem[/b:2eae37bff7] e exibirá o showmessage. É isso?


Responder

Gostei + 0

03/07/2004

Jprogramador

Acho que não me expliquei direito, então deixa eu por a situação real.
Quero fazer um software onde o meu menu vai ser criado em tempo de execução através de uma tabela.
Na tabela vai ter os campos
NomeMenu Caption Nive1 Nivel2 Nivel3

Abaixo a tabela preenchida com alguns itens

NomeMenu CaptionNivel1Nivel2Nivel3
MnuCadastro Cadastro100
MnuCadastroClientes Clientes110
MnuCadastroProdutos Produtos120
MnuLocalizar Localizar200
MnuLocalizarClientes Clientes210
MnuLocalizarProdutos Produtos220
MnuRelatorio Relatorio300
MnuRelatorioClientes Clientes310
MnuRelatorioClientesDiarioDiário311
MnuRelatorioClientesMensalMensal312
MnuRelatorioProdutos Produtos320
MnuRelatorioProdutosDiarioDiário321
MnuRelatorioProdutosMensalMensal322

Menu resultante

CadastroLocalizarRelatorio
ClientesClientesClientes--> Diário
Mensal
ProdutosProdutosProdutos--> Diário
Mensal

Procedimento utilizado para criar o menu

procedure criarmenu;
var
  QryMenu:TQuery;  
  MenuPrincipal:TMainMenu;  
  ItemMenu:array of TMenuItem;
  i,j:integer;
Begin
  MenuPrincipal:=TMainMenu.Create(self);  //Criar o menu
  QryMenu:=TQuery.Create(self);  //Criar a query
  QryMenu.DatabaseName:=´sistema´;  //Nome do meu alias(Em paradox)
  QryMenu.sql.Add(´select * from menus order by nivel1,nivel2,nivel3´); //Selecionar todos os campos e ordenar de modo que crie um menu por vez
  QryMenu.Open;
  SetLength(ItemMenu,QryMenu.RecordCount);  //Define o tamanho do vetor de itens do menu
  i:=0;
  while not QryMenu.Eof do
  begin
    ItemMenu[i]:=TMenuItem.Create(self);  //Criar item do menu
    ItemMenu[i].Name:=QryMenu.FieldByName(´NomeMenu´).Value;
    ItemMenu[i].Caption:=QryMenu.FieldByName(´Caption´).Value;
{Ai vem o motivo da 1º pergunta
Neste ponto queria passar o nome de uma procedure criada previamente com o mesmo nome do menu ex:
ItemMenu[i].OnClick:=QryMenu.FieldByName(´NomeMenu´).Value;
Só que OnClick é TNotifyEvent e QryMenu.FieldByName(´NomeMenu´).Value é string
outra alternativa seria criar a procedure nesse momento com o conteudo de um outro campo que eu criaria na tabela
Esse é o motivo da 2º pergunta
}
    if QryMenu.FieldByName(´nivel2´).Value=0 then  //Se for menu
    begin
      MenuPrincipal.Items.Add(ItemMenu[i]);  //Adiciona no principal
      j:=i;
    end
    else if QryMenu.FieldByName(´nivel3´).Value<>0 then  //Se for item de submenu  ex:Diário e mensal
      ItemMenu[j+QryMenu.FieldByName(´nivel2´).AsInteger].Add(ItemMenu[i])
    else  //Se for comando de menu
      ItemMenu[j].Add(ItemMenu[i]);
    i:=i+1;
    QryMenu.Next;
  end;
end;


Espero ter sido mais claro, qual o objetivo disso?
se conseguir criar a procedure na hora sempre que quiser criar um novo menu é só criar um novo registro na tabela
se não der pra criar na hora mas der pra passar uma procedure, de qualquer forma fica mais organizado para eu trocar o menu para um treeview, botoes ou qualquer outro tipo de componente.
não sei dá pra criar a procedure na hora pelo delphi, mas passar uma procedure para um evento atraves do nome sei que é possível.
Se alguém quiser me ajudar, a facilitar nossas vidas em manutenção de softwares ficarei grato.

Ficou um pouquinho grande né ;-)


Responder

Gostei + 0

03/07/2004

Jprogramador

sobe


Responder

Gostei + 0

03/07/2004

Jprogramador

sobe


Responder

Gostei + 0

04/07/2004

Emerson Nascimento

[b:7b234f6173][size=18:7b234f6173]veja se isso aqui funciona:[/size:7b234f6173][/b:7b234f6173]

procedure TForm.CriarMenu;
var
    QryMenu:TQuery;
    MenuPrincipal:TMainMenu;
    ItemMenu:array of TMenuItem;
    i,j:integer;
    Rotina: procedure of object; // aqui começa a mudança
Begin
    MenuPrincipal:=TMainMenu.Create(self);   //Criar o menu
    QryMenu:=TQuery.Create(self);   //Criar a query
    QryMenu.DatabaseName:=´sistema´;   //Nome do meu alias(Em paradox)
    //Selecionar todos os campos e ordenar de modo que crie um menu por vez
    QryMenu.sql.Add(´select * from menus order by nivel1,nivel2,nivel3´);
    QryMenu.Open;
    SetLength(ItemMenu,QryMenu.RecordCount);//Define o tamanho do vetor de itens do menu
    i:=0;
    while not QryMenu.Eof do
    begin
        ItemMenu[i]:=TMenuItem.Create(self);   //Criar item do menu
        ItemMenu[i].Name:=QryMenu.FieldByName(´NomeMenu´).Value;
        ItemMenu[i].Caption:=QryMenu.FieldByName(´Caption´).Value;

        // aqui ´pega´ a procedure. note que a rotina deve estar no próprio formulário.
        if QryMenu.FieldByName(´NomeMenu´).AsString <> EmptyStr then
        begin
            @Rotina := MethodAddress(QryMenu.FieldByName(´NomeMenu´).AsString);
            // aqui verifica se a rotina existe.
            if Assigned(Rotina) then
                try
                    ItemMenu[i].OnClick:=TNotifyEvent(Rotina); //aqui atribui a rotina ao evento OnClick
                except
                end;
        end;

        if QryMenu.FieldByName(´nivel2´).Value=0 then   //Se for menu
        begin
            MenuPrincipal.Items.Add(ItemMenu[i]);   //Adiciona no principal
            j:=i;
        end
        else
        if QryMenu.FieldByName(´nivel3´).Value<>0 then   //Se for item de submenu   ex:Diário e mensal
            ItemMenu[j+QryMenu.FieldByName(´nivel2´).AsInteger].Add(ItemMenu[i])
        else   //Se for comando de menu
            ItemMenu[j].Add(ItemMenu[i]);
        inc(i);
        QryMenu.Next;
    end;
end;


Responder

Gostei + 0

04/07/2004

Jprogramador

Valeu Emerson, funcionou como vc disse. Muito obrigado.
Se vc descobrir se é possível criar uma procedure em tempo de execução como eu havia comentado, por favor me avise.


Responder

Gostei + 0

31/01/2009

El-loeco

Olá emerson e JProgramador eu também usei essas dicas e funcionou beleza. Mas se pudece-mos adicionar mais um campo na tabela de ´NIVEL4... como ficaria o codigo? Ja tentei implementar mas não consegui. Se puder me ajudar fico grato. Abraço.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar