A Ferramenta Delphi nos disponibiliza grandes recursos para melhorarmos a nossa aplicação tais como: utilização de componentes de terceiros, a VCL aberta para estudo, criação de componentes próprios, Wizards e a possibilidade de criar Objetos de forma dinâmica e adicionar a estes recursos como o "Drag in Drop". Se você estiver se perguntando porque criar componentes em runtime, eis a resposta: Com esse recurso você pode disponibilizar para o seu cliente uma versão Professional do seu Produto e com esta versão ele poderá: criar novos relatórios, novos formulários de cadastro, gráficos e um ainda ter um assistente de consultas.

    Esse artigo está dividido em duas partes: Criação dos componentes e a Criação dos métodos para salvá-los e carregá-los no form.

1. Criação dos componentes

    Abra o Delphi e no form inicial adicione a este um ToolBar. A figura abaixo contém o layout de como está o meu form.

 

    Na figura acima os 5 primeiros botôes adicionam Edit, ComboBox, Button, Label e Memo. Os botões Save e Load servem para carregar e gravar as características dos objetos que foram adicionados. O botão Drag quando selecionado ativa o Drag in Drop de componentes.

1.1 Registrando as Classes:

    Para criar componentes dinâmicos você primeiro precisará registrar as classes que você irá trabalhar na sua aplicação. Para isso adicione o código abaixo na sessão initialization do seu form.

initialization
  RegisterClasses ([TEdit, TComboBox, TButton, TLabel, TMemo]);

1.2 Declarando um novo Tipo

  Para que você possa passar uma classe como parâmetro para uma procedure ou function você precisará usar o operador class of. Uma forma de não precisarmos ficar adicionando esse operador como parâmetro aos nosso método é definindo um novo tipo. Veja o código abaixo:

type
  TComponentClass = Class of TComponent;

    Agora já poderemos passar qualquer classe filha de TComponent como parâmetro para o nosso método que será implementado logo em seguida.


1.3 Criando um método para criar componentes

    Para não ficarmos com um código redundante em cada botão do nosso projeto, vamos centralizá-lo numa rotina chamada AddComponent. Essa rotina tem dois parâmetros: A classe e a posição X,Y onde o objeto deverá ser criado.

function AddComponent(BaseClass: TComponentClass; p: TPoint): TComponent;
begin
  result := BaseClass.Create(self);

  if result.InheritsFrom(TWinControl) then
    begin
    with TWinControl(result) do
      begin
      Parent  := Self;
      Left    := p.X;
      Top     := p.Y;
      Visible := True;
      Hint    := result.Name;
      ShowHint:= true;
      end;
    end
  else if result.InheritsFrom(TGraphicControl) then
    begin
    with TGraphicControl(result) do
      begin
      Parent  := Self;
      Left    := p.X;
      Top     := p.Y;
      Visible := True;
      Hint    := result.Name;
      ShowHint:= true;
      end;
    end;
end;

1.4 Definindo o local onde o objeto será criado e tratando o DragMode

    Essa nova rotina simplesmente tem a funcionalidade de retornar um Registro do tipo TPoint. Ela está fixando as posições X e Y como 10 e 50;

function GetCursor: TPoint;
begin
  result.X := 10;
  result.Y := 50;
end;

    O próximo passo é verificar se o botão Drag foi pressionado. Dependo do estado desse botão iremos ativar ou não o evento de arrastar e soltar objetos no form. A função abaixo devolve um valor do Tipo TDragMode de acordo com o estado do botão

function getDragMode: TDragMode;
begin
  if ButtonDrag.Down then
    result := dmAutomatic
  else
    result := dmManual;
end;

    Por último temos que preparar o nosso formulário para os eventos de arrastar e soltar. Adicione o código abaixo ao evento DragDrop do seu form.

procedure FormDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  if Source.InheritsFrom(TWinControl) then
    begin
    TWinControl(Source).Left := x;
    TWinControl(Source).Top  := y;
    end
  else if Source.InheritsFrom(TGraphicControl) then
    begin
    TGraphicControl(Source).Left := x;
    TGraphicControl(Source).Top  := y;
    end;
end;

  E ao evento DragOver o código

procedure FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := true;
end;

1.5 Implementando as rotinas Edit, Memo, Label, Button e ComboBox

  A última etapa é implementar os eventos associados aos botões do nosso formulário. Para isso adicione o código abaixo para cada Evento OnClick .

procedure ButtonEditClick(Sender: TObject);
begin
  TEdit(AddComponent(TEdit, GetCursor)).DragMode := getDragMode;
end;

procedure ButtonComboClick(Sender: TObject);
begin
  TComboBox(AddComponent(TComboBox, GetCursor)).DragMode := getDragMode;
end;

procedure ButtonButtonClick(Sender: TObject);
begin
  with TButton(AddComponent(TButton, GetCursor)) do
    begin
    DragMode := getDragMode;
    Caption  := 'Button';
    end;
end;

procedure ButtonLabelClick(Sender: TObject);
begin
  with TLabel(AddComponent(TLabel, GetCursor)) do
    begin
    DragMode := getDragMode;
    Caption  := 'Label';
    end;
end;

procedure ButtonMemoClick(Sender: TObject);
begin
  TMemo(AddComponent(TMemo, GetCursor)).DragMode := getDragMode;
end;


1.6 Passo final - ativando e desativando o Drag in Drop

    Após criar os objetos, você poderá desativar o DragDrop dos objetos por meio do método abaixo

procedure SetDragMode(dm: TDragMode);
var
  i: integer;
begin
  for i := 0 to componentcount - 1 do
    begin
    if (components[i] is TEdit) then
      (components[i] as TEdit).DragMode := dm;

    if (components[i] is TComboBox) then
      (components[i] as TComboBox).DragMode := dm;

    if (components[i] is TButton) then
      (components[i] as TButton).DragMode := dm;

    if (components[i] is TLabel) then
      (components[i] as TLabel).DragMode := dm;

    if (components[i] is TMemo) then
      (components[i] as TMemo).DragMode := dm;
    end;
end;

    No evento OnClick do botão Drag acrescente o código

procedure ButtonDragClick(Sender: TObject);
begin
   SetDragMode(getDragMode);
end;

Execute o programa e tente criar e arrastar alguns objetos. Essa é a tela final do sistema em execução



O fonte do projeto está em anexo.
Até a próxima.
Abaixo o link para a parte final