Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - vereinfachtes coding gesucht


ALF - Di 13.10.09 16:32
Titel: vereinfachtes coding gesucht
Hi, kann mir jemand sagen wie ich es evtl einfacher hinbekomme, das man nicht,(in diesem Beispiel 4x),
immer das selbe schreiben muss bzw. bei Veränderungen die mann in einem macht, nun auch bei den anderen source auch zu machen.
Fehler sind da nicht mehr ausgeschlossen bei den schlechten Codestill!! "Eigenkritik" :roll:

Ich gebe mal einen kleinen Einblick was ich meine:


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:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
    if names = 'ScrollBox1' then
    begin
         if (exnames = ''then
         PlayList1.Add(dateiname)
        else
          PlayList1.Insert(strtoint(exnames)-1+i, dateiname);

         names:='PlayList1';

    end
    else
    if names = 'ScrollBox2' then
    begin

        if (exnames = ''then
          PlayList2.Add(dateiname)
        else
          PlayList2.Insert(strtoint(exnames)-1+i, dateiname);

        names:='PlayList2';
    end
    else
    if names = 'ScrollBox3' then
    begin

        if (exnames = ''then
          PlayList3.Add(dateiname)
        else
          PlayList3.Insert(strtoint(exnames)-1+i, dateiname);

        names:='PlayList3';
    end
    else
    if names = 'ScrollBox4' then
    begin

        if (exnames = ''then
          PlayList4.Add(dateiname)
        else
          PlayList4.Insert(strtoint(exnames)-1+i, dateiname);

        names:='PlayList4';
    end;
    StrDispose(Dateiname);

  end;

  DragFinish(Msg.WParam);

  if names = 'PlayList1' then
  begin

    PlayList1.SaveToFile(PathProjekt+names+'.lst');

    for i := 0 to playlist1.Count -1 do
    begin
       PlayGauge := TGaugeCaption.create(ScrollBox1);
       with PlayGauge do
       begin
          Name := 'ScrollBox1_'+inttostr(i+1);
          Caption := ExtractFileName(playlist1.Strings[i]);

          backColor := clInfoBk;
          OnMouseDown := form1.ScrollBox1MouseDown;

          PopupMenu := form1.PopupMenu1;
          OnClick := Form1.ScrollBox1Click;
          Top := (i)*(playgauge.Height+5);
          Parent := ScrollBox1;
          show;
       end;
    end;
  end
  else
  if names = 'PlayList2' then
  begin
    label1.caption:=names;
    PlayList2.SaveToFile(PathProjekt+names+'.lst');
    for i := 0 to playlist2.Count -1 do
    begin
       PlayGauge := TGaugeCaption.create(ScrollBox2);
       with PlayGauge do
       begin
          Name := 'ScrollBox2_'+inttostr(i+1);
          Caption := ExtractFileName(playlist2.Strings[i]);

          backColor := clInfoBk;
          OnMouseDown := form1.ScrollBox1MouseDown;

          PopupMenu := form1.PopupMenu1;
          OnClick := Form1.ScrollBox1Click;
          Top := (i)*(playgauge.Height+5);
          Parent := ScrollBox2;
          show;
       end;
    end;
  end
  else
  if names = 'PlayList3' then
  begin
    PlayList3.SaveToFile(PathProjekt+names+ '.lst');
    for i := 0 to playlist3.Count -1 do
    begin
       PlayGauge := TGaugeCaption.create(ScrollBox3);
       with PlayGauge do
       begin
          Name := 'ScrollBox3_'+inttostr(i+1);
          Caption := ExtractFileName(playlist3.Strings[i]);

          backColor := clInfoBk;
          OnMouseDown := form1.ScrollBox1MouseDown;

          PopupMenu := form1.PopupMenu1;
          OnClick := Form1.ScrollBox1Click;
          Top := (i)*(playgauge.Height+5);
          Parent := ScrollBox3;
          show;
       end;
    end;
  end
  else
  if names = 'PlayList4' then
  begin
    PlayList4.SaveToFile(PathProjekt+names+ '.lst');
    for i := 0 to playlist4.Count -1 do
    begin
       PlayGauge := TGaugeCaption.create(ScrollBox4);
       with PlayGauge do
       begin
          Name := 'ScrollBox4_'+inttostr(i+1);
          Caption := ExtractFileName(playlist4.Strings[i]);

          backColor := clInfoBk;
          OnMouseDown := form1.ScrollBox1MouseDown;

          PopupMenu := form1.PopupMenu1;
          OnClick := Form1.ScrollBox1Click;
          Top := (i)*(playgauge.Height+5);
          Parent := ScrollBox4;
          show;
       end;
     end;
  end;


Wie gesagt, das setzt sich bei dragdrop und anderen proceduren so fort.
Nun Währe es schön wenn mir jemand bischen helfen würde das zu vereinfachen. :wink:
Habe natürlich selbst auch schon probiert, aber keine Ideen mehr(mit eigener func. Procedure usw.)
Im Enteffekt steht dort das selbe wieder drin wie gezeigt. :cry:

Gruss
ALF


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Di 13.10.2009 um 18:22


Hugo343 - Di 13.10.09 16:52

Ich könnte vielleicht ein Teilproblem lösen:
Du fragst ja immer nach 'Scrollbar1','Scrollbar2' usw. Das könntest du ja auch durch eine For-Schleife ersetzen:


Delphi-Quelltext
1:
2:
3:
4:
for I := 1 to 4 begin // die Zahl 4 ist nur ein Beispiel
  if names='Scrollbar'+inttostr(i) then
  // ...
end;


Oder muss das zwingend mit ELSE sein?
Wär nur so ne Idee :D .


ALF - Di 13.10.09 17:04

Danke für die Antwort.
Hilft aber nicht weiter, weil danach ja doch wieder die if abfragen kommen!!

Problem ist ja nicht das sondern, die jeweilige Zuweisungen!!!


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
PlayGauge := TGaugeCaption.create(ScrollBox1); //<- Scrollbox1

PlayGauge := TGaugeCaption.create(ScrollBox2); //<- ScrollBox2

oder...

 Parent := ScrollBox1;  //hier auch 
 Parent := ScrollBox2;  //hier auch

usw.
....


Alf


martin300 - Di 13.10.09 17:12

Die Lösung dafür sind Methoden. Dort schreibst den Code 1x hin und rufst nur noch die Methode mit entsprechenden Parameter auf.


ALF - Di 13.10.09 17:23

Thx

muss aber offen gestehen, hab mit methoden noch nie gearbeited.
Die delphi hilfe ist da auch nicht sehr hilfreich!
Für meinen Fall, mhh.. :roll: bischen code :?: , währe sehr hilfreich!??

Gruss
Alf


Hugo343 - Di 13.10.09 17:40

Oh doch die Delphi Hilfe gibt Antworten! ^^ Suchbegriff: "Methoden" = (ich zitiere) "Eine Methode ist eine Prozedur oder Funktion, die zu einer bestimmten Klasse gehört. Daher wird beim Aufruf einer Methode das Objekt (bzw. bei einer Klassenmethode die Klasse) angegeben, mit dem die Operation durchgeführt werden soll. SomeObject.Free ruft beispielsweise die Methode Free in SomeObject auf.". Ich denke wenn ich

Delphi-Quelltext
1:
2:
3:
procedure TForm1.OnCreate;
//oder weißnich ob das geht
function TForm1.blaaa

habe ist das eine Methode. Für mich wäre eine Prozedur hier ganz nett ^^. <--- lululu-ich-noob ^^


FinnO - Di 13.10.09 17:46

so kannst du eigene Methoden deklarieren:

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:
interface
type TForm1=class(TForm) 
  private

  public
    function MeineMethode(MeineZahl: Integer; ...;Variable: Typ) : Boolean //oder anderer Rückgabewert.
end;

implementation

function TForm1.MeineMethode(MeineZahl: Integer; ...;Variable: Typ) : Boolean;
begin
  if MeineZahl = 1 then
  begin
    doSth;
    Result := False;
  end;
  
  Result := Variable = Value;
end;

// aufruf im Programm:

TForm1.Btn1OnClick(Sender: TObject); 
begin
  MeineMethode(23, Value);
end;


ALF - Di 13.10.09 18:16

Sorry !!!
Glaube ich wittere ein Missverständnis! oder ich stehe neben mir :?

Es geht nicht um selbst erstellte Funktionen oder Proceduren. Das ist ja nicht das Problem!

Mir geht es, darum das ganze zu vereinfachen!
Mein Problem dabei ist, das man bei der Zuweisung : z.B.

Delphi-Quelltext
1:
2:
3:
4:
  PlayGauge := TGaugeCaption.create(ScrollBox2); //hier kann auch ScrollBox1 oder ScrollBox3 sein
.....
.....
  Parent := ScrollBox2; //hier das selbe

Wobei:
Scrollbox1 -4 keine Variable sondern Komponente ist.
An den Stellen wo das hin muss, wie im code gezeigt, kann man ebend keine Variable einsetzen!
Es sei den es gibt dafür auch andere Möglichkeiten, aber welche!?
denn dann währe alles leicht zu coden und man braucht das ganze nur einmal.
Hab aber keine idee!! :cry: sorry.

Alf


Apuch - Di 13.10.09 18:42

Um anhand des Objektnamens den die Komponente zu finden, gibts die Prozedur FindComponent. Einfach mal in die Hilfe schauen. Um alles etwas eleganter zu gestalten, kann man das ganze ja in ein Feld ablegen...

In Etwa so:


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:
...
interface
type TForm1=class(TForm) 
  private
    MyScollBoxes : array [1 .. 4of TScrollBox;
    ScrollBoxNames : TStringList;
    PlayLists : array [1 .. 4of TPlayList;
    
...

procedure TForm1.FormCreate(Sender: TObject);
var 
  i: integer;
begin
  ScrollBoxNames := TStringList.Create();
  for i := 1 to 4 do
  begin
    ScrollBoxNames.Add('PlayList'+inttostr(i));
    PlayLists[i] = FindComponent('PlayList'+inttostr(i));
    MyScollBoxes[i] := FindComponent('ScrollBox'+inttostr(i));
  end;
end

// und dann dein Code aus dem ersten Beitrag
procedure ... 
var index : integer;
begin
  if not ScrollBoxNames.Find(names, index) then
    exit;
  if (exnames = ''then
    PlayLists[index].Add(dateiname)
  else
    PlayLists[index].Insert(strtoint(exnames)-1+i, dateiname);
    names := PlayLists[index].Name;
  end;
  
  DragFinish(Msg.WParam);

  PlayLists[index].SaveToFile(PathProjekt+names+'.lst');

  for i := 0 to PlayLists[index].Count -1 do
  begin
    PlayGauge := TGaugeCaption.create(ScrollBoxes[index]);
    with PlayGauge do
    begin
      Name := ScrollBoxes[index].Name + '_' + inttostr(i+1);
      Caption := ExtractFileName(playlists[i].Strings[i]);

      backColor := clInfoBk;
      
      // Das hier muss dan noch irgendwie ...
      OnMouseDown := form1.ScrollBox1MouseDown;
      PopupMenu := form1.PopupMenu1;
      OnClick := Form1.ScrollBox1Click;
      Top := (i)*(playgauge.Height+5);
      Parent := ScrollBoxes[index];
      show;
   end;
  end;

end;


ALF - Di 13.10.09 19:04

Hi, danke, danke danke für die vielen Hinweise!!!
Aber es gibt doch ein Missverständnis :eyecrazy:
Die 4 fachen if Anweisungen, also immer der gleiche Inhalt kommen ja nur zustande
zB.

PlayGauge := TGaugeCaption.create(ScrollBox2]) //hier kann auch ScrollBox1 oder ScrollBox3 sein
...
Parent := ScrollBox2; //hier auch
usw.

dadurch habe ich das 4x drin. nicht, weil ich nicht weis wie man eine funktion oder procedure schreibt
oder Findcomponente nicht kenne!
Die Frage ist also:

Wie kann ich es machen das:
PlayGauge := TGaugeCaption.create( VARIABEL IST)
oder
Parent := VARIABEL IST ist. da man dort keine strings einfügen kann
Das ist mein Problem!! :autsch: :autsch: :autsch:

ALF


Apuch - Di 13.10.09 19:17

Schau in die OnlineHilfe, dann kennst du FindComponent ;).

Anhand des Names (woher du den auch immer bekommst) wird der Index festgestellt. Anhand des Indexes können die Komponenten aus einer hinterlegten Liste ausgewählt werden.

In meinem Code hab ich die in ein Array abgelegt. Find den Zugriff über diesen Umweg eleganter. In der FormCreate-Methode wird das Array befüllt. in deinem Code steht dann:


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:
// vorher
if names = 'ScrollBox1' then
  parent := ScrollBox1;
  PlayGauge := TGaugeCaption.create(ScrollBox1);
else if names = 'ScrollBox2' then
  parent := ScrollBox2;
  PlayGauge := TGaugeCaption.create(ScrollBox2);
else if names = 'ScrollBox3' then
  parent := ScrollBox3;
  PlayGauge := TGaugeCaption.create(ScrollBox3);
else if names = 'ScrollBox4' then
  parent := ScrollBox4;
  PlayGauge := TGaugeCaption.create(ScrollBox4);
else
  Exit;

/////////////////
//nachher
if not ScrollBoxNames.Find(names, index) then
  exit;

parent := ScollBoxes[index];
PlayGauge := TGaugeCaption.create(ScrollBoxes[index]);


ALF - Di 13.10.09 19:22

sorry user profile iconApuch

hab nicht alles gesehen nice.
Werd mich gleich dranmachen das umzucoden und zu sehen wo ich das alles einsetzen kann.
Gibt ja noch mehr code wo das ganze 4x in abgewandelter if Anweisung passiert.

THX user profile iconApuch

ach so wo die Strings herkommen!?

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:
procedure TForm1.WMDROPFILES(var Msg: TMessage);
var
  i, anzahl, size: Integer;
  //Dateiname: PChar;
  names, exnames: string;

begin

  inherited;

  anzahl := DragQueryFile(Msg.WParam, DF_NUMBEROFFILES, Dateiname, 255);
  GetCursorPos(pos);
  exnames := copy(FindDragTarget(pos, False).name, 123);
  for i := 0 to (anzahl - 1do
  begin
    names := copy(FindDragTarget(pos, False).name, 010);  //<-- da kommen die names her

    size := DragQueryFile(Msg.WParam, i, nil0) + 1;
    DateiName := StrAlloc(size);
    DragQueryFile(Msg.WParam, i, Dateiname, size);

// und hier werden die ganzen abfragen mit If gemacht

    if names = 'ScrollBox1' then
    begin
         if (exnames = ''then
         PlayList1.Add(dateiname)
        else
          PlayList1.Insert(strtoint(exnames)-1+i, dateiname);

         names:='PlayList1';

    end
    else
    if names = 'ScrollBox2' then
    begin
......
....


usw.

ALF


jaenicke - Mi 14.10.09 01:19

Du bekommst das Control direkt von FindDragTarget geliefert und statt dann direkt damit zu arbeiten nimmst du zuerst davon den Namen und suchst hinterher wieder genau das Control dazu?!?

(Mal abgesehen davon, dass die Bezeichnung der Komponenten nicht besonders aussagekräftig ist. :roll:)


jfheins - Mi 14.10.09 08:43

Ich werfe mal das hier in den Raum:

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:
var
Scrollbox: TScrollbox;
Playlist: TPlaylist;
begin
if names = 'ScrollBox1' then
begin
  Scrollbox := Scrollbox1;
  Playlist := Playlist1;
end
else if names = 'ScrollBox2' then
begin
  Scrollbox := Scrollbox2;
  Playlist := Playlist1;
end
else if names = 'ScrollBox3' then
begin
  Scrollbox := Scrollbox3;
  Playlist := Playlist1;
end
else
  raise EApocalypseException('Something happened that should not be possible. Change the programmer and try again.')

if (exnames = ''then
  PlayList1.Add(dateiname)
else
  PlayList1.Insert(strtoint(exnames)-1+i, dateiname);

GaugeCaption := TGaugeCaption.Create(Scrollbox);


Oder so ... mit Finscomponent könnt eman das am Anfang noch kürzen, aber das mit der variable sollte klar werden ;)


jaenicke - Mi 14.10.09 08:50

Wozu überhaupt sowas oder FindComponent, wenn die Komponente selbst bereits vorhanden ist. Wie gesagt: Es bringt doch nix zuerst den Namen der Komponente zu nehmen und daraus wieder die Komponente zu suchen. :hair:


Apuch - Mi 14.10.09 12:22

Die Komponente selbst ist bekannt. Mit dieser Komponente sind jedoch auch andere Felder verknüpft...(Playlist, Scrollbox, etc.). Vielleicht sollte man die in ein Record packen. Dieses record kommt dann in eine Liste und als Schlüssel nimmt man den Namen^^ Oder gibts unter Delphi sowas wie Userdata? Konnte man nicht tag zum speichern eines Schlüssels missbrauchen?

MfG


ALF - Mi 14.10.09 16:24

Hi,

danke nochmal für die Hinweise! leider funct es doch noch nicht so mit FindComponent!
Was die Komponenten betrifft, hier mal das ganze.
TForm1 <-TForm
-in der Form
GroupBox 1-4 <- TGroupBox
-in der jeweiligen GroupBox dann die
ScrollBox 1-4 <- TscrollBox
-in der jeweiligen ScrollBox die Gauges, sie werden mit DRAGDROP eingefügt,verschoben usw. und werden erst zur Laufzeit erstellt!!!!
PlayGauge 1-x <- TGaugeCaption abgeleited von Tgauge;

PlayList ist klar was die beinhalted
PlayList 1-4 <- TStringlist

Mit Findcomponent geht es nur bedingt da PlayList von TStringList kommt und keine kennung hat demzufolge auch nicht von FindComponent über den Namen gefunden werden kann!
Es sei ich erstelle ein neuen Type von TStringList mit zusatz Methode Name für die Identifikation!!??
OMG...

Ihr seht im Prinzip simple, aber...., wenn man weis wie man die ganzen Abfragen Vereinfachen kann ohne alles 4x zu machen.
Dies ist ja mein Problem!!

Gruss Alf


Apuch - Do 15.10.09 01:02


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:
...

TListItem : record
  GroupBox : TGroupBox;
  ScrollBox : TScollBox;
  PlayList : TStringList;
end;

...

TForm1=class(TForm) 
  private
    MyItems ; array [1 .. 4of TListItem;
    ...

procedure TForm1.FormCreate(Sender: TObject);
var 
  i: integer;
begin
  ScrollBoxNames := TStringList.Create();
  for i := 1 to 4 do
  begin
    MyItems[i].GroupBox := FindComponent('GroupBox' + inttostr(i));
    MyItems[i].ScrollBox := FindComponent('ScrollBox' + inttostr(i));
    MyItems[i].PlayList := TStringList.Create(); // Oder wo immer es kommt
    MyItems[i].ScrollBox.Tag := i; // die magische Zusweisung des Index
  end;

  ...
end;

...

procedure TForm1.WMDROPFILES(var Msg: TMessage);
var
  index, i, anzahl, size: Integer;
  exnames: string;
begin
  inherited;
  
  anzahl := DragQueryFile(Msg.WParam, DF_NUMBEROFFILES, Dateiname, 255);
  GetCursorPos(pos);
  exnames := ???

  for i := 0 to (anzahl - 1do
  begin
    index := FindDragTarget(pos, False).tag; // da haben wir den index
    size := DragQueryFile(Msg.WParam, i, nil0) + 1;
    DateiName := StrAlloc(size);
    DragQueryFile(Msg.WParam, i, Dateiname, size);

    if (exnames = ''then
      PlayList1.Add(dateiname)
    else
      MyItems[index].PlayList.Insert(strtoint(exnames)-1+i, dateiname);
    names := 'PlayList' + inttostr(i);
  end;
  ...

So in etwa. Den Zusammenhang mit FindDragTarget durchsteig ich aus Unkenntniss nicht. Sieht aber allgemein erstmal unsauber in deinen Codxe aus:

Delphi-Quelltext
1:
2:
exnames := copy(FindDragTarget(pos, False).name, 123);
  names := copy(FindDragTarget(pos, False).name, 010);

Durchsteig ich nicht und du in 6 Monaten auch nicht mehr... Das muss irgendwie eleganter gehen. Angefangen damit, das du bessere Namen für deine Komponenten findest. ScollBox ist einfach nicht eindeutig genug. PlayList ein Anfang..

MfG


ALF - Fr 16.10.09 19:10

So hier mal meine Lösung des ganzen!!
Ich weiss es ist nicht der SuperCode!!!
aber er funct und ist nicht mehr so aufwendig wie mein erster! :)
und ich kann nun über den "index" alles weitere im Programm steuern.


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:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
....
....
type
  TForm1 = class(TForm)

...
ScrollBox1: TScrollBox;  //<- ist Standart wenn mann ein Opjekt/komponente auf die Form legt
ScrollBox2: TScrollBox;  // welchen Sinnn macht es dieses zu Ändern in, z.B AblageScrollbox1
ScrollBox3: TScrollBox;  //oder GaugeAblageScrollbox1 etc.
ScrollBox4: TScrollBox;  //es sei denn man erstellt sie selbst, ändert aber an der Aufgabe der Scrollbox nichts
...
protected
      procedure WMDROPFILES(var Msg: TMessage); message WM_DROPFILES;

private
    MyScrollBoxes : array [1 .. 4of TScrollBox;
    ScrollBoxNames : TStringList;
    PlayList : array [1 .. 4of TStringList;

.....
.....

procedure TForm1.FormCreate(Sender: TObject);
var
   j: Integer;
begin
.....
.....
   DragAcceptFiles(Handle, True);
   ScrollBoxNames := TStringList.Create;
   ScrollBoxNames.Add('ScrollBox');     //ein "leerer Eintrag" um mit index 1-4 arbeiten zukönnen
   for j := 1 to 4 do
   begin
      ScrollBoxNames.Add('ScrollBox'+inttostr(j));
      PlayList[j] := TStringList.create;
      PlayList[j].OnChange:=Form1.PlayListChange;
      MyScrollBoxes[j] := TScrollBox(FindComponent('ScrollBox'+inttostr(j)));
   end;

end;

// Die kommende Prozedur benötigt man wenn man per DRAGROP mit den win Explorer arbeited
// Diese Prozedur erkennt nur das Aplikations Handle (also nur dein Fenster (TForm1)
// DragAcceptFiles(Handle, True); <- bezieht sich nur auf deine Applikation
// der Versuch nur auf,
// DragAcceptFiles(Scrollbox1.Handle, True);
// DragAcceptFiles(Scrollbox2.Handle, True);
// DragAcceptFiles(Scrollbox3.Handle, True);
// DragAcceptFiles(Scrollbox4.Handle, True);
// einzugrenzen scheitert, obwohl der Mauszeiger es anzeigt, vermute das die handles nicht public sind!
// erst beim loslassen der Maus,  kann man dann abfragen wo sich der mauszeiger befindet,
// mit GetCursorPos(pos) und FindDragTarget(pos, False),
// wie bei mir, names =scrollbox oder exnames =gauge, komponente

procedure TForm1.WMDROPFILES(var Msg: TMessage);
var
  i, anzahl, size: Integer;
  names, exnames: String;

begin

  inherited;
  exnames:='';
  anzahl := DragQueryFile(Msg.WParam, DF_NUMBEROFFILES, Dateiname, 255);
  GetCursorPos(pos);
  exnames := copy(FindDragTarget(pos, False).name, 123); //<- identifikation der Gauge in welcher scrollbox sie sich befindet und welche id sie hat
  for i := 0 to (anzahl - 1do
  begin
    names := copy(FindDragTarget(pos, False).name, 010); //<- identifikation der scrollbox 1-4

    size := DragQueryFile(Msg.WParam, i, nil0) + 1;
    DateiName := StrAlloc(size);
    DragQueryFile(Msg.WParam, i, Dateiname, size);

    index:= ScrollBoxNames.IndexOf(names);
    if index < 0 then   //<- theoretisch überflüssig, kann nicht unter 0 gehen, egal
       exit;

    if (exnames = ''then   //<- erklärt sich von selbst wenn man die nächsten zeilen list (Add, Insert)
      PlayList[index].Add(dateiname)
    else
      PlayList[index].Insert(strtoint(exnames)-1+i, dateiname); 
      names := 'PlayList'+inttostr(index); //<- hier wird der string übergeben welche Playlist bearbeited wurde
    end;


    StrDispose(Dateiname);
    DragFinish(Msg.WParam);


    PlayList[index].SaveToFile(PathProjekt+names+'.lst');// hier wird die Stringliste in eine Datei mit den Namen der stringliste gespeichert

    for i := 0 to PlayList[index].Count -1 do
    begin
       PlayGauge := TGaugeCaption.create(MyScrollBoxes[index]);
       with PlayGauge do
       begin
          Name := MyScrollBoxes[index].Name + '_' + inttostr(i+1); //<- hier erhalten die guges den namen, zb. ScrollBox1_1 oder ScrollBox2_12 etc.
          Caption := ExtractFileName(playlist[index].Strings[i]);

          backColor := clInfoBk;

         OnMouseDown := form1.ScrollBox1MouseDown;
         PopupMenu := form1.PopupMenu1;
         OnClick := Form1.ScrollBox1Click;
         Top := (i)*(playgauge.Height+5);
         Parent := MyScrollBoxes[index];
         show;
       end;
    end;


end;
.....
.....
// Hier noch ein  Beispiel warum es so wichtig war das alles zu vereinfachen
// und jetzt mit den index zu arbeiten. 
// Vorher standen hier 4 if Anweisungen drin wie oben beschrieben!!! 
// und es gibt ja noch mehr Proceduren  in diesem Projekt wo dies so gebraucht wird

procedure TForm1.ScrollBox1Click(Sender: TObject);
var
   gaugeindex, i, Scrollboxmitte: Integer;
   names: string;

begin
     GetCursorPos(pos);

     names := copy(FindDragTarget(pos, False).name, 010);
     index:= ScrollBoxNames.IndexOf(names);
     if index < 0 then
        exit;
     Scrollboxmitte:= MyScrollBoxes[index].Height div 2;

     if (Sender is Tgaugecaption) then
     begin
            gaugeindex := (Sender as Tgaugecaption).ComponentIndex;
            for i := 0 to MyScrollBoxes[index].ComponentCount -1 do
                 (MyScrollBoxes[index].Components[i] as Tgaugecaption).BackColor:=clInfoBk;

            if  (Sender as Tgaugecaption).top > Scrollboxmitte then
                MyScrollBoxes[index].VertScrollbar.Position:= MyScrollBoxes[index].VertScrollbar.Position + playgauge.Height+5;
            
            if  (Sender as Tgaugecaption).top < Scrollboxmitte then
                MyScrollBoxes[index].VertScrollbar.Position:= MyScrollBoxes[index].VertScrollbar.Position - playgauge.Height+5;

           (MyScrollBoxes[index].Components[gaugeindex] as Tgaugecaption).BackColor:=cllime;


    end;

end;


Nun werden wieder einige sagen, schlechter code, unübersichtlich, komponenten sind nicht ausagekräftig???
oder
man kann alles noch einfacher machen mh.......

Bitte her damit, ich bin für jede Kritik offen :wink:

nur dann bitte auch mit code.
Der einzigste der mir da den Ansatz gegeben hatt war user profile iconApuch
THX

Alles andere waren zwar nette Hinweise, wenn man aber nicht weiter kommt (ohne anderen code)
sind auch die besten Hinweise wertlos. :roll:

Trotzdem danke an alle

Gruss ALf


Apuch - Fr 16.10.09 19:45

Warum man den Komponenten einen eigenen Namen gibt und es nicht beim Standardnamen belässt? Welche der beiden folgenden Zeilen ist Aussagekräftiger?

Delphi-Quelltext
1:
2:
rdbMouseactionPan.Checked := true; // 1
RadioButton1.Checked := true; // 2

Ich währe für die erste;) (Ein Radiobutton der irgendwas mit der Mausaktionen Pan zu tun hat wird aktiviert.. beim zweiten halt nur ein Radiobutton). Man benennt die Controls also aus dem selben Grund um wie man seine Variablen nicht a,b,c.... tauft -> bessere Lesbarkeit.

In deinem Projekt kann (!) es sein, das ScrollBox1..4 vollkommend ausreichend ist. Das aber nur wenn ScrollBox auch den Zweck beschreibt und eindeutig ist, was mit 1..4 gemeinst ist. Im Idealfall lese ich deinen Code und verstehe ohne nachragen was gemeinst ist.. wie gesagt, Idealfall. Praktisch ist das nur selten möglich. (Vor kurzen hat einer über Code von mir gesagt "kann man ganz gut lesen" ... ging runter wie Öl ;) ).

Als Faustformel gilt: Dont Repeat Yourself. Wenn du merkst, du kopierst Quellcode von anderen Stellen: Stopp, zurücklehnen, drüber nachdenken. Das geht in 98% der Fälle auch anders. Der gesamte Quellcode wird so kürzer, besser lesbar, einfacher wartbar und weniger Fehleranfällig. Was du ja am Anfang schon gesagt hast :P Das an den entsprechenden Stellen zu sehen ist dann Übungssache...


Zu deinem Code:
- ich bn Fan von konsequent englischen Bezeichnern Scrollboxmitte:= MyScrollBoxes[index].Height div 2; wirkt wie Sprachgepansche in meinen Augen
- konsequent 1 Schrittweite benutzen (du hast mal 2, mal 4 mal 8 ...)
- Konstrukte wie (Sender as Tgaugecaption). ... Sollten nach möglichkeit nicht zu oft auftauchen. Dann lieber in ner separablen Variable Speichern.
- 80 Zeichen Seitenbreite ... wie es seit etwa 40 Jahren gilt ;)

So genug gemeckert.. zum Schluss noch den Zen of Python (gilt aber auch für andere Programmiersprachen):
Zitat:

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Bei letzteren hat Delphi ein Problem ^^

MfG


ALF - Fr 16.10.09 21:05

OMG
jetzt hast du user profile iconApuch mich aber runtergemacht :oops:
zu 1:
hätt ich die ScrollBoxen, Container benannt, glaube nicht das irgend jemand dies verstanden hätte
zumal der

Delphi-Quelltext
1:
2:
3:
   PlayGauge := TGaugeCaption.create(ScrollBox1);
   ...
   Parent := ScrollBox1;

eindeutig ist

zu 2:
Sorry für Copy & Paste

zu3:
Ich glaube und bin sogar fest überzeugt das 80/% der Coder, egal in welcher Sprache Assembler, Delphi
C++ usw. wenn sie nicht Professionel coden ein Sprachgepansche haben. Wird sich auch nicht ändern! Da die meisten eh nicht in diesen Sektor arbeiten werden und dies nur als Hobby machen!
(Ausnahmen bestätigen die Regel) :lol:

Schrittweite mh... gut

Ob es Sinn macht für alles eine Variable zu setzen mh....????, Glaube da streiten sich sogar Fachleute darüber!

80 Zeichen??? dann schau dir manschen Profi code an und seine Kommentar zeilen (die Jungs bekommen Geld dafür) nur so am rande

und so anbei, mein engl. ist sooooo schlecht leider :mrgreen:

Trotzdem danke ich dir :beer:
ALF