Procedure comum em todos os forms

02/09/2004

0

Boa dia, gostaria de saber como faço para ter uma procedure comum para todos o forms de um programa.

Exemplo:
Tenho uma unit de funções chamada u_Funcoes, em um forma tenho vários botões onde mudarei suas propriedades a medida que é executado algum outro comando. como todos os forms terão esses mesmos botões com as mesmas propriedade, gostaria de saber como faço para utilizar as mesmas funções para todos os forms.

Ps. Tentei criar a procedure deste jeito, mas não deu certo - não consegui compilar o programa
Procedure AtivaAtalhos();
Begin
  OB_Anterior.Enabled:=True;
  OB_Proximo.Enabled:=True;
  OB_Ultimo.Enabled:=True;
  OB_Novo.Enabled:=True;
  OB_Alterar.Enabled:=True;
  OB_Excluir.Enabled:=True;
  OB_Fechar.Enabled:=True;
  OB_Primeiro.Enabled:=True;
  OB_Confirma.Visible:=False;
End;


Obrigado


Lucianogar

Lucianogar

Responder

Posts

02/09/2004

Lucas Silva

Se você trabalhar com herança de formulários, você pode fazer assim:

No form principal vc declara ela na seção public
Procedure AtivaAtalhos(); virtual; // virtual é pq ela poderá ser implementada nas classes Filhas.



Nas filhas se vc quiser implementar é só colocar:
Procedure AtivaAtalhos(); override;


até mais,
Lucas!


Responder

02/09/2004

Vinicius2k

Colega,

Vc pode alterar sua procedure para que ela receba o form em que vc chamá-la como parametro... creio que ficaria assim:
procedure AtivaAtalhos(frm: TForm);
var i: Integer;
begin
  with frm do begin
    for i:= 0 to (ComponentCount - 1) do begin
      with Components[i] do begin
        { **** }
        if (Name = ´OB_Anterior´) or (Name = ´OB_Proximo´ ) or
           (Name = ´OB_Ultimo´  ) or (Name = ´OB_Novo´    ) or
           (Name = ´OB_Excluir´ ) or (Name = ´OB_Fechar´  ) or
           (Name = ´OB_Primeiro´) or (Name = ´OB_Anterior´) then
          (Components[i] as TButton).Enabled:= True;
        { **** }
        if (Name = ´OB_Confirma´) then
          (Components[i] as TButton).Enabled:= False;
      end;
    end;
  end;
end;


Para chamar, em qualquer form, basta :
AtivaAtalhos(Self);


Espero ter ajudado...
T+


Responder

02/09/2004

Bruno Belchior

sobre a procedure enviada pelo colega utilizae-a assim:

procedure AtivaAtalhos(frm: TForm);
var i: Integer;
begin
with frm do begin
for i:= 0 to (ComponentCount - 1) do begin
with Components[i] do begin
{ **** }
if (Name in [´´OB_Anterior´´,´OB_Proximo´ ,´OB_Ultimo´,´OB_Novo´,
´OB_Excluir´ ,´OB_Fechar´,´OB_Primeiro´,´OB_Anterior´]) then
(Components[i] as TButton).Enabled:= True;
{ **** }
if (Name = ´OB_Confirma´) then
(Components[i] as TButton).Enabled:= False;
end;
end;
end;
end;

porque evitar o ´or´ melhora o desempenho de se código!


Responder

02/09/2004

Lucianogar

Primeiro obrigado pela ajuda, mas infelizmente não esta dando certo
fiz esse segunda opção (vinicius2K) e esta ocorrendo o seguinte erro:

´List index out of bounds (50)´

se alguem puder me ajudar, obrigado


Responder

02/09/2004

Ipc$

if (Name in [´´OB_Anterior´´,´OB_Proximo´ ,´OB_Ultimo´,´OB_Novo´, ´OB_Excluir´ ,´OB_Fechar´,´OB_Primeiro´,´OB_Anterior´]) then

Em qual Delphi vc consegue compilar esse código :?:


Responder

02/09/2004

Vinicius2k

[quote:a0e56962cf=´IPC$´]
if (Name in [´´OB_Anterior´´,´OB_Proximo´ ,´OB_Ultimo´,´OB_Novo´, ´OB_Excluir´ ,´OB_Fechar´,´OB_Primeiro´,´OB_Anterior´]) then
Em qual Delphi vc consegue compilar esse código :?:[/quote:a0e56962cf]
Isso eu tbm queria saber... :?
Estamos tratando de Strings (nome do componente) e não tipos ordinais...


Colega lucianogar, tem certeza de que este trecho estah correto ? :
for i:= 0 to (ComponentCount - 1) do begin 

Vc não se esqueceu do [b:a0e56962cf][color=red:a0e56962cf]-1[/color:a0e56962cf][/b:a0e56962cf] ? Lembre-se de que a contagem de índices de um Array (Components) começa de Zero, por isso é necessário o -1...

T+


Responder

02/09/2004

Emerson Nascimento

gostaria de questionar uma coisa: visto que os botões são conhecidos, porque o laço com a pesquisa de componentes?
não bastaria mencioná-los? com certeza a execução se tornaria muito mais rápida, visto que, com o laço (for..next) a função ficará mais demorada quando o form tiver muitos componentes.

creio que o ideal seria:

procedure AtivaAtalhos(Form: TForm; Ativar: boolean = True);
const Botoes: array[0..8] of string =
    (´OB_Anterior´,´OB_Proximo´,´OB_Ultimo´,´OB_Novo´,´OB_Alterar´,
    ´OB_Excluir´,´OB_Fechar´,´OB_Primeiro´,´OB_Confirma´);
var
    i: byte;
begin
    with Form do
        for i := 0 to High(Botoes) do
            try
                if Botoes[i] = ´OB_Confirma´ then
                    TButton(FindComponent(Botoes[i])).Enabled := not Ativar
                else
                    TButton(FindComponent(Botoes[i])).Enabled := Ativar;
            except
            end;
end;

a sintaxe seria:
AtivarAtalhos(Self) ou, para inverter os botões,
AtivarAtalhos(Self,False)


Responder

02/09/2004

Ipc$

gostaria de questionar uma coisa: visto que os botões são conhecidos, porque o laço com a pesquisa de componentes? não bastaria mencioná-los? com certeza a execução se tornaria muito mais rápida, visto que, com o laço (for..next) a função ficará mais demorada quando o form tiver muitos componentes.

Caro colega, se vc verificar a função FindComponent em Classes.pas, notará que ela faz um laço de 0 a Count-1.
Então vc estará fazendo o laço da função 9 vezes.
Se eles estiverem no início, pode ser que seja até mais rápido, pq o laço se encerra quando o componente é encontrado; contudo serão sempre 9 laços.


Responder

02/09/2004

Emerson Nascimento

[size=18:07c5b325e7][b:07c5b325e7]melhor:[/b:07c5b325e7][/size:07c5b325e7]

procedure AtivaAtalhos(Form: TForm; Ativar: boolean = True);
const Botoes: array[0..8] of string =
    (´OB_Anterior´,´OB_Proximo´,´OB_Ultimo´,´OB_Novo´,´OB_Alterar´,
    ´OB_Excluir´,´OB_Fechar´,´OB_Primeiro´,´OB_Confirma´);
var
    i: byte;
    Componente: TComponent;
begin
    with Form do
        for i := 0 to High(Botoes) do
        begin
            Componente := FindComponent(Botoes[i]);
            if Componente <> nil then
            begin
                if Botoes[i] = ´OB_Confirma´ then
                    TButton(Componente).Enabled := not Ativar
                else
                    TButton(Componente).Enabled := Ativar;
            end;
end;

onde se lê TButton, coloque a classe correta.


Responder

02/09/2004

Vinicius2k

Emerson,

Sua solução estah mais completa e enxuta que a minha, mas discordo de vc quanto à velocidade do laço... o método FindComponent utiliza sobre o container o mesmo laço que eu re-escrevi...
Veja :
function TComponent.FindComponent(const AName: string): TComponent;
var
  I: Integer;
begin
  if (AName <> ´´) and (FComponents <> nil) then
    for I := 0 to FComponents.Count - 1 do
    begin
      Result := FComponents[I];
      if SameText(Result.FName, AName) then Exit;
    end;
  Result := nil;
end;


E se medirmos, talvez nem chegasse a ficar na casa dos milisegundos, mas creio que a sua seria ligeiramente mais lenta que a minha pq vc está fazendo dois laços... um visível e outro embutido na FindComponent...

T+


Responder

02/09/2004

Emerson Nascimento

[quote:275dcdbfc2=´IPC$´]
gostaria de questionar uma coisa: visto que os botões são conhecidos, porque o laço com a pesquisa de componentes? não bastaria mencioná-los? com certeza a execução se tornaria muito mais rápida, visto que, com o laço (for..next) a função ficará mais demorada quando o form tiver muitos componentes.

Caro colega, se vc verificar a função FindComponent em Classes.pas, notará que ela faz um laço de 0 a Count-1.
Então vc estará fazendo o laço da função 9 vezes.
Se eles estiverem no início, pode ser que seja até mais rápido, pq o laço se encerra quando o componente é encontrado; contudo serão sempre 9 laços.[/quote:275dcdbfc2]

[b:275dcdbfc2][size=18:275dcdbfc2]está correto[/size:275dcdbfc2][/b:275dcdbfc2]


Responder

02/09/2004

Beppe

O mais eficiente seria criar um array de componentes, não dos nomes deles. Como os componentes não são os mesmos, apenas os nomes, deve ser usado herança nos formulários(se possível), ou então cada formulário implementa uma interface que provê como propriedades os componentes.

Uma solução mais fácil de fazer, conforme o método de procurar nomes, seria formar uma string com os nomes de todos os componentes, usando uma delimitador como ´;´ ou #0. Ex:

const
  Botoes = ´OB_Anterior;OB_Proximo;OB_Ultimo;OB_Novo;OB_Alterar;OB_Excluir;OB_Fechar;OB_Primeiro;OB_Confirma´;
var
  I: Integer;
begin
  with Frm do
    for I := 0 to ComponentCount - 1 do
      if Components[i] is TButton then
        TButton(Components[i]).Enabled := Pos(Botoes, Components[i].Name) > 0; 
end;

Isto funciona, salvo erros de digitação. Como ´;´ não pode pertencer a um nome de componente, a função Pos pode ser usada.

Outra maneira seria usar a Tag dos controles.

Mas acho que o método utilizado nem importa, pq é um procedimento raro de ser executado. Como o vinicius2k disse, tvznem chegue aos milissegundos. Neste caso o que deve contar mais é a facilidade de escrever/manter do que a eficiência.


Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

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

Aceitar