Fórum Dragdrop #271364

08/03/2005

0

Bom Dia,

Estou com um pouco de dificuldade na implementação de um gerador de relatorios. Este gerador é construido utilizando o quickreport porem o mesmo deve ter a possibilidade de selecionar varios componentes, redimensiona-los e arrasta-los. A minha maior dificuldade é justamente implementar os recursos de arrastar e soltar com mais de um componente selecionado usando o dragdrop, alquem conhece uma forma mais pratica de se executar está ação. Não posso simplesmente alterar as propriedades left, top dos meus componentes pois isto faz a tela piscar.

Para produzir o efeito de seleção dos objetos estou desenhndo varios paineis pintados de preto ao redor dos componentes selecionados. Alquem conhece uma maneira mais elegante de fazer isto tambem?


Leads

Leads

Responder

Posts

08/03/2005

Marcelo Saviski

Pra não piscar, talvez vc pudesse fazer assim:

desenhar um retângulo na nova posição aonde o compoennte vai estar, e ó mudar o left e top depois que soltar o mouse, tipo usando essa função que copiei da RxLib, unit VclUtils

procedure DrawInvertFrame(ScreenRect: TRect; Width: Integer);
var
  DC: HDC;
  I: Integer;
begin
  DC := GetDC(0);
  try
    for I := 1 to Width do begin
      DrawFocusRect(DC, ScreenRect);
      InflateRect(ScreenRect, -1, -1);
    end;
  finally
    ReleaseDC(0, DC);
  end;
end;


no onmousedown, vc armazenaria a posição e tamanho dos componentes

var
  Rects: array of TPoint;
  HotSpot: TPoint


no MouseDown, salvaria o tamanho dos componentes selecionados:

SetLength(Rects, NumCompsSelecionado)
HotSpot := Point(X, Y);
for ...   //faz um for em todos os comps selecionados
  with ComponenteSelecionado[X] do
  begin    
    Rects[I] := BoundsRect;
    Rects[I].TopLeft := ClientToScreen(Rects[I].TopLeft);
    Rects[I].BottomRight := ClientToScreen(Rects[I].BottomRight);
    DrawInvertFrame(Rects[I], 3);
  end;

end;

depois no MouseMove, vc movimenta os valores do array pos, mas não move os componentes, e chama o DrawInvertFrame pra desenhar um retângulo na tela, no lugar para onde os componentes estariam sendo movidos:

if ssLeft in Shift then // se o botão esquerdo do mouse está pressionado
  for I :- Low(Rects) to High(Rects) do
  begin  
    DrawInvertFrame(Rects[I], 3);
    //move de acordo com a posição do mouse
    Rects[I].Left := Rects[I].Left + X - HotSpot.X;
    Rects[I].Right:= Rects[I].Right+ X - HotSpot.X;
    Rects[I].Top := Rects[I].Top + X - HotSpot.X;
    Rects[I].Bottom := Rects[I].Bottom + X - HotSpot.X;
    DrawInvertFrame(Rects[I], 3);
  end;


o DrawInvertFrame inverte as bordas do retangulo passado como parametro, então depois tem que inverter denovo pra voltar ao normal, que é feito no 1º no MouseMove

e no MouseUp, tem que pegar os novos valores do array rects e passar para os componentes:

for I :- Low(Rects) to High(Rects) do
  with Rects[I] do
    ComponentesSelecionados[I].SetBounds(Left, Top, Right - Left, Bottom - Top);


Não garanto que isso irá funcionar já de 1º :) :P , eu não testei, escrevi o código no fórum mesmo, então teste e diga se conseguiu fazer funcionar.

acho que isso não resolve todo o seu problema, mas assim não pisca e da uma cara melhor.


Responder

Gostei + 0

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

Aceitar