Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Button Image bei Drag & Drop (https://www.delphipraxis.net/177876-button-image-bei-drag-drop.html)

Natcree 3. Dez 2013 11:32

Button Image bei Drag & Drop
 
Hallo Ich will einen TButton mit Drag & Drop auf der Form verschieben.

Was auch kein Problem ist.

Nun soll aber beim Drag over Der Button sichtbar bleiben ? Habe mir schon vieles angesehen.

Kann mir jemand weiter helfen Hier mal mein Code

Delphi-Quellcode:
procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := Source is TButton;
  end;

procedure TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
    if Source is TButton then
    begin
      TButton(Source).Left := X;
      TButton(Source).Top := Y;
    end;
end;

Volker Z. 3. Dez 2013 21:52

AW: Button Image bei Drag & Drop
 
Hallo,

Zitat:

[...] Nun soll aber beim Drag over Der Button sichtbar bleiben [...]
Wenn Du es unbedingt mit Drag & Drop machen möchtest, dann hast Du ein kleines Problem: Solange der Mauszeiger auf Deinem Control ist gibt es kein "Drag". Erst wenn der Mauszeiger außerhalb des Controls ist kann Du mit DragOver darauf reagieren und dann musst Du den Button dem Mauszeiger "hinterherziehen".
Funktionieren würde es z. B. so:
Delphi-Quellcode:
TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure FormDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
  private
    { Private-Deklarationen }
    FDragButton : TButton;
  public
    { Public-Deklarationen }
  end;

procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Sender is TButton) and (Button = mbLeft) then
    begin
      FDragButton := TButton (Sender);
      FDragButton.BeginDrag (False, 4)
    end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.DragMode := dmManual; // oder im OI zuweisen
  FDragButton := nil
end;

procedure TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  FDragButton := nil
end;

procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
var
  r : TRect;
begin
  Accept := Source = FDragButton;
  if Accept then
    begin
      r := FDragButton.BoundsRect;
      if X < r.Left - 1 then
        FDragButton.Left := X + 1
      else
        if r.Right < X then
          FDragButton.Left := X - r.Right + r.Left;

      if Y < r.Top - 1 then
        FDragButton.Top := Y + 1
      else
        if r.Bottom < Y then
          FDragButton.Top := Y - r.Bottom + r.Top
    end
end;
Eine andere Variante: Anstatt Drag & Drop verschiebe den Button über OnMouseMove. Das funktioniert dann z. B. so:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    FCursorPos : TPoint;
    FDragButton : TButton;
  public
    { Public-Deklarationen }
  end;

implementation

{$R *.dfm}

procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Sender is TButton) and (Button = mbLeft) then
    begin
      FCursorPos := Point (X, Y);
      FDragButton := TButton (Sender)
    end
end;

procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if Assigned (FDragButton) then
    begin
      if Screen.Cursor <> crDrag then
        Screen.Cursor := crDrag;

      FDragButton.Left := FDragButton.Left + X - FCursorPos.X;
      FDragButton.Top := FDragButton.Top + Y - FCursorPos.Y
    end
end;

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FDragButton := nil;
  Screen.Cursor := crDefault
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FDragButton := nil
end;
[EDIT]
BTW: Eine weitere Variante findest Du hier (wurde von Furtbichler bei einem ähnlichen Thema gepostet).
[/EDIT]

Gruß

himitsu 3. Dez 2013 22:01

AW: Button Image bei Drag & Drop
 
Ich weiß leider nicht mehr genau wie, aber es giebt auch eine Möglichkeit das "Verschieben", wie im FormDesigner, im eigenen Programm zu verwenden.
Man muß da nur irgendwas im OnMouseDown machen.

Eventuell mal hier oder auf www.torry.net nach "Komponente verschieben", oder Dergleichen, suchen.

Natcree 3. Dez 2013 22:48

AW: Button Image bei Drag & Drop
 
Ich Danke euch Habe es so gemacht
Delphi-Quellcode:
var
flastpos: TPoint;
Delphi-Quellcode:
procedure TForm1.ButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
r:TRect;
begin
  if [ssLeft,ssRight]*Shift=[ssLeft,ssRight] then exit;
  with TControl(Sender) do
  begin
    flastpos:=ClientToScreen(Point(x,y));//um sicherzustellen, daß der Button auf dem Panel bleibt
    r:=Parent.ClientRect;
    r.TopLeft:=Parent.ClientToScreen(r.TopLeft);
    r.BottomRight:=Parent.ClientToScreen(r.BottomRight);
    inc(r.Left,x);
    dec(r.Right,Width-x);
    inc(r.Top,y);
    dec(r.Bottom,Height-y);
    ClipCursor(@r);
  end;
end;

procedure TForm1.ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
var
mpos:TPoint;
begin
  if [ssLeft,ssRight]*Shift=[] then exit;
  with TControl(Sender) do
  begin
    mpos:=ClientToScreen(Point(x,y));
    x:=mpos.x-flastpos.x;
    y:=mpos.y-flastpos.y;
    SetBounds(Left+x,Top+y,Width,Height);
    flastpos:=mpos;
  end;
end;

procedure TForm1.ButtonMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
  if [ssLeft,ssRight]*Shift<>[] then exit;
  ClipCursor(nil);
end;

Sir Rufo 4. Dez 2013 00:12

AW: Button Image bei Drag & Drop
 
Eine globale Variable ...

Für alle die diesen Thread lesen gilt wie immer bei globalen Variablen "Don't do that at home!"
(auf deutsch "Bitte nicht nachmachen!")

Falls die Frage aufkommt, wie es richtig geht, einfach nachfragen, wir - speziell auch ich - geben gerne Antwort.

Sir Rufo 4. Dez 2013 01:07

AW: Button Image bei Drag & Drop
 
Merci und danke für den Jungspund :mrgreen:

Bei einer globalen Variablen hat sich der Ersteller zu 80% keine Gedanken zum Kontext gemacht (wozu gehört diese Variable - ach, zur Instanz) und zu 20% Faulheit, weil er keine Singleton-Klasse, bzw. Default-Klasse oder simple Funktion erstellen/erzeugen möchte.

Und aus dem Kindergarten kenne ich noch die Sprüche wie "Aber der Klaus hat auch..."

Nur weil Borland das u.a. mit dem RAD-Ansatz vormacht, muss man nicht wie die Lemminge hinterher.

Auch wenn da was in Büchern steht ... Papier ist und war schon immer geduldig.

Es zählt einfach nur ein robustes Programmdesign, das bekommt man nicht geschenkt und eine globale Variable ist nicht robust.

Volker Z. 4. Dez 2013 01:13

AW: Button Image bei Drag & Drop
 
Hallo,

Zitat:

Die 'kleine' Problematik, das eine globale eine lokale überdecken kann ist mir schon bewußt...
Offenbar nicht! Wenn, dann verschattet eine lokale Variable eine globale Variable und nicht umgekehrt.
Delphi-Quellcode:
implementation

var
  aVar : Integer;

procedure DoSomething;
var
  aVar : string;
begin
  aVar := 'Hallo Welt';
  WriteLn (aVar); // Output 'Hallo Welt' nicht 42
  [...]
end;

begin
  aVar := 42;
  DoSomething
end.
Gruß

Sir Rufo 4. Dez 2013 01:46

AW: Button Image bei Drag & Drop
 
Zitat:

Zitat von Smut (Beitrag 1238437)
Hi und danke für die Antwort...

Hier nur mal mein musikalischer Geburtstagsgruß:
http://www.youtube.com/watch?v=_2BqiipGKNA
Ich steh ja soooo auf Musik... wird Dir wohl nicht gefallen... na egal.

Da muss ich dich leider enttäuschen ...

Tubular Bells I, II, III, Orchestral, Millennium sowie die BBC Aufnahme der Tubular Bells I (Video) sind seit Urzeiten ein fester Bestandteil meiner Audiothek (neben Hergest Ridge, Amarok, etc.)

Zitat:

Zitat von Smut (Beitrag 1238437)
Zu den globalen Variablen: Angenommen, ich nehme EINE Globale Variable,nenne die z.B. MasterLang und bin so in der Lage, Datenbankeingaben mehrsprachig zu gestalten, was ist daran verkehrt?

Nimm einfach eine Funktion und du kannst den Zugriff darauf besser kontrollieren (threadsafe)

Also statt
Delphi-Quellcode:
interface

var
  MasterLang : string;
einfach
Delphi-Quellcode:
interface

function MasterLang : string;

implementation

var
  _MasterLang : string;

function MasterLang : string;
begin
  if _MasterLang = '' then
    _MasterLang := GetMasterLang;
  Result := _MasterLang;
end;
Will ich das threadsafe haben, kein Problem, einfach eine TCriticalSection rein.

Will ich das aber auch noch speichern/laden, dann kommt das in eine Klasse (z.B. TApplicationLayer) und die Klasse speichert und lädt die Einstellungen.

Der Zugriff auf diese Klasse erfolgt analog über eine Funktion.

Wie schon gesagt, es ist eigentlich nur Faulheit - die sich meistens irgendwann rächt.
Ich bin lieber am Anfang rege und lege mich später entspannt zurück (z.B. ein kleines Notfallkassensystem mit automatischem Datenaustausch an eine WaWi läuft seit ca. 8 Jahren fehlerfrei in der Version 1.0.1 - ein Ausgabe-Fehler beim Nachbon - und häufiger im Einsatz als ursprünglich geplant - wir haben doch noch eine Kasse)

Schlimm ist erst mal nix, schlimm wird es aber auch schon von alleine und man muss es nicht schon vom Design an schlimm gestalten ;)

DeddyH 4. Dez 2013 07:14

AW: Button Image bei Drag & Drop
 
Ich vermute, himitsu hat das hier gemeint:
Delphi-Quellcode:
procedure TFormTest.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  SC_DRAGMOVE = $F012;
begin
  if (ssLeft in Shift) and (Sender is TWinControl) then
    begin
      ReleaseCapture;
      TWinControl(Sender).Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
    end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz