Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Lasso zum Auswählen mehrerer Objekte


Marco D. - Mi 21.09.05 16:04
Titel: Lasso zum Auswählen mehrerer Objekte
Wie kann man so ein Lasso zum Auswählen mehrerer Objekte realisieren? Ein Beispiel wäre, wenn man im Explorer die linke Maustaste gedrückt halt und die Maus bewegt um mehrere Dateien auszuwählen. Ich will prüfen welche Checkboxen im Lasso drinne sind und dann enabled auf true setzen. :gruebel:


arcardia - Mi 21.09.05 16:20

mmmhh...
um das zu erreichen müsstest du beim MouseDown
erstmal die X,Y der Mauskoordinaten merken

Lässt der User die Maustaste dann los
dann kannste ein Rechteck ermitteln
das der Markierung entspricht

anschliessend müsste man dann die Komponenten durchgehen
und gucken ob diese vom Top,Left Werten her in das
ausgewählte Rechteck passen würden


Marco D. - Mi 21.09.05 17:18
Titel: Lasso
Das könnte man so machen. Kannste das vielleicht mal an nem kleinen Beispiel näher erläutern? Danke Koller :)


arcardia - Mi 21.09.05 17:48

also fürs grobe in etwa:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
Private Variablen:
  AnchorX, AnchorY, CurX, CurY: Integer;
  Bounding : Boolean;



// Diese Procedure guckt welche Checkbox in dem Bereich des Rechtecks war
// und setzt den Status auf Checked
procedure TForm1.CheckBox;
begin

  If (CheckBox1.Left>=AnchorX) and
     (CheckBox1.Top>=AnchorY) and
     (CheckBox1.Top+CheckBox1.Height<=CurY) and
     (CheckBox1.Left+CheckBox1.Width<=CurX) then CheckBox1.Checked := True;

  If (CheckBox2.Left>=AnchorX) and
     (CheckBox2.Top>=AnchorY) and
     (CheckBox2.Top+CheckBox2.Height<=CurY) and
     (CheckBox2.Left+CheckBox2.Width<=CurX) then CheckBox2.Checked := True;

end;



// Die Maus wird gedrückt - Wir beginnen Rahmen zu malen
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  AnchorX := X;
  CurX := X;
  AnchorY  := Y;
  CurY := Y;
  Bounding := True;
end;


// wir malen hier das Rechteck während bewegung..
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 if Bounding then begin
    Canvas.Pen.Mode := pmNot;
    Canvas.Pen.Width := 2;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
    CurX := X;
    CurY := Y;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
  end;
end;


// Die Maus wird in der Form losgelassen...
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Bounding then begin
    Bounding := False;
    Canvas.Pen.Mode := pmNot;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
    CheckBox;  // <- Diese Procedure guckt was Sache ist !!!!....
  end;
end;




! Achtung
Du musst in dem Beispiel von mir
das Rechteck beginnend von oben links nach unten rechts zeichnen

sonst musst du noch in CheckBox
die beiden X,Y werte vertauschen


Die Checkboxen müssen komplett umrandet werden
also nicht nur halb drüberziehen , sondern den Rahmen
grosszügig ziehen ;)


Wenn du allerdings sehr viele Checkboxen hast
würde ich nach diesen mit FindComponent suchen
oder evtl. gleich auf die VirtualtreeView Komponente
ausweichen , dort kannste genau wie im Explorer
Eintrage mit einer Checkbox versehen und durch
Rahmen ziehen die Einträge auswählen

so long...

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt


Marco D. - Mi 21.09.05 20:04
Titel: Lasso
Hey!

Danke für deinen ausführlichen Tipp. Auf den ersten Blick überfordert mich das aber ich werd mich mal in Ruhe mit beschäftigen. :wink: Das problem bei treeview ist dass die checkboxen eine bestimme Anordnung haben müssen.


Marco D. - Do 22.09.05 08:38
Titel: Lasso
Das Programm funzt, das PRoblem ist halt das wenn man das REchteck von rechts aufzieht dann passiert nix. Könnte man das nicht genauso realisieren nur die Werte irgendwie umdrehen? :gruebel:
hab das prog mal hochgeladen


digi_c - Do 22.09.05 10:31

Ja das könnte man, es gibt auch die nette Funktion PtnInRect() die einem viel Kombinationsarbeit erpspaart ;) und die Kombiniert mit Clientrect.Topleft,BottomRight sollte einiges erleichtern :D

Für die Auswahl nimm am besten das Windowsstandartauswahlrechteck aka "Ameisenauswahl"


arcardia - Do 22.09.05 17:57

Hab das ganze mal etwas angepasst
siehe Anhang


digi_c - Fr 23.09.05 08:27

Wenn du von oben rechts nach unten links gehst, dann funzt es nicht.
Das Auswahlrechteckt ist nciht Standartkonform, keine Ameisenlinie ;)

Das Verhalten orientiert sich aber nicht am MS Standart oder war das mit den Checkboxen wirklich nur ein Beispiel?
Was willst du denn konkret umsetzen?


Marco D. - Fr 23.09.05 14:36
Titel: Lasso
Also ich habe 17 Checkboxen. Die haben eine bestimme Anordnung was sehr wichtig ist. Das Prog con acardia entspricht genau dem was ich suche, aber :wink: mein Problem ist dass meine checkboxen in einem Panel liegen und deswegen die canvas-methode nicht sichtbar ist. Nun könnte man sagen dann nimm halt die checkboxen aus dem panel raus aber das ist nicht möglich! (viel zu großer Aufwand).
Was tun?


arcardia - Fr 23.09.05 16:07

Du packst einfach eine PaintBox Komponente in das Panel
(quasi als Hintergrund)

und nimmst dann halt nicht Form1.Mousedown
sondern PaintBox.Mousedown...

(Es gäbe noch die Möglichkeit dem Panel ein
Canvas aufzuzwängen aber die Sache mit der
Paintbox dürfte entschieden leichter sein)

Greetz


Marco D. - Di 27.09.05 11:28
Titel: Lasso
Ich hab das ganze mal angepasst nur werden die checkboxen nicht mehr verändert :bawling:


arcardia - Di 27.09.05 23:34

Du musst nur



Delphi-Quelltext
1:
2:
   // Hier ALLE Checkboxen auf der Form suchen...
   for i := 0 to form1.panel1.ComponentCount - 1 do begin



ändern in



Delphi-Quelltext
1:
2:
   // Hier ALLE Checkboxen auf der Form suchen...
   for i := 0 to Form1.Panel1.ControlCount - 1 do begin


Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt


Marco D. - Mo 10.10.05 19:09
Titel: Box
Geht das auch irgendwie von unten rechts und oben links?


Amateur - Mo 10.10.05 19:15

hab jetzt keinen code und weiß net ob das klappt aber rein logisch betrachtet muste doch nur überprüfen ob der start x wert größer oder kleiner als der end x wert ist und dann wenn der end x wert kleiner ist die beiden werte vertauschen. das gleiche nochmal mit den y werten. sollte man doch mit 2 if then abfragen realisieren können. (hab mir jetzt net eure progs geladen, nur wenn man die x und y werte einfach speichert und mit ihnen nen rechteck macht sollte man so auch von rechts unten und so ziehen können)