Executar procedure através de uma string
Na verdade são 2 perguntas que eu quero fazer.
1º Tem como eu executar uma procedure através de uma string, tipo.
2º Tem como criar uma procedure em tempo de execução onde o código da mesma estará em um arquivo externo.[/code]
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
Curtidas 0
Respostas
Sandra
02/07/2004
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?
GOSTEI 0
Jprogramador
02/07/2004
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
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é ;-)
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é ;-)
GOSTEI 0
Jprogramador
02/07/2004
sobe
GOSTEI 0
Jprogramador
02/07/2004
sobe
GOSTEI 0
Emerson Nascimento
02/07/2004
[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;
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;
GOSTEI 0
Jprogramador
02/07/2004
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.
Se vc descobrir se é possível criar uma procedure em tempo de execução como eu havia comentado, por favor me avise.
GOSTEI 0
El-loeco
02/07/2004
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.
GOSTEI 0