Olá galera, nesta Quick Tips mostrarei como podemos criar um formulário padrão para ser usado com Herança. Nele será possível:

  • Incluir;
  • Editar;
  • Gravar;
  • Excluir;
  • Cancelar;
  • Habilitar Edits, DBEdits, Combobox, DBCombobox, RadioGroup, DBRadioGroup, entre outros componentes;
  • Habilitar e desabilitar os botões de navegação;
  • Habilitar e desabilitar os botões de incluir, editar, excluir, cancelar, gravar;
  • Mudar a cor do componente que receber o foco.

Vamos montar uma tela com os seguintes componentes:

  • 1 ToolBar (10 ToolButton – Basta clicar com o botão direito e adicionar os 10 botões). Os nomes seguem a lógica do Caption dos ToolButton:BtnNovo, BtnGravar,BtnEditar, BtnDeletar,BtnCancelar, BtnPesquisa, BtnPrimeiro,BtnAnterior,BtnProximo, BtnUltimo
  • 1 Panel
  • 1 BallonHint
  • 2 ImageList(Img_BallonHint, Img_Botoes)
  • 1 DataSorce(DSPadrao)
  • 1 StatusBar ( Vamos adicionar um Panel)

Veja como ficará nossa tela:

resultado da tela

Agora vamos criar alguns métodos para estarmos preparando nosso exemplo:

private

{ Private declarations }

     procedure HabilitaControles;

     procedure HabilitaControlesVisuais(Status: Boolean);

     procedure ChangeEnter(Sender: TObject);

     procedure ChangeExit(Sender: TObject);

protected

     xBooValidaRequeridos : Boolean;

     function ValidaRequeridos: Boolean;

Vamos agora implementar a procedure HabilitaControles com o código a seguir:

procedure TFrmPadrao.HabilitaControles;

begin

    BtnNovo.Enabled := not(DSPadrao.DataSet.State in [dsInsert, dsEdit]);

    BtnGravar.Enabled := (DSPadrao.DataSet.State in [dsInsert, dsEdit]);

    BtnEditar.Enabled := (DSPadrao.DataSet.State in [dsBrowse]);

    BtnDeletar.Enabled := (DSPadrao.DataSet.State in [dsEdit,dsBrowse]) and DSPadrao.DataSet.Active;

    BtnCancelar.Enabled := (DSPadrao.DataSet.State in [dsInsert, dsEdit]);

    BtnPesquisa.Enabled := not(DSPadrao.DataSet.State in [dsInsert, dsEdit]);

end;

 

procedure TFrmPadrao.HabilitaControlesVisuais(Status: Boolean);

var

    I: Integer;

begin

    for I := 0 to ComponentCount - 1 do

    begin

        if Components[I] is TLabel then

            TLabel(Components[I]).Font.Color := clWindowText

        else if Components[I] is TDBEdit then

            TDBEdit(Components[I]).Enabled := Status

        else if Components[I] is TDBLookupComboBox then

            TDBLookupComboBox(Components[I]).Enabled := Status

        else if Components[I] is TDBComboBox then

            TDBComboBox(Components[I]).Enabled := Status

        else if Components[I] is TDBMemo then

            TDBMemo(Components[I]).Enabled := Status

        else if Components[I] is TCheckListBox then

            TCheckListBox(Components[I]).Enabled := Status

        else if Components[I] is TDBRadioGroup then

            TDBRadioGroup(Components[I]).Enabled := Status

        else if Components[I] is TDateTimePicker then

            TDateTimePicker(Components[I]).Enabled := Status

    end;

    StatusBar1.Panels[0].Text := '';

end;

Agora vamos a implementação de outros 3 métodos restantes: ChangeEnter, ChangeExit e ValidaRequeridos.

ChangeEnter: Este método mudará a cor dos componentes dependendo do seu tipo ao receber o foco:

procedure TFrmPadrao.ChangeEnter(Sender: TObject);

begin

  if Sender is TDBEdit then

    TDBEdit(Sender).Color := $00BAFEF5

  else if Sender is TDBMemo then

    TDBMemo(Sender).Color := $00BAFEF5

  else if Sender is TDBLookupComboBox then

    TDBLookupComboBox(Sender).Color := $00BAFEF5

  else if Sender is TDBComboBox then

    TDBComboBox(Sender).Color := $00BAFEF5;

end;

ChangeExit: Este método mudará a cor dos componentes dependendo do seu tipo ao perder o foco:

procedure TFrmPadrao.ChangeExit(Sender: TObject);

begin

  if Sender is TDBEdit then

    TDBEdit(Sender).Color := clWindow

  else if Sender is TDBMemo then

    TDBMemo(Sender).Color := clWindow

  else if Sender is TDBLookupComboBox then

    TDBLookupComboBox(Sender).Color := clWindow

  else if Sender is TDBComboBox then

    TDBComboBox(Sender).Color := clWindow;

end;

ValidaRequeridos: Este método validará os campos marcados como requerido, caso seu conteúdo não seja preenchido, além de jogar foco para o componente associado aquele Field requerido. É importante usarmos a propriedade FocusControl dos nossos labels para que esta function rode perfeitamente:

function TFrmPadrao.ValidaRequeridos: Boolean;

var

   I: Integer;

   lbl: TLabel;

  fn: string;

  c: TObject;

begin

  Result := True;

  for I := 0 to ComponentCount - 1 do

  begin

    if Components[I] is TLabel then

      lbl := Components[I] as TLabel

  else

    Continue;

  lbl.Font.Color := clWindowText;

  if lbl.FocusControl <> nil then

  begin

    c := lbl.FocusControl;

    if IsPublishedProp(c, 'DataSource') then

    begin

      DSPadrao := TDataSource(GetObjectProp(c, 'DataSource'));

      if IsPublishedProp(c, 'DataField') then

      begin

        fn := GetStrProp(c, 'DataField');

        if DSPadrao.DataSet.FieldByName(fn).Required then

          if (DSPadrao.DataSet.FieldByName(fn).IsNull) or (DSPadrao.DataSet.FieldByName(fn).AsString = ''

            ) then

          begin

              lbl.Font.Color := clred;

              lbl.FocusControl.SetFocus;

              StatusBar1.Panels[0].Text := 'Campo ' + lbl.Caption + ' deve ser preenchido ';

              Result := False;

              xBooValidaRequeridos := False;

              Break;

          end

         else

         begin

            Result := True;

            xBooValidaRequeridos := True;

            StatusBar1.Panels[0].Text := '';

          end;

      end;

    end;

  end;

  end;

end;

A seguir implementaremos os botões que vão controlar o DataSet,ou seja, os botões de cadastrado, usando o evento onClick de cada um.

BtnCancelar:

procedure TFrmPadrao.BtnCancelarClick(Sender: TObject);

begin

   ActiveControl := Nil;

   with DSPadrao.DataSet do

      begin

         Cancel;

         Filtered := False;

         Close;

         HabilitaControles;

         HabilitaControlesVisuais(False);

      end;

end;

BtnDeletar:

procedure TFrmPadrao.BtnDeletarClick(Sender: TObject);

begin

   ActiveControl := Nil;

   if MessageDlg('Deseja Excluir o Registro?', mtconfirmation, [mbYes, mbNo], 0)

      = mrYes then

   with DSPadrao.DataSet do

   begin

      Delete;

      Close;

      HabilitaControles;

      HabilitaControlesVisuais(False);

   end;

end;

BtnEditar:

procedure TFrmPadrao.BtnEditarClick(Sender: TObject);

begin

   ActiveControl := Nil;

   with DSPadrao.DataSet do

   begin

      Edit;

      HabilitaControles;

      HabilitaControlesVisuais(True);

   end;

end;

BtnGravar:

procedure TFrmPadrao.BtnGravarClick(Sender: TObject);

begin

   ActiveControl := Nil;

   with DSPadrao.DataSet do

   begin

      if not ValidaRequeridos then

         Exit;

      Post;

      Close;

      HabilitaControles;

      HabilitaControlesVisuais(False);

      ShowMessage('Registro gravado com Sucesso!!!');

   end;

end;

BtnNovo:

procedure TFrmPadrao.BtnNovoClick(Sender: TObject);

begin

   ActiveControl := Nil;

   with DSPadrao.DataSet do

   begin

      Open;

      Insert;

      HabilitaControles;

      HabilitaControlesVisuais(True);

   end;

end;

BtnPrimeiro:

procedure TFrmPadrao.BtnPrimeiroClick(Sender: TObject);

begin

   with DSPadrao.DataSet do

   begin

      First;

      HabilitaControles;

   end;

end;

BtnProximo:

procedure TFrmPadrao.BtnProximoClick(Sender: TObject);

begin

   with DSPadrao.DataSet do

   begin

      Next;

      HabilitaControles;

   end;

end;

BtnAnterior:

procedure TFrmPadrao.BtnAnteriorClick(Sender: TObject);

begin

   with DSPadrao.DataSet do

   begin

      Prior;

      HabilitaControles;

   end;

end;

BtnUltimo:

procedure TFrmPadrao.BtnUltimoClick(Sender: TObject);

begin

   with DSPadrao.DataSet do

   begin

      Last;

      HabilitaControles;

   end;

end;

Finalizando o projeto

Mostraremos agora a parte final, com a configuração dos eventos finais. Lembrando que tudo estará disponível para download.

FormCreate: Neste evento vamos configurar todos os componentes com os eventos ChangeEnter,ChangeExit, além de deixarmos todos como UpperCase. Veja que temos algumas linhas comentadas, pois estas vão lhe ajudar a usar o BallonHint:

procedure TFrmPadrao.FormCreate(Sender: TObject);

var

    I: Integer;

    begin

        for I := 0 to ComponentCount - 1 do

        begin

            if Components[I] is TDBEdit then

            begin

               TDBEdit(Components[I]).OnEnter := ChangeEnter;

               TDBEdit(Components[I]).OnExit := ChangeExit;

               TDBEdit(Components[I]).CharCase := ecUpperCase;

               // TDBEdit(Components[I]).CustomHint := BalloonHint1;

               // TDBEdit(Components[I]).ShowHint := True;

            end

            else if Components[I] is TDBLookupComboBox then

            begin

               TDBLookupComboBox(Components[I]).OnEnter := ChangeEnter;

               TDBLookupComboBox(Components[I]).OnExit := ChangeExit;

               // TDBLookupComboBox(Components[I]).CustomHint := BalloonHint1;

               // TDBLookupComboBox(Components[I]).ShowHint := True;

            end

            else if Components[I] is TDBComboBox then

            begin

               TDBComboBox(Components[I]).OnEnter := ChangeEnter;

               TDBComboBox(Components[I]).OnExit := ChangeExit;

               TDBComboBox(Components[I]).CharCase := ecUpperCase;

               // TDBComboBox(Components[I]).CustomHint := BalloonHint1;

               // TDBComboBox(Components[I]).ShowHint := True;

            end

            else if Components[I] is TDBMemo then

            begin

               TDBMemo(Components[I]).OnEnter := ChangeEnter;

               TDBMemo(Components[I]).OnExit := ChangeExit;

               // TDBMemo(Components[I]).CustomHint := BalloonHint1;

               // TDBMemo(Components[I]).ShowHint := True;

            end

            else if Components[I] is TDateTimePicker then

            begin

               TDateTimePicker(Components[I]).OnEnter := ChangeEnter;

               TDateTimePicker(Components[I]).OnExit := ChangeExit;

               // TDateTimePicker(Components[I]).CustomHint:= BalloonHint1;

               // TDateTimePicker(Components[I]).ShowHint := True;

            end;

      end;

   Try

      DSPadrao.DataSet.Close;

      HabilitaControles;

      HabilitaControlesVisuais(False);

   except

         on e: Exception do

         begin

            ShowMessage('Erro ao conectar base de dados' + #13 + 'Erro : ' +

            e.Message + #13 + 'Classe : ' + e.ClassName);

         end;

   end;

end;

FormClose: Neste evento vamos apenas fechar o DataSet, para não deixar registros em memória:

procedure TFrmPadrao.FormClose(Sender: TObject; var Action: TCloseAction);

begin

   DSPadrao.DataSet.Close;

end;

Com o exemplo pronto basta criarmos um projeto e adicionarmos este form ao mesmo, para depois fazemos a parte da Herança visual.

O legal disso tudo é que esta tela não depende de tecnologia, dbexpress, ado, ou seja lá qual for sua maneira de conectar, pois estamos trabalhando diretamente com o DataSource, e sua propriedade DataSet.

Fico por aqui ate à próxima Quick Tips.